Call file to Local/9000 redirect to SIP/*/X

I am trying to develop a reminding system that will make an automatic call to remind a person of a specific event. For this I am using Asterisk to make the calls and PHP in order to create a call file for Asterisk. I want the call file to execute 30 seconds after it is added. To do this I set the modified time stamp in the PHP script. Everything works great except that I want to run a check agains a web service to determine if it is still relevant to call the user.

Here is my PHP script

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $request = json_decode(file_get_contents("php://input"));

        $tmpcallfile = tempnam("/tmp", "call");
        $callfile = tempnam("/var/spool/asterisk/outgoing/", "call");

        $fh = fopen($tmpcallfile, "w");
        fwrite($fh, "Channel: Local/9000@remind_event\n");
        fwrite($fh, "CallerID: " . $request->{'FromPhoneNumber'} . "\n");
        fwrite($fh, "MaxRetries: 3\n");
        fwrite($fh, "RetryTime: 5\n");
        fwrite($fh, "Context: remind_event\n");
        fwrite($fh, "Extension: 9000\n");
        fwrite($fh, "Priority: 1\n");
        fwrite($fh, "Archive: Yes\n");
        fwrite($fh, "SetVar: PHONE_NUMBER=" . $request->{'ToPhoneNumber'} . "\n");

        fclose($fh);

        touch($tmpcallfile, time()+30);

        rename($tmpcallfile, $callfile);
}
?>

And my idea was to simply call the web service using curl in the extensions.conf however for this to be possible I need to be able to redirect the local call to an external call in case the web service tells that the call should be made. I have now made a simple extensions.conf just in order to transfer the internal call to an external number. I leave the curl check out for now.

The crazy thing is that I receive two different calls on my cell phone simultaneously when running the call-file and I am clueless of why. First I get one call, then there is a call waiting activated. When I pick upp I hear dial tone. If I park the first call and answer the second I hear silence. When I hang up the second call also the first call is hung up.

[voxbeam_outbound]
exten => _X.,1,NoOp()
        same => n,Answer
        same => n,Dial(SIP/voxbeam_outbound/${EXTEN})

[remind_event]
exten => 9000,1,NoOp()
       same => n,Dial(SIP/voxbeam_outbound/${PHONE_NUMBER})
       same => n,Playback(remind_event)
       same => n,Hangup

For completeness here is also added lines in sip.conf although I guess these are actually not relevant:

[voxbeam_outbound]
type=peer
insecure=invite,port
nat=no
canreinvite=no
username=<hidden>
secret=<hidden>
host=<hidden>
context=voxbeam_outbound

Here is the output of asterisk -vvvr

Connected to Asterisk 13.16.0 currently running on sippoc2 (pid = 23986)
    -- Attempting call on Local/9000@remind_event for 9000@remind_event:1 (Retry 1)
    -- Called 9000@remind_event
    -- Executing [9000@remind_event:1] NoOp("Local/9000@remind_event-00000000;2", "") in new stack
    -- Executing [9000@remind_event:2] Dial("Local/9000@remind_event-00000000;2", "SIP/voxbeam_outbound/+467<hidden>") in new stack
  == Using SIP RTP CoS mark 5
    -- Called SIP/voxbeam_outbound/+467<hidden>
    -- SIP/voxbeam_outbound-00000000 is making progress passing it to Local/9000@remind_event-00000000;2
    -- Local/9000@remind_event-00000000;1 is making progress
    -- SIP/voxbeam_outbound-00000000 requested media update control 26, passing it to Local/9000@remind_event-00000000;2
    -- SIP/voxbeam_outbound-00000000 is ringing
    -- Local/9000@remind_event-00000000;1 is ringing
    -- SIP/voxbeam_outbound-00000000 requested media update control 26, passing it to Local/9000@remind_event-00000000;2
    -- SIP/voxbeam_outbound-00000000 answered Local/9000@remind_event-00000000;2
    -- Local/9000@remind_event-00000000;1 answered
    -- Executing [9000@remind_event:1] NoOp("Local/9000@remind_event-00000000;1", "") in new stack
    -- Executing [9000@remind_event:2] Dial("Local/9000@remind_event-00000000;1", "SIP/voxbeam_outbound/+467<hidden>") in new stack
  == Using SIP RTP CoS mark 5
    -- Called SIP/voxbeam_outbound/+467<hidden>
    -- Channel SIP/voxbeam_outbound-00000000 joined 'simple_bridge' basic-bridge <94c7a115-a487-45ee-b516-2dd0f561b6fc>
    -- Channel Local/9000@remind_event-00000000;2 joined 'simple_bridge' basic-bridge <94c7a115-a487-45ee-b516-2dd0f561b6fc>
    -- Local/9000@remind_event-00000000;1 requested media update control 26, passing it to SIP/voxbeam_outbound-00000001
    -- SIP/voxbeam_outbound-00000001 is making progress passing it to Local/9000@remind_event-00000000;1
    -- SIP/voxbeam_outbound-00000001 requested media update control 26, passing it to Local/9000@remind_event-00000000;1
    -- SIP/voxbeam_outbound-00000001 is ringing
    -- Channel SIP/voxbeam_outbound-00000000 left 'simple_bridge' basic-bridge <94c7a115-a487-45ee-b516-2dd0f561b6fc>
    -- Channel Local/9000@remind_event-00000000;2 left 'simple_bridge' basic-bridge <94c7a115-a487-45ee-b516-2dd0f561b6fc>
    -- Local/9000@remind_event-00000000;1 requested media update control 26, passing it to SIP/voxbeam_outbound-00000001
  == Spawn extension (remind_event, 9000, 2) exited non-zero on 'Local/9000@remind_event-00000000;2'
  == Spawn extension (remind_event, 9000, 2) exited non-zero on 'Local/9000@remind_event-00000000;1'
  [Aug  1 18:25:08] NOTICE[24053][C-00000001]: pbx_spool.c:460 attempt_thread: Call completed to Local/9000@remind_event

You need two different contexts, one for each leg of the call.

One context plays the audio, the other context places the call.

Try creating a couple test contexts and play with how the originate works.

[playback_test]
exten => s,1,Answer()
same => n,Playback(hello-world)
same => n,Hangup()

Originate LOCAL/yournumber@voxbeam_outbound extension s@playback_test

1 Like

Answer() does nothing when used with Origniate, as the call is already up before the extension is run.

1 Like

Why create a call file instead of use AMI originate Action and cron job, the idea would be run the php script using cron every 1 minute that will check your web service and the system time stamp if alll condtions are met , it will initiate the call

1 Like

Thank you for the reply @johnkiniston. So I need two contexts, make sense.
I have now created according to your suggestion:

[playback_test]
exten => s,1,Answer()
        same => n,Playback(warn_timerwillexpire)
        same => n,Hangup()

I have also created a context I call outbound_withcheck. Now it is just calling immediately but if I get this to work I guess I can make the check using curl before it reaches the Dial row.

[outbound_withcheck]
exten => _X.,1,Log(ERROR, called)
        same => n,Answer
        same => n,Dial(SIP/voxbeam_outbound/${PHONE_NUMBER})

Here is the call file, I am sure there is some mistake in here:

Channel: Local/9000@outbound_withcheck
CallerID: +46<hidden>
MaxRetries: 3
RetryTime: 5
Context: playback_test
Extension: s@playback_test
Priority: 1
Archive: Yes 
SetVar: PHONE_NUMBER=+46<hidden>
StartRetry: 26420 1 (1564771650)
Status: Completed

Here is the log output I get:

Connected to Asterisk 13.16.0 currently running on sippoc2 (pid = 26420)
**--** Attempting call on Local/9000@outbound_withcheck for s@playback_test@playback_test:1 (Retry 1)
**--** Called 9000@outbound_withcheck
**--** Executing [9000@outbound_withcheck:1] **Log** (" **Local/9000@outbound_withcheck-00000002;2** ", " **ERROR, called** ") in new stack
[Aug 2 18:52:33] **ERROR** [26528][C-00000004]: **Ext. 9000** : **1** **@ outbound_withcheck** : called
**--** Executing [9000@outbound_withcheck:2] **Answer** (" **Local/9000@outbound_withcheck-00000002;2** ", "") in new stack
**--** Local/9000@outbound_withcheck-00000002;1 answered
[Aug 2 18:52:33] **WARNING** [26527][C-00000005]: **pbx.c** : **4414** **__ast_pbx_run** : Channel 'Local/9000@outbound_withcheck-00000002;1' sent to invalid extension but no invalid handler: context,exten,priority=playback_test,s@playback_test,1
[Aug 2 18:52:33] **NOTICE** [26527][C-00000005]: **pbx_spool.c** : **460** **attempt_thread** : Call completed to Local/9000@outbound_withcheck
**==** Spawn extension (outbound_withcheck, 9000, 2) exited non-zero on 'Local/9000@outbound_withcheck-00000002;2'

This is because there is a lot of different users that might need to be reminded. If I create a call file for each one I will move the responsibility to asterisk.
If I dont do this I need to implement elsewhere:

  • Have some kind of method to query the other system which uses should be reminded
  • Removing those who should no longer be reminded if conditions change
  • Handle retries

So I mainly want to create a call file for each one and let Asterisk ask the other system if it is still relevant to remind in order to minimize the work that has to be done on the other system. It is also good that Asterisk can handle the reminding even though the other system is down at some point.

Your ‘Extension’ line just needs to be ‘s’ no ‘@playback_test

1 Like

The Answer () on the A leg will break it! Asterisk will start running the B leg immediately, so that the playback ha completed before anyone really answers.

Dialplan extensions should not start with Answer () unless they are B side and you want to start charging the caller immediately. The implied Answer will be enough for Playback, and you generally don’t want to answer before calling Dial unless you have a problem with B side early media and no early media support on the A side.

1 Like

@johnkiniston: Thanks! So far this seem to work exactly like I want it to. I will add the condition check on web service tomorrow I hope and see if it works also.

@david551: Thank you as well. I had the problem you mention that it will start playing immediately and before pickup. I just heard the second half. After removing both Answer commands it seem to have fixed this issue.

1 Like

Just want to share that I tried it all yesterday and it worked perfectly. Thanks again!

1 Like