2017-02-04 66 views
2

我正在關注使用Heroku上的python部署的,並且能夠撥打電話。這是我遇到的問題。我沒有修改任何TVOIncomingCall實例或PKPushRegistry的init或委託邏輯。實際上,當我編譯時,日誌說"pushRegistry:didUpdatePushCredentials:forType""Successfully registered for VoIP push notifications."這讓我覺得我的server.py中的傳入處理程序是問題。使用Twilio可編程語音SDK接收呼叫

我的問題是這樣的:在python中,什麼是正確的方式來觸發VoIP推送通知來通知用戶來電?我已經在我的應用程序中啓用了VoIP服務,並生成了VoIP服務證書(.p12),並收到了有效的PUSH_CREDENTIAL_SID我的努力,但如何處理?

快速入門說打我的服務器的'placeCall'端點,所以我更新我的Twilio號碼的傳入路徑,並相應地在儀表板中指出它,但這會導致「應用程序錯誤已發生」響應,每當有人打電話給我的Twilio號碼。

這裏是我的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_test'另外,PUSH_CREDENTIAL_SID在哪裏起作用?

在此先感謝。

UPDATE
______

按@ philnash的評論,我已經嵌套在dial動詞內部client名詞。這是我的新/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作爲參數。

IDENTITY串在我的server.py是:

  1. 定義的任何方法範圍之外。
  2. 用於生成accessToken
  3. 嵌套在client名詞的dial動詞。

回答

1

Twilio開發者傳道這裏。

/placeCall終端不適合您的Twilio號碼的來電webhook。在這個例子中,它被用來簡單地生成一個到客戶端的呼叫。

而是,您的傳入呼叫webhook應該指向一個端點,該端點將返回一些TwiML指示Twilio撥打您的客戶端。 TwiML只是XML的一個子集,您需要的元素是<Dial>,嵌套<Client>。你的端點應該返回類似於:

<Response> 
    <Dial> 
    <Client>YOUR_CLIENT_NAME</Client> 
    </Dial> 
</Response> 

讓我知道這是否有幫助。

更新

基於對問題的更新,我們現在需要產生這種TwiML Python編寫的。您可以使用Python的with語法將nest TwiMLTwilio Python helper library一起使用。我相信這應該工作:

@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) 
+0

感謝菲爾的迴應!我已經更新了我原來的問題。請參閱更新部分中的註釋。 :) –

+0

感謝您的更新。我認爲你沒有正確地進行嵌套,請檢查我的更新答案。行! – philnash

+0

行!現在我們到了某個地方!更新服務器與您的建議,現在變得'錯誤 - 52134 - 無效APNs設備令牌'。我將重新生成並上傳新的VoIP服務證書並更新我的推送憑據SID。感謝菲爾。 –

0

使用新的推送憑證SID更新應用服務器的server.py文件中的PUSH_CREDENTIAL_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是參考包含一些調用說明的TwiML app

+0

謝謝你的迴應梅根!我應該從一開始就共享更多的代碼,但大部分你所說的實際上已經在我的server.py中。我沒有在'placeCall'函數中包含最後兩行。但是,它現在在那裏,但調用我的Twilio號碼仍然導致可怕的「應用程序錯誤已發生」響應消息。 –