我正在尝试开发一个提醒系统,该系统将自动调用以提醒一个特定事件的人。为此,我使用星号进行呼叫和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。您必须考虑这一点。