Automated Call Recording Uploader in Dial Plan

376 Views Asked by At

i have an issue regarding call recording. What i wanted to do is automatically upload the call recording after hangup

My extensions.conf looks some like this

exten => _!,n,System(mkdir “/var/spool/asterisk/${CALLERID(number)}”)
exten => _!,n,Set(FILENAME=CallingTime(${EPOCH})-Called(${EXTEN}))
exten => _!,n,Set(MONITOR_EXEC_ARGS=&& mv “/var/spool/asterisk/monitor/${FILENAME}.wav” “/var/spool/asterisk/${CALLERID(number)}/”)
exten => _!,n,Monitor(wav,${FILENAME},mb)
exten => _!,n,Dial(SIP/100,r)
exten => _!,n,Hangup()

I’ve tried adding

exten => _!,n,System( uploader ${CALLERID(number)} /var/spool/asterisk/${CALLERID(number)}/ ${FILENAME}.wav)

but the recording is not available yet

I’ve tried adding it after hangup

exten => h,1,System( uploader ${CALLERID(number)} /var/spool/asterisk/${CALLERID(number)}/ ${FILENAME}.wav )

but the recording is not available yet

i’ve tried appending the uploader function into the MONITOR_EXEC_ARGS which look something like this

exten => _!,n,Set(MONITOR_EXEC_ARGS=&& mv “/var/spool/asterisk/monitor/${FILENAME}.wav” “/var/spool/asterisk/${CALLERID(number)}/” && uploader ${CALLERID(number)} /var/spool/asterisk/${CALLERID(number)}/ ${FILENAME}.wav )

But the recording fails to merge the two leg files

If you can point me to the right direction or find what i am doing wrong here it would be very helpful. Thanks in anticipation

2

There are 2 best solutions below

2
On

You should not add long action to hangup handler. That can cause asterisk stuck.

Use cdr(userfield) or other to mark records you want do, after that process it by external scripting.

0
On

Notes:

When trying to reproduce the behavior of your dialplan, it did not work for me because the quotes in your dialplan example were not correct. I had to change to ". I tested with a SIP endpoint with Caller ID +17777888 and dialplan entry point was 1234@default.

Solution:

Avoid curly brackets in the filename variable so that it can be safely used correctly in the shell command by the asterisk monitor application:

old: exten => _!,n,Set(FILENAME=CallingTime(${EPOCH})-Called(${EXTEN}))

new: exten => _!,n,Set(FILENAME=CallingTime_${EPOCH}-Called_${EXTEN})

Alternatively, if your filename absolutely must have the curly brackets, you can try to escape the brackets with a backslash in your variable name, but it’s relatively hard to trace the consequences of escaping.

Full dialplan that worked for me:

[default]
exten => _!,1,System(mkdir -p "/var/spool/asterisk/${CALLERID(number)}")
exten => _!,n,Verbose(0,trying mkdir "/var/spool/asterisk/${CALLERID(number)}". system app result: '${SYSTEMSTATUS}')
exten => _!,n,Set(FILENAME=CallingTime_${EPOCH}-Called_${EXTEN})
exten => _!,n,Set(MONITOR_EXEC_ARGS=&& mv "/var/spool/asterisk/monitor/${FILENAME}.wav" "/var/spool/asterisk/${CALLERID(number)}/")
exten => _!,n,Monitor(wav,${FILENAME},m)
exten => _!,n,Answer()
exten => _!,n,MusicOnHold(default,5)
exten => _!,n,Hangup()
exten =>  h,1,Goto(999)
exten =>  h,999,NoOp(hangup)

Approch / Debugging

Check if System-Execution mkdir result was successful

check the System app documentation:

asthost*CLI> core show application System

  -= Info about application 'System' =-

[Synopsis]
Execute a system command.

[Description]
Executes a command  by  using  system(). If the command fails, the console
should report a fallthrough.
Result of execution is returned in the ${SYSTEMSTATUS} channel variable:
${SYSTEMSTATUS}:
    FAILURE: Could not execute the specified command.
    SUCCESS: Specified command successfully executed.

[Syntax]
System(command)

[Arguments]
command
    Command to execute
    WARNING!!!: Do not use untrusted strings such as ${CALLERID(num)} or
    ${CALLERID(name)} as part of the command parameters.  You risk a command
    injection attack executing arbitrary commands if the untrusted strings
    aren't filtered to remove dangerous characters.  See function ${FILTER()}.

