python - 无法使用 Asterisk 生成对手机的调用

标签 python voip asterisk

我目前正在开展一个项目“电子邮件到语音通话”。我使用 python 提取了电子邮件并将其转换为语音并保存在 WAV 文件中。现在使用 Asterisk (我在我的 ubuntu 10.10 操作系统上安装了 Asterisk 10.2.1),我想通过我的系统生成对用户手机(比如 919833000000 印度号码)的调用。

我编写了一个Python代码来连接到 Asterisk 管理器界面。我还配置了 sip.conf 和 extensions.conf 文件以及 manager.conf。我已向 voip 提供商 voiceall.com 注册并拥有其用户名密码。

现在,当我执行 python 代码时,代码执行时没有任何错误,但什么也没有发生。没有生成任何调用。谁能帮我解决这个问题。 python代码如下:

import sys, os, socket, random
# Asterisk Manager connection details
HOST = '127.0.0.1'
PORT = 5038
# Asterisk Manager username and password
USER = 'MYUSERNAME'
SECRET = 'MYPASSWORD'
# Set the name of the SIP trunk to use for outbound calls
TRUNK = 'voiceall'



OUTBOUND = '919833000000'

# Send the call details to the Asteirsk Manager Interface
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
sleep(3)
s.send('Action: login\r\n')
s.send('Username: ' + USER + '\r\n')
s.send('Secret: ' + SECRET + '\r\n\r\n')
sleep(3)
s.send('Action: status\r\n')
data = s.recv(1024)
print data + '\n'
s.send('Events: off\r\n\r\n')
sleep(3)
s.send('Action: originate\r\n')
s.send('Channel: Sip/' + TRUNK + '/' + OUTBOUND + '\r\n')
s.send('WaitTime: 30\r\n')
s.send('CallerId: VOICEALL_USERNAME\r\n')
s.send('Application: playback\r\n')
s.send('Data: /home/Documents/newdemo1' + '\r\n')  #newdemo1 is the wave file
s.send('Context: testing\r\n')
s.send('Async: true\r\n')
s.send('Priority: 1\r\n\r\n')
sleep(10)
s.send('Action: Logoff\r\n\r\n')
s.close()

我的 sip.conf 文件如下:

[general]                
register => VOICEALL_USERNAME:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5f0910161c1a1e1313000f1e0c0c08100d1b1f2c362f712930363c3a3e333371313a2b" rel="noreferrer noopener nofollow">[email protected]</a>:5038

[voiceall]
canreinvite=no
context=mycontext
host=sip.voiceall.net
secret=VOICEALL_PASSWORD ;your password
type=peer
username=VOICEALL_USERNAME ;your account
disallow=all
allow=ulaw

fromuser=VOICEALL_USERNAME ;your account
trustrpid=yes
sendrpid=yes
insecure=invite
nat=yes

extensions.conf 文件如下:

[mycontext]

include => voiceall-outbound

[voiceall-outbound]
exten => _1NXXNXXXXXX,1,Dial(SIP/${EXTEN}@voiceall)
exten => _1NXXNXXXXXX,n,Playback(/home/Documents/demonew1)
exten => _1NXXNXXXXXX,n,Hangup()
exten => _NXXNXXXXXX,1,Dial(SIP/1${EXTEN}@voiceall)
exten => _NXXNXXXXXX,n,Playback(/home/Documents/demonew1)
exten => _NXXNXXXXXX,n,Hangup()
exten => _011.,1,Dial(SIP/${EXTEN}@voiceall)
exten => _011.,n,Playback(/home/Documents/demonew1)
exten => _011.,n,Hangup()

请帮助我,因为我是 Asterisk 的新手。 任何帮助将不胜感激。提前致谢。

最佳答案

