我正在努力开发一个提醒系统,它将自动调用来提醒一个人某一特定事件。为此,我使用星号进行调用和PHP,以便为Asterisk创建一个调用文件。我希望调用文件在添加后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: 3\n");
fwrite($fh, "RetryTime: 5\n");
fwrite($fh, "Context: remind_event\n");
fwrite($fh, "Extension: 111\n");
fwrite($fh, "Priority: 1\n");
fwrite($fh, "Archive: Yes\n");
fclose($fh);
touch($tmpcallfile, time()+30);
rename($tmpcallfile, $callfile);
}
?>我的想法是简单地使用extensions.conf中的curl调用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服务,然后去10去挂断,如果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脚本来实现我想要的?
我意识到这是编程和配置的混合体,我认为这最适合于堆栈溢出,而不是超级用户,因为它是我正在构建的应用程序,而且涉及到编程。
编辑:根据@arheops的建议,我尝试过使用本地调用
php脚本中的新行,也在我想要达到的最终电话号码中添加了一个PHONE_NUMBER变量,不过我可以在拨号计划脚本中使用它。
fwrite($fh, "Channel: Local/0@remind_event\n");
...
fwrite($fh, "SetVar: PHONE_NUMBER=" . $request->{'ToPhoneNumber'} . "\n");在remind_event中的拨号计划脚本中的新extensions.conf
[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>发布于 2019-08-04 10:38:24
从星号社区得到了很大的帮助。主要的问题是,需要两种情况,每一阶段调用一次。
下面是工作的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>因此,从最终的解决方案来看,对于任何精通星号的人来说,这是非常直接的。
发布于 2019-08-02 15:26:14
调用文件是很好的调度,但我会使用PHP AGI而不是拨号计划来做web端。
您将让呼叫文件拨一个带有目标电话号码的本地exten,以及查询web服务(用户ID、电子邮件等)所需的任何参数。然后AGI执行curl请求,您可以继续从AGI内部拨号。我猜这对你来说比拨号计划更舒服。它将消除“由于某种原因它做X”的部分混乱,因为您在PHP中直接控制调用,并且可以从您的AGI脚本中登录到文件。
您还可以执行更高级的API查询,例如需要auth令牌的外部API、处理更复杂的输出等。
以下是一些帮助您入门的链接:
AGI图书馆链接 (我个人更喜欢PHPAGI)
发布于 2019-08-09 16:18:37
为此,我宁愿使用带有本地通道和AGI的起始AMI操作。另一个很好的选择是ARI,让你用星号做你想做的任何事情。
我正在使用AJAM或phpAMI或PAMI。你必须考虑这一点。
https://stackoverflow.com/questions/57279524
复制相似问题