调用文件,如果网络服务这样说,则取消调用

我正在尝试开发一个提醒系统,该系统将自动拨打电话提醒某人特定事件。为此,我使用 Asterisk 进行调用,并使用 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

我想,如果我会检查网络服务,然后转到 10 挂断,如果网络服务回复 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 而不是超级用户,因为它是我正在构建的应用程序,并且因为涉及编程。


白衣非少年
浏览 123回答 3
3回答

萧十郎

你的调用文件有重试参数,所以它认为调用失败并重试。您在这里有 3 个选择1)在不需要的情况下删除文件2) 挂断前接听电话。3) 删除重试。

潇潇雨雨

调用文件非常适合调度,但我会使用 PHP AGI 而不是拨号计划来做 web 端。您可以让呼叫文件使用目标电话号码和查询 Web 服务所需的任何参数(用户 ID、电子邮件等)拨打本地分机号。然后 AGI 执行 curl 请求,您可以继续从 AGI 内部拨号。我猜这对你来说比拨号计划更舒服。它将消除“出于某种原因它做了 X”的困惑部分,因为您可以在 PHP 中直接控制调用,并且可以从您的 AGI 脚本中记录到文件。您还可以执行更高级的 API 查询,例如需要身份验证令牌的外部 API、处理更复杂的输出等。

九州编程

从 Asterisk 社区得到了一些很大的帮助。主要问题是需要两个上下文,一个用于呼叫的每一段。使用 Dial 进行呼叫的一种上下文(下面的 message_dial)播放声音文件的另一个上下文。(下方留言)这是有效的 extensions.conf 文件。只需在拨号命令之前在 message_dial 的拨号计划中添加任何条件:[message_dial]exten => s,1,NoOp()&nbsp; &nbsp; &nbsp; &nbsp; same => n,Dial(SIP/voxbeam_outbound/${PHONE_NUMBER})[message]exten => s,1,NoOp()&nbsp; &nbsp; &nbsp; &nbsp; same => n,Playback(message)&nbsp; &nbsp; &nbsp; &nbsp; same => n,Hangup调用文件可能如下所示Channel: Local/s@message_dialCallerID: +46<hidden>MaxRetries: 3RetryTime: 15Context: messageExtension: sPriority: 1Archive: YesSetVar: PHONE_NUMBER=+46<hidden>所以看看最终的解决方案,对于任何精通 Asterisk 的人来说,实现它真的很简单。
打开App,查看更多内容
随时随地看视频慕课网APP