WebRTC 瀏覽器支援狀況:http://caniuse.com/#search=webrtc
注意:
- Chrome 47以上版本,若不是 https 加密連線網址,將不允許呼叫 getUserMedia() 使用麥克風、視訊。 瀏覽器 console 會有錯誤訊息:twilio.js 1.3 requires WebRTC/ORTC browser support
- 需有麥克風,否則 JavaScript SDK (twilio.min.js) 會出現找不到麥克風裝置錯誤訊息
步驟:
- PHP Server 端用到的東西,可先參考另一邊文章 「PHP 使用 Twilio 發送簡訊範例」:
A.下載 Twilio 提供的 PHP SDK。
B.取得 ACCOUNT SID、AUTH TOKEN (https://www.twilio.com/console)
- Clinet端瀏覽器則會用到 JavaScript SDK (twilio.min.js)
我之前使用時,GA(Generally Available)版本為 1.3,所以以下都用1.3版當作範例。
1.3版網址: https://www.twilio.com/docs/api/client/twilio-js-13
官方說明為直接外部引用,也可選擇將 twilio.min.js 直接下載回來再使用。<script src="//media.twiliocdn.com/sdk/js/client/v1.3/twilio.min.js" type="text/javascript">
官網說明:The twilio.js Library: Twilio in the Browser - Twilio - 登入 Twilio 管理介面,到「Home / Phone Numbers / Tools / TwiML Apps」
新增一個 TwiML App 設定,然後記下 「TwiML App 的 SID」
「FRIENDLY NAME」:自己任意定義的名稱
「Voice 的 REQUEST URL」:這個很重要,是要給 Twilio 訪問的網址,請填一個之後要開放給 Twilio 訪問的網址。 - 下載官方 PHP + JavaScript 範例測試
GitHub:https://github.com/TwilioDevEd/client-quickstart-php
下載:https://github.com/TwilioDevEd/client-quickstart-php/archive/master.zip
解壓縮,並將步驟1 Twilio 提供的 PHP SDK,放到 vendor/ 資料夾下,因範例檔引用路徑是 include('./vendor/autoload.php')。
最後上傳到可執行PHP的對外Server。
官方 PHP + JavaScript 範例裡面有幾個檔:index.html、quickstart.js、config.example.php、token.php、randos.php、voice.php,說明如後。 - 「index.html」,引用 twilio.min.js (twilio 的 JavaScript SDK工具包)、quickstart.js (JavaScript 使用範例,可隨自己需求修改)
<!DOCTYPE html> <html> <head> <title>Twilio Client Quickstart</title> <link rel="stylesheet" href="site.css"> </head> <body> <div id="controls"> <div id="info"> <p class="instructions">Twilio Client</p> <div id="client-name"></div> </div> <div id="call-controls"> <p class="instructions">Make a Call:</p> <input id="phone-number" type="text" placeholder="Enter a phone # or client name" /> <button id="button-call">Call</button> <button id="button-hangup">Hangup</button> </div> <div id="log"></div> </div> <script type="text/javascript" src="//media.twiliocdn.com/sdk/js/client/v1.3/twilio.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script src="quickstart.js"></script> </body> </html>
- 「quickstart.js」,twilio.min.js 使用範例。
其中這一段會將參數資料傳送給 Twilio,之後 Twilio 訪問第3步驟設定的網址時,也會將這些參數資料一併回傳,所以自訂此處的參數資料,可做一些想達到的效果,例如接收要撥的電話號碼、或是進行自己定義的驗證規則。... // get the phone number to connect the call to var params = { To: document.getElementById('phone-number').value }; console.log('Calling ' + params.To + '...'); Twilio.Device.connect(params); ...
quickstart.js完整內容:$(function() { log('Requesting Capability Token...'); $.getJSON('./token.php') .done(function(data) { log('Got a token.'); console.log('Token: ' + data.token); // Setup Twilio.Device Twilio.Device.setup(data.token); Twilio.Device.ready(function(device) { log('Twilio.Device Ready!'); document.getElementById('call-controls').style.display = 'block'; }); Twilio.Device.error(function(error) { log('Twilio.Device Error: ' + error.message); }); Twilio.Device.connect(function(conn) { log('Successfully established call!'); document.getElementById('button-call').style.display = 'none'; document.getElementById('button-hangup').style.display = 'inline'; }); Twilio.Device.disconnect(function(conn) { log('Call ended.'); document.getElementById('button-call').style.display = 'inline'; document.getElementById('button-hangup').style.display = 'none'; }); Twilio.Device.incoming(function(conn) { log('Incoming connection from ' + conn.parameters.From); var archEnemyPhoneNumber = '+12099517118'; if (conn.parameters.From === archEnemyPhoneNumber) { conn.reject(); log('It\'s your nemesis. Rejected call.'); } else { // accept the incoming connection and start two-way audio conn.accept(); } }); setClientNameUI(data.identity); }) .fail(function() { log('Could not get a token from server!'); }); // Bind button to make call document.getElementById('button-call').onclick = function() { // get the phone number to connect the call to var params = { To: document.getElementById('phone-number').value }; console.log('Calling ' + params.To + '...'); Twilio.Device.connect(params); }; // Bind button to hangup call document.getElementById('button-hangup').onclick = function() { log('Hanging up...'); Twilio.Device.disconnectAll(); }; }); // Activity log function log(message) { var logDiv = document.getElementById('log'); logDiv.innerHTML += '<p>> ' + message + '</p>'; logDiv.scrollTop = logDiv.scrollHeight; } // Set the client name in the UI function setClientNameUI(clientName) { var div = document.getElementById('client-name'); div.innerHTML = 'Your client name: <strong>' + clientName + '</strong>'; }
- 「config.example.php」,設定檔。
config.example.php 改名 config.php
修改 config.php$TWILIO_ACCOUNT_SID = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; // 前面取得的 ACCOUNT SID $TWILIO_AUTH_TOKEN = 'your_auth_token'; //前面取得的 AUTH TOKEN $TWILIO_TWIML_APP_SID = 'APXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; // 前面取得的 TwiML App SID $TWILIO_CALLER_ID = '+1XXXYYYZZZZ'; // 向 Twilio 買的有效的號碼(有語音功能)
- 「token.php」, JS 一開始會訪問「token.php」,「token.php」會產生給 JS 用的 token
範例中只有 token是必須的,另一個 identity 可有可無(會出現在 Twilio 的撥號記錄)。<?php include('./vendor/autoload.php'); include('./config.php'); include('./randos.php'); use Twilio\Jwt\ClientToken; // choose a random username for the connecting user $identity = randomUsername(); $capability = new ClientToken($TWILIO_ACCOUNT_SID, $TWILIO_AUTH_TOKEN); $capability->allowClientOutgoing($TWILIO_TWIML_APP_SID); $capability->allowClientIncoming($identity); $token = $capability->generateToken(); // return serialized token and the user's randomly generated ID header('Content-Type: application/json'); echo json_encode(array( 'identity' => $identity, 'token' => $token, ));
- 「randos.php」,這個檔只是用來產生前面「token.php」的隨機identity,正式應該用不到。
<?php // Generate a random username for the connecting client function randomUsername() { $ADJECTIVES = array( 'Abrasive', 'Brash', 'Callous', 'Daft', 'Eccentric', 'Fiesty', 'Golden', 'Holy', 'Ignominious', 'Joltin', 'Killer', 'Luscious', 'Mushy', 'Nasty', 'OldSchool', 'Pompous', 'Quiet', 'Rowdy', 'Sneaky', 'Tawdry', 'Unique', 'Vivacious', 'Wicked', 'Xenophobic', 'Yawning', 'Zesty', ); $FIRST_NAMES = array( 'Anna', 'Bobby', 'Cameron', 'Danny', 'Emmett', 'Frida', 'Gracie', 'Hannah', 'Isaac', 'Jenova', 'Kendra', 'Lando', 'Mufasa', 'Nate', 'Owen', 'Penny', 'Quincy', 'Roddy', 'Samantha', 'Tammy', 'Ulysses', 'Victoria', 'Wendy', 'Xander', 'Yolanda', 'Zelda', ); $LAST_NAMES = array( 'Anchorage', 'Berlin', 'Cucamonga', 'Davenport', 'Essex', 'Fresno', 'Gunsight', 'Hanover', 'Indianapolis', 'Jamestown', 'Kane', 'Liberty', 'Minneapolis', 'Nevis', 'Oakland', 'Portland', 'Quantico', 'Raleigh', 'SaintPaul', 'Tulsa', 'Utica', 'Vail', 'Warsaw', 'XiaoJin', 'Yale', 'Zimmerman', ); // Choose random components of username and return it $adj = $ADJECTIVES[array_rand($ADJECTIVES)]; $fn = $FIRST_NAMES[array_rand($FIRST_NAMES)]; $ln = $LAST_NAMES[array_rand($LAST_NAMES)]; return $adj . $fn . $ln; }
- 「voice.php」,回應 Twilio,Twilio 會根據回應的內容做對應的動作。
所以回應內容前,也可自己做一些驗證,例如 Twilio 傳送過來的 ACCOUNT SID、TwiML App SID 是否正確,或自己額外傳送的資料是否正常。
voice.php 的網址須為「Voice 的 REQUEST URL」填的網址。<?php include('./vendor/autoload.php'); include('./config.php'); #$response = new \Twilio\Twiml; //SDK 5.4.2 $response = new \Twilio\TwiML\VoiceResponse();; //SDK 6.40.1 // get the phone number from the page request parameters, if given if (isset($_REQUEST['To']) && strlen($_REQUEST['To']) > 0) { $number = htmlspecialchars($_REQUEST['To']); #$dial = $response->dial(array('callerId' => $TWILIO_CALLER_ID)); //SDK 5.4.2 $dial = $response->dial("", array('callerId' => $TWILIO_CALLER_ID)); //SDK 6.40.1 // wrap the phone number or client name in the appropriate TwiML verb // by checking if the number given has only digits and format symbols if (preg_match("/^[\d\+\-\(\) ]+$/", $number)) { $dial->number($number); //播電話給$number這個號碼 } else { $dial->client($number); } } else { $response->say("Thanks for calling!");//會用語音講"Thanks for calling" } header('Content-Type: text/xml'); echo $response; //因要給Twilio 訪問,所以是公開的網址,因此也可以自行加些驗證判斷,不合法就回應404 //header("HTTP/1.0 404 Not Found");
最後結果產生的 XML 格式如下,
用買的電話號碼 $TWILIO_CALLER_ID(+447*********),撥電話給 $number(+886*********)<?xml version="1.0" encoding="UTF-8"?> <Response><Dial callerId="+447*********"><Number>+886*********</Number></Dial></Response>
- Twilio 發送紀錄:https://www.twilio.com/console/voice/dashboard
發送失敗debug:https://www.twilio.com/console/dev-tools/debugger
參考:
- Which browsers support WebRTC? – Twilio Support
「Which browsers support WebRTC?
The Twilio Client JavaScript SDK version 1.3 supports WebRTC on the most recent versions of Chrome and Firefox,
and provides ORTC support for Microsoft Edge. Desktop browsers which do not support WebRTC/ORTC,
including Safari on Mac OS X and Internet Explorer, can use Twilio Client SDK 1.2 which includes a Flash version.」 - Twilio Client Javascript Quickstart - Twilio
- 價格:https://www.twilio.com/pricing
語音費用:https://www.twilio.com/voice/pricing
瀏覽器client費用:https://www.twilio.com/client/pricing - 錯誤代號說明:Error and Warning Dictionary - Twilio
- TwiML™ Voice: Twilio's Request - Twilio
- https://www.twilio.com/docs/libraries/reference/twilio-php/
The Twilio PHP Helper Library - https://www.twilio.com/docs/api
API Reference - In-Depth Reference for all Twilio APIs and SDKs | Twilio
其他:
Create a Real-Time Video Chat Room with WebRTC & Twilio — SitePoint
https://docs.microsoft.com/zh-tw/azure/partner-twilio-php-make-phone-call
http://twimlets.com/message?Message=test
https://cloud.google.com/appengine/docs/flexible/nodejs/using-sms-and-voice-services-via-twilio
https://www.npmjs.com/package/twilio-js
沒有留言:
張貼留言