How to flag a call for future follow-up

Earlier in the week we celebrated the anniversary of Canada’s confederation, and it appears there’s a similar sort of holiday taking place to our south today, so today’s #FridayFun is topical (if only tangentially) about flags.

Our plan today is to setup a framework for how one might setup an in-call feature code for a PBX user to flag their current call in some way for a follow up. In the context of support where my day-to-day existence is, I would set this up to send some sort of notification with call details to a support team to investigate call issues, but could easily be adapted for other purposes.

First step is to setup and in-calll feature code, which is described in detail in this thread. So this is our starting point:

To the file /etc/asterisk/features_applicationmap_custom.conf, add the following:

flag_call => *6,self,Gosub(flag-call,s,1)

To the file /etc/asterisk/globals_custom.conf add the lines:

DYNAMIC_FEATURES = ${DYNAMIC_FEATURES}#flag_call

and to the file /etc/asterisk/extensions_custom.conf, lets start with some very basic dial plan like this

[flag-call]
exten => s,1,Noop(Entering user defined context flag-call in extensions_custom.conf)
; exten => s,n,DumpChan   ; uncomment for debug
exten => s,n,Set(CHANNEL(hangup_handler_push)=flag-call-complete,s,1)
exten => s,n,Return

[flag-call-complete]
exten => s,1,Noop(Entering user defined context flag-call-complete in extensions_custom.conf)
exten => s,n,DumpChan
exten => s,n,Return

This gives us a good starting point. With the above edits made and the dialplan reloaded, when on a live call, a user can enter DTMF *6 and get a hangup handler added to the channel. When the call terminates, the hangup handler dialplan runs, and you can perform whatever action you want at that point. Let see how it looks in the console:

When you use the feature code

    -- PJSIP/5003-00000002 Internal Gosub(flag-call,s,1) start
    -- Executing [s@flag-call:1] NoOp("PJSIP/5003-00000002", "Entering user defined context flag-call in extensions_custom.conf") in new stack
    -- Executing [s@flag-call:2] Set("PJSIP/5003-00000002", "CHANNEL(hangup_handler_push)=flag-call-complete,s,1") in new stack
    -- Executing [s@flag-call:3] Return("PJSIP/5003-00000002", "") in new stack

and once the call terminates:

    -- Executing [s@flag-call-complete:1] NoOp("PJSIP/5003-00000002", "Entering user defined context flag-call-complete in extensions_custom.conf") in new stack
    -- Executing [s@flag-call-complete:2] DumpChan("PJSIP/5003-00000002", "") in new stack

Dumping Info For Channel: PJSIP/5003-00000002:
================================================================================
Info:
Name=               PJSIP/5003-00000002
Type=               PJSIP
 * lines removed for brevity *
================================================================================
    -- Executing [s@flag-call-complete:3] Return("PJSIP/5003-00000002", "") in new stack

So now you have framework, what can you do with it? Continuing with the idea that we’re flagging the call for support purposes, we can isolate the asterisk full log lines and call recording and mail them to an address.

To isolate asterisk log lines for a specific call, I always start by grepping the asterisk full log for the UNIQUEID value, which results in a line like this:

root@tangopbx5:~# grep 1751641123.74 /var/log/asterisk/full
[2025-07-04 14:58:43] VERBOSE[615720][C-00000010] pbx.c: Executing [s@macro-user-callerid:1] Set("PJSIP/5003-0000001a", "TOUCH_MONITOR=1751641123.74") in new stack

From this line, isolate the string in third set of brackets and do another grep on the full log, like this:

root@tangopbx5:~# grep C-00000010 /var/log/asterisk/full
[2025-07-04 14:58:43] VERBOSE[615720][C-00000010] pbx.c: Executing [5002@from-internal:1] GotoIf("PJSIP/5003-0000001a", "1?ext-local,5002,1:followme-check,5002,1") in new stack
[2025-07-04 14:58:43] VERBOSE[615720][C-00000010] pbx_builtins.c: Goto (ext-local,5002,1)
[2025-07-04 14:58:43] VERBOSE[615720][C-00000010] pbx.c: Executing [5002@ext-local:1] Set("PJSIP/5003-0000001a", "__RINGTIMER=15") in new stack
[2025-07-04 14:58:43] VERBOSE[615720][C-00000010] pbx.c: Executing [5002@ext-local:2] ExecIf("PJSIP/5003-0000001a", "0?Set(__CWIGNORE=)") in new stack
   *** snip ***

Modifiying the above commands so the grep doesn’t match in places we don’t want it to, the dialplan for that looks like:

[flag-call-complete]
exten => s,1,Noop(Entering user defined context flag-call-complete in extensions_custom.conf)
; exten => s,n,DumpChan   ; uncomment for debug
exten => s,n,set(full-log-id=${TRIM(${SHELL(grep \"TOUCH_MONITOR=${UNIQUEID}\" ${ASTLOGDIR}/full | cut -d '[' -s -f 4 | cut -d ']' -f 1)})})
exten => s,n,System(grep ${full-log-id} ${ASTLOGDIR}/full > ${ASTSPOOLDIR}/${UNIQUEID})
exten => s,n,System(mail -s 'FLAGGED CALL ${UNIQUEID}' -a ${ASTSPOOLDIR}/${UNIQUEID} -a ${MIXMONITOR_FILENAME} address@email.com )
exten => s,n,Return
4 Likes