Special dial plan most probably needs AGI

I need help with a dial plan can do the belows call flow

  1. Call from Extension: An voip phone user dials *123*(number)#, where (number) is the desired phone number.

  2. PBX Receives Call: The PBX receives the call and checks the dialed number pattern.

  3. Pattern Match: The PBX matches the pattern *123*(number)# and triggers a specific dialplan.

  4. Hangup: The PBX hangs up the call.

  5. Callback: The PBX initiates a new call to the voip phonethat made the original call.

  6. Extension Answers: The voip phone user answers the callback.

  7. Dial Outbound Call: The PBX dials the (number) that was specified in the original call.

  8. Bridge Calls: Once the outbound call is answered, the PBX bridges the two calls, connecting the extension user with the called party.

Whilst this sounds strangely similar to another recent question, this variation doesn’t make sense, as, assuming extension means a local VoIP phone (extension, in the Asterisk sense, makes no sense here), there is really no advantage over just skipping steps 4, 5, and 6.

Generally though you need to show what you have done and ask specific questions about areas of difficulty; people are not going to design complete dialplans for free.

The main technical difficulty here is that the dialplan matching can’t really cope with an arbitrary number length in matching your pattern.

I am willing to pay cause i am tired of trying and i am out of time

Hi Community i am straggling to implement this dial plan when i implement the cal is properly rejected but doesn’t trigger a call back no errors check the log below

asterisk*CLI> dialplan reload

Dialplan reloaded.

    > Time to scan old dialplan and merge leftovers back into the new: 0.000081 sec

    > Time to restore hints and swap in new dialplan: 0.000039 sec

    > Time to delete the old dialplan: 0.000136 sec

    > Total time merge_contexts_delete: 0.000256 sec

    > pbx_config successfully loaded 3 contexts (enable debug for details).

-- Executing [*123*0677256155@from-internal:1] NoOp("PJSIP/troxy-00000005", "Received call transfer request") in new stack

-- Executing [*123*0677256155@from-internal:2] Set("PJSIP/troxy-00000005", "TARGET_NUMBER=0677256155") in new stack

-- Executing [*123*0677256155@from-internal:3] NoOp("PJSIP/troxy-00000005", "Target number is 0677256155") in new stack

-- Executing [*123*0677256155@from-internal:4] Set("PJSIP/troxy-00000005", "ORIGINATING_CHANNEL=PJSIP/troxy-00000005") in new stack

[2025-05-09 19:22:02] WARNING[1388][C-00000006]: pbx.c:2943 pbx_extension_helper: No application ‘AGI’ for extension (from-internal, 1230677256155, 5)

== Spawn extension (from-internal, 1230677256155, 5) exited non-zero on ‘PJSIP/troxy-00000005’

Dial plan
[from-internal]
; Local extension dialing
exten => 201,1,Dial(PJSIP/troxy,20)
exten => 209,1,Dial(PJSIP/tinashe,20)

; Feature code for call transfer
exten => _123X.,1,NoOp(Received call transfer request)
same => n,Set(TARGET_NUMBER=${EXTEN:5}) ; Extract the number after 123
same => n,NoOp(Target number is ${TARGET_NUMBER})
same => n,Set(ORIGINATING_CHANNEL=${CHANNEL}) ; Store the originating channel
same => n,AGI(call_transfer.agi,${ORIGINATING_CHANNEL},${TARGET_NUMBER}) ; Execute the AGI script
same => n,Hangup() ; Drop the initial call

; Outbound dialing via SIP trunk
exten => _0ZXXXXXXXX,1,Set(CALLERID(num)=27871889742)
same => n,Dial(PJSIP/${EXTEN}@${TRUNKOUT})
same => n,Hangup()

; Handle numbers with leading ‘+’
exten => _+X.,1,Set(STRIPPED=${EXTEN:1})
same => n,Set(CALLERID(num)=27871889742)
same => n,Dial(PJSIP/${STRIPPED}@${TRUNKOUT})
same => n,Hangup()

[from-vphone]
exten => s,1,NoOp(Incoming call from vphone trunk)
same => n,Dial(PJSIP/troxy&PJSIP/tinashe,30)
same => n,Hangup()

[call-transfer-logic]
exten => s,1,Answer() ; Answer the originating call to the extension
same => n,Set(CALLERID(num)=27871889742) ; Set the outbound Caller ID
same => n,Dial(PJSIP/${TARGET_NUMBER}@${TRUNKOUT},30) ; Dial the target number
same => n,Hangup()

PYTHON AGI SCRIPT
#!/usr/bin/env python
import sys
from asterisk.agi import AGI

agi = AGI()
originating_channel = sys.argv[1]
target_number = sys.argv[2]

agi.verbose(f"Originating channel: {originating_channel}, Target number: {target_number}")

Get the extension number from the originating channel name (assuming a pattern like PJSIP/201-…)

extension = originating_channel.split(‘/’)[1].split(‘-’)[0]
agi.verbose(f"Originating extension: {extension}")

Originate call to the internal extension

agi.verbose(f"Originating call to {extension}“)
call1 = agi.originate(f"PJSIP/{extension}”, “call-transfer-logic”, “s”, “1”, async=True)
agi.verbose(f"Originate call 1 result: {call1}")

No need to originate the second call here if the dialplan in [call-transfer-logic] handles it.

The dialplan will be executed when the call to the extension in originate() is answered.

agi.hangup()

Presumably res_agi is not loaded, so you can’t run AGIs.

@Tenacious I moved your latest post into here, as it is the same fundamental underlying issue/discussion.