Python 使用Twilio可编程语音SDK接收呼叫
我正在Heroku上使用python部署,并且能够很好地进行调用。这是我遇到的问题接收。我没有修改Python 使用Twilio可编程语音SDK接收呼叫,python,twilio,voip,Python,Twilio,Voip,我正在Heroku上使用python部署,并且能够很好地进行调用。这是我遇到的问题接收。我没有修改TVOIncomingCall实例或PKPushRegistry的任何init或委托逻辑。事实上,当我编译时,日志上写着“pushRegistry:didUpdatePushCredentials:forType”和“已成功注册VoIP推送通知。”这让我认为我的服务器上的传入处理程序是问题所在 我的问题是:在python中,发出VoIP推送通知以通知用户来电的正确方法是什么?我已经在我的应用程序中启
TVOIncomingCall
实例或PKPushRegistry
的任何init或委托逻辑。事实上,当我编译时,日志上写着“pushRegistry:didUpdatePushCredentials:forType”
和“已成功注册VoIP推送通知。”
这让我认为我的服务器上的传入处理程序是问题所在
我的问题是:在python中,发出VoIP推送通知以通知用户来电的正确方法是什么?我已经在我的应用程序中启用了VoIP服务,生成了VoIP服务证书(.p12),并收到了有效的推送凭证\u SID
,但如何处理它呢
“快速启动”要求点击我的服务器的“placeCall”端点,因此我更新了Twilio号码的传入路径,并在仪表板中相应地指向它,但无论何时有人调用我的Twilio号码,这都会导致“出现应用程序错误”响应
以下是my server.py中的相关代码:
import os
from flask import Flask, request
from twilio.jwt.access_token import AccessToken, VoiceGrant
from twilio.rest import Client
import twilio.twiml
ACCOUNT_SID = 'ACxxxxxxxx'
API_KEY = 'SKxxxxxxxxxxxxxxxx'
API_KEY_SECRET = 'xxxxxxxxxxxxxxxx'
PUSH_CREDENTIAL_SID = 'CRxxxxxxxxxxxxxxxx'
APP_SID = 'APxxxxxxxxxxxxxxxx'
ACCOUNT_AUTH = 'xxxxxxxxxxxxxxxx'
IDENTITY = 'MyApp' #not literally
app = Flask(__name__)
@app.route('/accessToken')
def token():
account_sid = os.environ.get("ACCOUNT_SID", ACCOUNT_SID)
api_key = os.environ.get("API_KEY", API_KEY)
api_key_secret = os.environ.get("API_KEY_SECRET", API_KEY_SECRET)
push_credential_sid = os.environ.get("PUSH_CREDENTIAL_SID", PUSH_CREDENTIAL_SID)
app_sid = os.environ.get("APP_SID", APP_SID)
grant = VoiceGrant(
push_credential_sid = push_credential_sid,
outgoing_application_sid = app_sid
)
token = AccessToken(account_sid, api_key, api_key_secret, IDENTITY)
token.add_grant(grant)
return str(token)
@app.route('/placeCall', methods=['GET', 'POST'])
def placeCall():
account_sid = os.environ.get("ACCOUNT_SID", ACCOUNT_SID)
api_key = os.environ.get("API_KEY", API_KEY)
api_key_secret = os.environ.get("API_KEY_SECRET", API_KEY_SECRET)
push_credential_sid = os.environ.get("PUSH_CREDENTIAL_SID", PUSH_CREDENTIAL_SID)
app_sid = os.environ.get("APP_SID", APP_SID)
CALLER_ID = request.values.get('From')
IDENTITY = request.values.get('To')
#client = Client(api_key, api_key_secret, account_sid)
client = Client(api_key, api_key_secret, account_sid, app_sid, push_credential_sid)
call = client.calls.create(to='client:' + IDENTITY, from_= 'client:' + CALLER_ID)
return str(call.sid)
我的Identity
值显然是错误的。我认为它需要以某种方式等同于对应用程序实例的引用。在快速启动python示例中,IDENTITY='voice\u test'
还有,PUSH\u凭证\u SID
在哪里发挥作用
提前谢谢
更新______ 根据@philnash的评论,我将
client
名词嵌套在dial
动词中。这是我新的/incoming
端点:
@app.route('/incoming', methods=['GET', 'POST'])
def incoming():
CALLER_ID = request.values.get('From')
resp = twilio.twiml.Response()
resp.dial(client = IDENTITY, callerId = CALLER_ID, record = "record-from-answer-dual")
return str(resp)
现在,这会导致调试器中出现“架构验证警告”,指出“未知或意外的嵌套元素”是可能的原因。我是否注册的客户不正确?旧SDK允许您显式地将clientName作为参数传入
my server.py中的IDENTITY
字符串是:
dial
动词的client
名词中使用新的推送凭据SID更新应用程序服务器的
server.py
文件中的PUSH\u CREDENTIAL\u SID
值。它在文件顶部带有以下常量:
ACCOUNT_SID = 'AC***'
API_KEY = 'SK***'
API_KEY_SECRET = '***'
PUSH_CREDENTIAL_SID = 'CR***'
APP_SID = 'AP***'
在您的placeCall
功能中:
def placeCall():
account_sid = os.environ.get("ACCOUNT_SID", ACCOUNT_SID)
api_key = os.environ.get("API_KEY", API_KEY)
api_key_secret = os.environ.get("API_KEY_SECRET", API_KEY_SECRET)
push_credential_sid = os.environ.get("PUSH_CREDENTIAL_SID", PUSH_CREDENTIAL_SID)
app_sid = os.environ.get("APP_SID", APP_SID)
您似乎还缺少上面的
APP_SID
,它是包含一些调用指令的引用 这里是Twilio开发者福音传道者
/placeCall
端点不适用于您的Twilio号码的来电webhook。在本例中,它仅用于生成对客户端的调用
相反,您的传入呼叫webhook应该指向一个端点,该端点将返回一些指示Twilio来拨打您的客户端。TwiML只是XML的一个子集,您需要的元素是嵌套的。您的端点应该返回如下内容:
<Response>
<Dial>
<Client>YOUR_CLIENT_NAME</Client>
</Dial>
</Response>
谢谢你的回复,梅根!从一开始我就应该分享更多的代码,但事实上,您告诉我的大部分内容都已经在我的server.py中了。我没有在“placeCall”函数中包含最后两行。然而,它现在就在那里,但是拨打我的Twilio号码仍然会导致可怕的“应用程序错误已发生”响应消息。感谢您的回复!我已经更新了我原来的问题。请参阅更新部分中的注释。:)谢谢你的更新。我不认为你做的嵌套正确,检查我的更新答案。好的!现在我们有进展了!根据您的建议更新了服务器,我现在收到“错误-52134-无效的APNs设备令牌”。我将重新生成并上载新的VoIP服务证书,并更新推送凭据SID。谢谢你,菲尔。
@app.route('/incoming', methods=['GET', 'POST'])
def incoming():
CALLER_ID = request.values.get('From')
resp = twilio.twiml.Response()
with resp.dial(callerId = CALLER_ID, record = "record-from-answer-dual") as dial:
dial.client(IDENTITY)
return str(resp)