致电文件,如果网络服务这样说,请取消呼叫



我正在尝试开发一个提醒系统,该系统将自动调用以提醒一个特定事件的人。为此,我使用星号进行呼叫和PHP,以创建星号的调用文件。我希望呼叫文件在添加后30秒执行。为此,我在PHP脚本中设置了修改后的时间戳。一切都很好,除了我想再次运行检查Web服务以确定致电用户是否仍然相关。

这是我的php脚本

<?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: SIP/voxbeam_outbound/" . $request->{'ToPhoneNumber'} . "n");
        fwrite($fh, "CallerID: " . $request->{'FromPhoneNumber'} . "n");
        fwrite($fh, "MaxRetries: 3n");
        fwrite($fh, "RetryTime: 5n");
        fwrite($fh, "Context: remind_eventn");
        fwrite($fh, "Extension: 111n");
        fwrite($fh, "Priority: 1n");
        fwrite($fh, "Archive: Yesn");
        fclose($fh);
        touch($tmpcallfile, time()+30);
        rename($tmpcallfile, $callfile);
}
?>

我的想法是简单地使用curl在extensions.conf中调用Web服务。

[voxbeam_outbound]
exten => _X.,1,NoOp()
        same => n,Answer
        same => n,Dial(SIP/voxbeam_outbound/${EXTEN})
[remind_event]
exten => _X.,1,Answer
        same => n,Set(status=${CURL(http://localhost/ShouldRemindEvent)})
        same => n,GotoIf($["${status:0:1}" != "1"]?10)
        same => n,Dial(SIP/voxbeam_outbound/${EXTEN})
        same => n,Playback(remind_event)
        same => n,Hangup
        same => 10,Hangup

我认为,如果我要检查Web服务,然后如果WebService回复了1。

对于完整性,在sip.conf中也添加了行,尽管我猜这些实际上与:

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

所以问题是,我可以这样做,还是我需要编写一个AGI脚本才能实现我想要的?

我意识到这是编程和配置之间的混合,我相信这最适合stackoverflow而不是超级用户,因为它是我正在构建的应用程序,并且由于涉及编程。

编辑:根据@arheops的建议,我尝试使用local

致电

php脚本中的新线路,还为我要到达的最终电话号码添加了一个phone_number变量,尽管我可以在Dialplan脚本中使用它

fwrite($fh, "Channel: Local/0@remind_eventn");
...
fwrite($fh, "SetVar: PHONE_NUMBER=" . $request->{'ToPhoneNumber'} . "n");

extensions.conf

中的拨号计划脚本中的新smind_event
[remind_event]
exten => 0,1,NoOp()
       same => n,Dial(SIP/voxbeam_outbound/${PHONE_NUMBER})
       same => n,Playback(remind_event)
       same => n,Hangup

,但似乎仍然根据星号的详细日志

失败
Connected to Asterisk 13.16.0 currently running on hostname (pid = 22261)
    -- Attempting call on Local/0@remind_event for 111@remind_event:1 (Retry 1)
    -- Called 0@remind_event
    -- Executing [0@remind_event:1] NoOp("Local/0@remind_event-00000000;2", "") in new stack
    -- Executing [0@remind_event:2] Dial("Local/0@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/0@remind_event-00000000;2
    -- Local/0@remind_event-00000000;1 is making progress
       > 0xffa3a0 -- Probation passed - setting RTP source address to <hidden ip>:15476
    -- SIP/voxbeam_outbound-00000000 requested media update control 26, passing it to Local/0@remind_event-00000000;2
    -- SIP/voxbeam_outbound-00000000 requested media update control 26, passing it to Local/0@remind_event-00000000;2
    -- SIP/voxbeam_outbound-00000000 is ringing
    -- Local/0@remind_event-00000000;1 is ringing
    -- SIP/voxbeam_outbound-00000000 answered Local/0@remind_event-00000000;2
    -- Local/0@remind_event-00000000;1 answered
[Aug  1 12:18:15] WARNING[22326][C-00000001]: pbx.c:4414 __ast_pbx_run: Channel 'Local/0@remind_event-00000000;1' sent to invalid extension but no invalid handler: context,exten,priority=remind_event,111,1
[Aug  1 12:18:15] NOTICE[22326][C-00000001]: pbx_spool.c:460 attempt_thread: Call completed to Local/0@remind_event
    -- Channel SIP/voxbeam_outbound-00000000 joined 'simple_bridge' basic-bridge <988269c4-fbe9-439f-b0a9-22af873d5118>
    -- Channel Local/0@remind_event-00000000;2 joined 'simple_bridge' basic-bridge <988269c4-fbe9-439f-b0a9-22af873d5118>
    -- Channel Local/0@remind_event-00000000;2 left 'simple_bridge' basic-bridge <988269c4-fbe9-439f-b0a9-22af873d5118>
  == Spawn extension (remind_event, 0, 2) exited non-zero on 'Local/0@remind_event-00000000;2'
    -- Channel SIP/voxbeam_outbound-00000000 left 'simple_bridge' basic-bridge <988269c4-fbe9-439f-b0a9-22af873d5118>

您的呼叫文件具有重试参数,因此认为呼叫失败并进行重试。

您有3个选项

1(在不需要的情况下删除文件

2(在挂起之前接听电话。

3(删除重试。

调用文件非常适合调度,但是我会使用PHP AGI而不是拨号程序来执行网络。

您将"呼叫文件拨号"一个本地扩展,并带有目标电话号码,以及查询Web服务(用户ID,电子邮件等(所需的任何参数。然后,AGI执行卷曲请求,您可以继续从AGI内拨号。我猜这对您来说比拨号程序更舒服。它会删除混乱的"出于某种原因x"部分,因为您在php中直接控制了呼叫,并且可以在AGI脚本中登录文件。

您也可以执行更多高级的API查询,例如需要验证令牌的外部API,处理更复杂的输出等。

这里有一些有用的链接可以让您入门:

agi库链接(我个人更喜欢phpagi(

php curl docs

从星号社区获得了一些很大的帮助。主要问题是需要两个上下文,一个是通话的每个腿。

  • 一个上下文,用拨号(下面的消息_dial(进行呼叫
  • 播放声音文件的另一个上下文。(下面消息(

这是有效的Extensions.conf文件。只需在拨号命令之前在Message_dial中的拨号程序中添加任何条件:

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

呼叫文件看起来像这样

Channel: Local/s@message_dial
CallerID: +46<hidden>
MaxRetries: 3
RetryTime: 15
Context: message
Extension: s
Priority: 1
Archive: Yes
SetVar: PHONE_NUMBER=+46<hidden>

因此,看看最终解决方案,对于熟练的星号的任何人来说,它真的很直截了当。

我宁愿将原始动作与本地渠道和AGI一起使用。另一个不错的选择是Ari,让您使用Asterisk做任何您想做的事情。

我正在使用ajam,phpami或pami。您必须考虑这一点。

最新更新