在评论您的原始命令之前需要注意一些事项:

  1. 基于 TCP 的 AMI 的 Python 包装器库已存在:starpy 。您可能需要检查一下,因为它将减少您为启动和运行而需要重新发明轮子的工作量。

  2. 一般来说,您可能不应该为 AMI 操作中的每个参数使用单独的 TCP 发送。相反,您应该单独发送每条消息。一般来说,starpy 通过将每个 AMI 操作视为键/值对的字典来很好地处理这个问题,这显然很好地映射到 AMI 的语法。如果您决定不使用 starpy,您可能仍想了解它们如何将通用字典映射到 AMI 操作。

  3. 您在 manager.conf 中是否为您的用户提供了适当的身份验证类别?为了发起调用,您的用户将需要写入授权的发起类

在您的发起中,您尝试调用 SIP/voiceall/919833000000。这意味着 Asterisk 将创建一个 SIP channel ,并在上下文 voiceall-outbound (因为它是您指定的对等方的默认上下文)、与您指定的扩展匹配的扩展处启动其 pbx_thread。

首先,您尝试放置的扩展名是 919833000000。您没有与此匹配的扩展名 - 最接近的扩展名是 _NXXNXXXXXX。这指定其模式匹配,第一个字符必须是数字 [2-9],接下来的两个字符是数字 [0-9],第四个字符是数字 [2-9],接下来的六个字符字符为数字[0-9],总共10个字符。您指定的扩展名是 12 个字符。我预计源会失败。

假设源确实成功,并且您有一个模式匹配扩展,其应用程序与 _NXXNXXXXXX 相同。您发起的 channel 将与其他内容绑定(bind) - 另一个上下文、扩展、拨号计划中的优先级或应用程序。在您的情况下,您已经指定了两者:要连接到(播放)的应用程序,以及传递给它的数据,以及上下文和优先级(但没有扩展名)。那是无效的。来自 Asterisk 的“manager show command originate”:

扩展 扩展使用(需要“上下文”和“优先级”) 语境 使用上下文(需要“扩展”和“优先级”) 优先事项 使用优先级(需要“扩展”和“上下文”)

一般来说,您不会将应用程序/数据与上下文、扩展、优先级结合起来。当您只想对调用的内容执行非常简单的操作时,就存在“应用程序/数据”选项 - 在您的示例中,播放消息符合要求,但一般来说,我更喜欢将其连接到拨号计划中的其他内容,因此我有更多控制。我假设您想要使用 Context、Exten、Priority - 在这种情况下,您可以执行如下操作:

[testing]
exten => internal_playback,1,NoOp()
same => n,Playback(/home/Documents/demonew1)
same => n,Hangup()

[voiceall-outbound]
exten => _9XXXXX000000,1,NoOp()
same => n,Dial(SIP/${EXTEN}@voiceall)
same => n,Hangup()

您的来源将如下所示:

Action: Originate
Channel: local/internal_playback@testing
Context: voiceall-outbound
Exten: 919833000000
Priority: 1

您会注意到,我们不再使用 SIP channel 来调用拨号方案。您仍然可以在您的源中使用 SIP channel - 这实际上只是个人偏好。 Dial 应用程序已经为我们创建了一个 SIP channel ,并将其桥接到我们发起的任何地方,因此我们只使用本地 channel 。对于我们的本地 channel ,我们将一端连接到内部播放分机,用于向拨号方播放声音,另一端连接到出站分机。

关于python - 无法使用 Asterisk 生成对手机的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10025422/

相关文章:

python - 回归结果不正确

c++ - 在 mac 中创建 dylib 在 python 中导入

iOS 使用 webrtc 和 Call Kit 保持后没有音频

voip - Restcomm Apps 中的基本逻辑组件

python - 将 Python Pandas 数据帧写入 CSV 文件时出现 Unicode 错误

c++ - C/C++如何知道动态分配的数组有多长

installation - 使用 Asterisk 设置 IVR

Asterisk,如何播放音频文件

actionscript-3 - flex AS3和 Asterisk 服务器之间的通信?

javascript - Asterisk:通过 AMI 使用模板创建用户