I’m seeing a flaw in this thread (and in its counterpart at FreePBX forums) when discussing Originate or AMI with Local channels. No one is providing details on the fact Local channels are optimized out of the call/bridge path unless other wise told not to. That optimized channels behave in a different manner and may not have the desired results.
All three of these are different.
Channel: PJSIP/301 # Acts like an inbound call to the system. If 301 is unavailable an error will occur and AMI won't see it because the AMI action actually completed.
Channel: Local/301@from-internal # this is the default local channel method which means the Local channel will be optimized out of the call path. This has implications to the call handling.
Channel: Local/301@from-internal/n # this is a non-optimized Local channel, it means it stays present during the life of the call. Provides more control and is the required method when certain features or monitoring want to be used on the call. This includes post call handling.
So you always need to decide which method is the best. Now in the OPs case, the question to ask is “Do I need the Local channel optimized or non-optimized?” and here’s how you can break that down.
Optimized Option
Action: Originate
Channel: Local/301@originate-skipvm
WaitTime: 30
Context: click-to-call
Exten: s
Priority: 1
Variable: number=02081231234
Variable: pin=0000#
Async: yes
This will call 301, avoiding going to voicemail if not answered. It will check for things such as Call Waiting, Do No Disturb, Follow-Me, etc that any incoming call to 301 would be checked for. This also including dialing all the contacts if this is a PJSIP extension. Once 301 answers, it will jump to click-to-call,s,1 which will trigger the outbound call.
Click to call context
[click-to-call]
exten = s,1,NoOp(Click to Call for ${number} using PIN ${pin}) ; Will show the proper number and pin.
exten = s,n,Dial(Local/${number}@from-internal,,D(wwww${pin})) ; Should dial the number and pass the pin.
exten = s,n,Hangup
Problem: The Local channel is optimized and when it hits the Dial() it will move the Bridge to new channel (in this case another local channel) and all the variables set on the this channel will be lost. There is a very big chance that both ${number} and ${pin} will be non-existent (thus empty) when the Dial() is processed.
If things like call recording or other variables were setup on Local/301 before hitting the click-to-call context, they will be lost too. So if 301 is supposed to override the Outbound Route and always record outbound calls…that setting is ignored at this point because it’s lost.
In summary an Optimized Local channel will remove itself (and all it’s channel variables) from the call path/bridge the moment it creates a new channel. While it gives you more control over the calling channel in case it’s busy or should make a call based on X logic you lose that control once the new channel is made. Controls on features like MixMonitor, Park and others will be lost. There’s also no post-call control i.e. when the Dial() completes.
Non-Optimized Local Channel
Requires one minor modification and the local channel (and all its variables and settings stay in the call/bridge). You add /n
to the end.
Channel: Local/301@originate-skipvm/n
Now this 100% guarantees that ${phonenumber} and ${pin} are accessible and do not get destroyed. It also means other settings and features triggered on the calling channel are honored and used such as Call Recording, etc. It also guarantees post-call control when the Dial() completes.
But what about the Channel: PJSIP/301
option? This is the most basic option and provides zero control over the calling channel nor any real post-call handling. This is truly a “fire and forget” method.