Help with AMI Custom Dialplan to SendDTMF

Hi everyone,

I’m running FreePBX 17 which runs Asterisk 22.4.1. I’m banging my head against this and would deeply appreciate help from anyone who may know how to crack this.


What I’m Trying to Do

I’m using a PHP script to trigger a call via AMI Originate. Here’s the flow:

  1. I originate a call to Local/301@from-internal/n
  2. Extension 301 rings and the user answers
  3. The system says: “Please enter your password followed by the pound key.”
    → This is from a FreePBX PIN Set on the outbound route
  4. I want to automatically send the PIN (e.g., 1234#) so the user doesn’t have to type it

What I’ve Tried So Far

  • Dial(...,B(context^s^1(${pin})) + SendDTMF() in a subroutine
  • Dial(...,D(wwww1234#)) to send tones to the callee leg (doesn’t help since PIN prompt is on caller leg)
  • Running an AGI script that sends SEND DTMF after a delay
  • Using Answer(), Wait(), even double SendDTMF() with sleep and Wait() added
  • Confirmed the AGI script runs and can say digits / play audio
  • Tried sending DTMF from AGI after waiting 6–8 seconds — still fails

Here is the custom dialplan code I tried:

[clicktocall-pin]
exten => s,1,NoOp(Click-to-Call with PIN: ${number} PIN: ${pin})
exten => s,n,Dial(Local/${number}@from-internal,B(clicktocall-auth^s^1(${pin})))
exten => s,n,Hangup()

[clicktocall-auth]
exten => s,1,NoOp(Running click-to-call PIN injection with PIN: ${ARG1})
exten => s,n,SendDTMF(${ARG1}#)
exten => s,n,Return()


What Does Work (but I can’t use)

  • If I configure a Yealink phone to dial 02081231234,1234#, it works perfectly — the phone delays and sends tones after the prompt
  • But I need this automated, from the server side, with no softphone / SIP device intervention

Constraints (Musts)

  • I must use the FreePBX PIN Set on the outbound route - can’t remove or bypass it
  • I must automate PIN entry (no manual keypad input)
  • I can’t use softphones, external SIP clients - this has to be done within Asterisk/FreePBX server side
  • I’m using Asterisk 22.4.1

Has Anyone Made This Work?

All I need is for Asterisk to send the PIN after the prompt starts, on the caller channel. But:

  • SendDTMF() does not work
  • D() sends to wrong channel
  • FreePBX’s PIN macro runs late in the dialplan
  • There doesn’t seem to be a way to “pause then send” DTMF at the right moment

If anyone has solved this:

  • Did you use Local/, SIP/, or something else?
  • Did you inject DTMF another way?
  • Can you buffer DTMF until media is active?

I’ve spent days trying every method I can find. Any suggestions would be much appreciated.

Thanks in advance!

Too early. Before the INVITE has been sent.

Don’t understand why you think this won’t work, but I may not have understood the requirement, e.g. I’m assuming that the reference to FreePBX is not important.

How do you run it? The normal ways would be too early or too late.

Wrong channel.

Thanks for the reply.

To clarify:

  • The FreePBX PIN Set is applied to the outbound route, so the PIN prompt is played to the caller leg i.e., extension 301.
  • I’m trying to have Asterisk auto-enter that PIN (e.g. 1234#) so the user at 301 doesn’t have to type it manually.
  • I confirmed via SayDigits that my AGI script does run and can speak to the caller, so it’s executing on the correct leg (301).
  • I’m tried the AGI script from a custom context like this:
[clicktocall-pin]
exten => s,1,Answer()
exten => s,n,AGI(sendpin.agi,${pin})
exten => s,n,Dial(Local/${number}@from-internal)
exten => s,n,Hangup()
  • In the AGI script I sleep 5 before calling SEND DTMF for each digit and #.

So far, it always runs before FreePBX plays “Please enter your password” - so the tones are missed.

I even tried the following, but still no luck. What I am told is that DTMF is only sent when the call is established but in my case that’s not happening because the system is waiting for the PIN before it tries to establish that connection.

[clicktocall-pin]
exten => s,1,NoOp(Click-to-Call with PIN: ${number} PIN: ${pin})
exten => s,n,Dial(Local/${number}@from-internal,,B(clicktocall-auth^s^1(${pin})))
exten => s,n,Hangup()

[clicktocall-auth]
exten => s,1,NoOp(Running click-to-call PIN injection with PIN: ${ARG1})
exten => s,n,SendDTMF(${ARG1}#)
exten => s,n,Return()

Any idea how I can solve this please?

Thanks again

So this is on the same machine, not a separate machine that just happens to be running FreePBX. You mat need FreePBX internals knowledge to give a good answer, in which case you need the FreePBX forum. On the other hand, I can’t think of any reason why D wouldn’t work.

Note that B is on the wrong channel, as well as too early.

I suspect it might be easier to have a secret dial prefix that bypasses the PIN check. It’s no worse in terms of embedding a clear text secret in the dialplan.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.