[See Also]
Not available

As documented, the SYSTEMSTATUS variable stores the execution status of the system call. Add to your dialplan some output to see if the System() call was successful:

exten => _!,n,System(mkdir "/var/spool/asterisk/${CALLERID(number)}")
exten => _!,n,Verbose(0,trying mkdir "/var/spool/asterisk/${CALLERID(number)}". system app result: '${SYSTEMSTATUS}')

Output should be like:

trying mkdir "/var/spool/asterisk/+17777888". system app result: 'SUCCESS'

If the directory already exists, your will get an error status like APPERROR. You can append -p option to your mkdir command to always get SUCCESS value of the SYSTEMSTATUS variable, even if the directory already exists.

See what exactly the monitor application calls in the system

First set debug level to 1 to see more output:

asthost*CLI> core set debug 1

Then initiate a new call. After you hang up, your should sie on asterisk cli something like that:

[2023-03-13 11:40:01] DEBUG[681389][C-0000008c]: res_monitor.c:532 __ast_monitor_stop: monitor executing ( nice -n 19 sox -m "/var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234)-in.wav" "/var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234)-out.wav" "/var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234).wav" && mv “/var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234).wav” “/var/spool/asterisk/+17777888/” && rm -f "/var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234)-"* ) &

Now check which files are in the monitor directory after the call is hung up:

root@asthost:/# ls -l /var/spool/asterisk/monitor/*
-rw-r--r-- 1 root root 240684 Mar 13 11:40 '/var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234)-in.wav'
-rw-r--r-- 1 root root 240044 Mar 13 11:40 '/var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234)-out.wav'

As we can see, the unmixed -in.wav and -out.wav files are still in the monitor directory, so the file mixing seems to have failed. Try to run the same command on your bash console:

root@asthost:/# ( nice -n 19 sox -m "/var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234)-in.wav" "/var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234)-out.wav" "/var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234).wav” && mv "/var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234).wav" "/var/spool/asterisk/+17777888/" && rm -f "/var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234)-"* ) &

Console outputs the error message:

root@asthost:/# sox FAIL formats: can't open input file `/var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234)-out.wav': No such file or directory

Try to find the file. An error message occures:

root@asthost:/# ls /var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234)-out.wav
bash: syntax error near unexpected token `('

Try with escaped brackets. That will do:

root@asthost:/# ls /var/spool/asterisk/monitor/CallingTime\(1678703986\)-Called\(1234\)-in.wav
'/var/spool/asterisk/monitor/CallingTime(1678703986)-Called(1234)-in.wav'

Fix your dialplan

Avoid curly brackets in your filename, so use underscore, for example. Change your dialplan line like this:

old: exten => _!,n,Set(FILENAME=CallingTime(${EPOCH})-Called(${EXTEN}))

new: exten => _!,n,Set(FILENAME=CallingTime_${EPOCH}-Called_${EXTEN})

Reload your dilaplan

asthost*CLI> dialplan reload

Check the behavior

Now is should work. Activate debug level 1 and initiate a new call.

asthost*CLI> core set debug 1
...
[2023-03-13 12:16:26] DEBUG[682358][C-00000095]: res_monitor.c:532 __ast_monitor_stop: monitor executing ( nice -n 19 sox -m "/var/spool/asterisk/monitor/CallingTime_1678706180-Called_1234-in.wav" "/var/spool/asterisk/monitor/CallingTime_1678706180-Called_1234-out.wav" "/var/spool/asterisk/monitor/CallingTime_1678706180-Called_1234.wav" && mv "/var/spool/asterisk/monitor/CallingTime_1678706180-Called_1234.wav" "/var/spool/asterisk/+17777888/" && rm -f "/var/spool/asterisk/monitor/CallingTime_1678706180-Called_1234-"* ) &

Check your files.

monitor directory should not contain the wav files of the last call:

root@asthost:/# ls -l /var/spool/asterisk/monitor/
total 0

caller-id directory should contain the wav files of the last call:

root@asthost:/# ls -l /var/spool/asterisk/+17777888/
total 92
-rw-r--r-- 1 root root 93484 Mar 13 12:16 CallingTime_1678706180-Called_1234.wav

That looks as expected.