Getting started with Messages and Dispatch Paul Ardeleanu & Hui Jing Chen
A presentation at Vonage Campus in October 2019 in San Francisco, CA, USA by Paul Ardeleanu
Getting started with Messages and Dispatch Paul Ardeleanu & Hui Jing Chen
dashboard.nexmo.com
dashboard.nexmo.com CAMPUS2019
CampusDemo cb9d439f-5c97-42e4-b05c-eacd3980f38d • voice • messages • rtc • vbc
CampusDemo cb9d439f-5c97-42e4-b05c-eacd3980f38d nexmo-cli Server SDKs Client SDKs • • • • • • • • • nexmo-node nexmo-php nexmo-python nexmo-ruby nexmo-dotnet nexmo-java Android SDK iOS SDK JavaScript SDK
nexmo-cli
nexmo-cli ‣ Install github.com/nexmo/nexmo-cli $ npm install nexmo-cli@beta -g /usr/local/bin/nexmo -> /usr/local/lib/node_modules/nexmo-cli/lib/bin.js + nexmo-cli@0.4.9-beta-2 added 35 packages from 28 contributors and updated 17 packages in 4.886s $ yarn global add nexmo-cli@beta
nexmo-cli ‣ Setup
nexmo-cli ‣ Setup $ nexmo setup <api_key> <api_secret> No existing config found. Writing to new file. Credentials written to /Users/pardeleanu/.nexmorc C:\Users\pardeleanu/.nexmorc $ cat ~/.nexmorc [credentials] api_key=xxx api_secret=xxx
Get-Content ~/.nexmorc
nexmo-cli ‣ Create an application $ mkdir CampusDemo $ cd CampusDemo $ nexmo app:create CampusDemo Capabilities: messages ? Application Name: ? ? ? ? ? Select Messages Inbound URL: ⮐ Messages Status URL: ⮐ Public Key path: ⮐ Private Key path: ⮐ Application created: 85aabc9a-1501-4820-8683-61a5ac878ab8
nexmo-cli ‣ Create an application Application created: 85aabc9a-1501-4820-8683-61a5ac878ab8 Private Key: ——-BEGIN PRIVATE KEY——… ——-END PRIVATE KEY——- WARNING: You should save this key somewhere safe and secure now, it will not be provided again. No existing config found. Writing to new file. Credentials written to /Users/pardeleanu/CampusDemo/.nexmo-app
nexmo-cli ‣ Create an application $ cat .nexmo-app [app_config] app_id=85aabc9a-1501-4820-8683-61a5ac878ab8 private_key=”——-BEGIN PRIVATE KEY—— … ——-END PRIVATE KEY——-\n”
Get-Content .nexmo-app
nexmo-cli ‣ Create an application
nexmo-cli ‣ Create an application Application created: 85aabc9a-1501-4820-8683-61a5ac878ab8 Private Key: ——-BEGIN PRIVATE KEY——… ——-END PRIVATE KEY——- WARNING: You should save this key somewhere safe and secure now, it will not be provided again. No existing config found. Writing to new file. Credentials written to /Users/pardeleanu/CampusDemo/.nexmo-app To recreate this application in the future without interactive mode use the following command: nexmo app:create CampusDemo —capabilities=messages —messages-inbound-url=https:// example.com/ —messages-status-url=https://example.com/
Webhooks nexmo app:create CampusDemo —capabilities=messages —messages-inbound-url=https://example.com/ —messages-status-url=https://example.com/ Inbound webhook Status webhook
webhooks ‣ Status Send SMS CampusDemo cb9d439f-5c97-42e4-b05c-eacd3980f38d https://example.com
webhooks ‣ Inbound https://example.com/inbound Inbound message CampusDemo cb9d439f-5c97-42e4-b05c-eacd3980f38d https://example.com/status
dashboard.nexmo.com
dashboard.nexmo.com
Authorization POST https://api.nexmo.com/v0.1/messages Authorization: ??? …
authorization ‣ JSON Web Tokens jwt.io/introduction
authorization ‣ Generate a JWT $ nexmo jwt:generate eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1NzAyODQ4NTAsImp0aSI6IjY2ODM3YjcwLW U3N2EtMTFlOS1iMzU2LTk1YWZjODM0NGExYiIsImFwcGxpY2F0aT3uX2lkIjoiODVhYWJjOWEtM2UwMS00O DI4LTg2ODMtNjFhNWFjODc4YWI4In0.N5WzcVvpR6uIiz_OjdAUM2YwfxDFrb50qnxcla8cbIateYNg10MydHK5mY8zqGWHdVCGY04Qq7HHEyltYDLk2H87duE3bvryHgzAP 1462mMIirraknSVooHrmahDuVyPdaHbr3TOHgCYIwINqX1Q0PpqVw6QOXTs4bzXDWaswH6Ly97i6wheshmsxkblxGY_ea_RQ RLJrzUJ9m6vsEtdNcYZh6D70367_hPdzKU0qgGmZNzStSwwmvauTnoL3fcOcB_B510lchR4XLfdpN0Okb6P0ZZea222 aqya1BCF3SjT3fiO5c1h3fbS9k9HPmMMEBM9U91PrzPZDcXCw_w
authorization ‣ JWT POST https://api.nexmo.com/v0.1/messages Authorization: Bearer eyJ…w_w …
Getting started with Messages and Dispatch Paul Ardeleanu & Hui Jing Chen
It started with a… SMS
SMS APIs Brand alerts customer that the package has been shipped. Toy Store Your package has been shipped! More info at www.toystore123.com
SMS APIs Brand alerts customer that the package has been shipped. Package is not delivered !?!#@?! Toy Store Your package has been shipped! More info at www.toystore123.com
SMS APIs Brand alerts customer that the package has been shipped. Package is not delivered !?!#@?! Customer tries to respond via SMS Toy Store Toy Store Your package has been shipped! More info at www.toystore123.com Your package has been shipped! More info at www.toystore123.com My package has not been delivered. !
SMS APIs Brand alerts customer that the package has been shipped. Package is not delivered !?!#@?! Customer tries to respond via SMS Customer calls to get more information Toy Store Toy Store Your package has been shipped! More info at www.toystore123.com Your package has been shipped! More info at www.toystore123.com My package has not been delivered. !
Preferred Communication Channels Expanding beyond SMS 2.5B 1.5B 1.3B 900M OTT Messaging app users WW by 2021 WhatsApp monthly users Facebook Messenger monthly users users on Viber
Customer Experience With Social Chat Apps Brand alerts customer that the package has been shipped. Package is not delivered !?!#@?! Customer enquires Toy Store Toy Store Your package has been shipped! More info at www.toystore123.com Your package has been shipped! More info at www.toystore123.com My package has not been delivered. ✓
Customer Experience With Social Chat Apps Brand alerts customer that the package has been shipped. Package is not delivered !?!#@?! Customer enquires Brand responds with updates Toy Store Toy Store Toy Store Your package has been shipped! More info at www.toystore123.com Your package has been shipped! More info at www.toystore123.com My package has not been delivered. Your package has been shipped! More info at www.toystore123.com My package has not been delivered. Your order #ABC123 has cleared customs and entered the Royal Mail network for delivery. It will delivered on November 4th between 8am and 5pm.
Engagement Opportunities with Social Channels Toy Store Your package has been shipped! More info at www.toystore123.com My package has not been delivered. Your order #ABC123 has cleared customs and entered the Royal Mail network for delivery. It will delivered on November 4th between 8am and 5pm. For latest delivery information please visit: https://ryml.me/?ABC123 Your package has been delivered:
Engagement Opportunities with Social Channels
Messages and Dispatch APIs
Messages API Dispatch API One API, multiple channels Orchestrate messages with failover
Messages API
Access to multiple social chat apps Single API Call that sends the message via one channel
Messages API ‣ Sending POST https://api.nexmo.com/v0.1/messages Authorization: Bearer YOUR_JWT Content-Type: application/json Accept: application/json { “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “message”: { “content”: { “type”: “text”, “text”: “This is an example SMS sent using the Messages API” } } }
Messages API ‣ Sending POST https://api.nexmo.com/v0.1/messages Authorization: Bearer YOUR_JWT Content-Type: application/json Accept: application/json { “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “message”: { “content”: { “type”: “text”, “text”: “This is an example SMS sent using the Messages API” } } }
Messages API ‣ Sending POST https://api.nexmo.com/v0.1/messages Authorization: Bearer YOUR_JWT Content-Type: application/json Accept: application/json { “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “message”: { “content”: { “type”: “text”, “text”: “This is an example SMS sent using the Messages API” } } }
Messages API ‣ Sending POST https://api.nexmo.com/v0.1/messages Authorization: Bearer YOUR_JWT Content-Type: application/json Accept: application/json { “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “message”: { “content”: { “type”: “text”, “text”: “This is an example SMS sent using the Messages API” } } }
Messages API ‣ Sending POST https://api.nexmo.com/v0.1/messages Authorization: Bearer YOUR_JWT Content-Type: application/json Accept: application/json { “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “message”: { “content”: { “type”: “text”, “text”: “This is an example SMS sent using the Messages API” } } }
Messages API ‣ Sending POST https://api.nexmo.com/v0.1/messages Authorization: Bearer YOUR_JWT Content-Type: application/json Accept: application/json { “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “message”: { “content”: { “type”: “text”, “text”: “This is an example SMS sent using the Messages API” } } }
Messages API POST https://api.nexmo.com/v0.1/messages Authorization: Bearer YOUR_JWT Content-Type: application/json Accept: application/json { “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “message”: { “content”: { “type”: “text”, “text”: “This is an example SMS sent using the Messages API” } } } {“message_uuid”:”87d66f13-a8a5-4894-a1e2-2a2c8f7d5cc6”}
Messages API ‣ Content Type POST https://api.nexmo.com/v0.1/messages Authorization: Bearer YOUR_JWT Content-Type: application/json Accept: application/json { “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “message”: { “content”: { “type”: “text”, “text”: “This is an example SMS sent using the Messages API” } } }
Messages API ‣ Content Type POST https://api.nexmo.com/v0.1/messages Authorization: Bearer YOUR_JWT Content-Type: application/json Accept: application/json { “from”: { “type”: “whatsapp”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “whatsapp”, “number”: “DESTINATION_NUMBER” }, “message”: { “content”: { “type”: “image”, “image”: { “url”: “https://vonage.com/Campus.png”, “caption”: “Vonage Campus” } } } }
Messages API ‣ Channels POST https://api.nexmo.com/v0.1/messages Authorization: Bearer YOUR_JWT Content-Type: application/json Accept: application/json { “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “message”: { “content”: { “type”: “text”, “text”: “This is an example SMS sent using the Messages API” } } }
Messages API ‣ Channels “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” },
Messages API ‣ Channels “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “from”: { “type”: “mms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “mms”, “number”: “DESTINATION_NUMBER” },
Messages API ‣ Channels “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “from”: { “type”: “mms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “mms”, “number”: “DESTINATION_NUMBER” }, “from”: { “type”: “whatsapp”, “number”: “YOUR_WHATSAPP_NUMBER” }, “to”: { “type”: “whatsapp”, “number”: “DESTINATION_NUMBER” },
Messages API ‣ Channels “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “from”: { “type”: “mms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “mms”, “number”: “DESTINATION_NUMBER” }, “from”: { “type”: “whatsapp”, “number”: “YOUR_WHATSAPP_NUMBER” }, “to”: { “type”: “whatsapp”, “number”: “DESTINATION_NUMBER” }, “from”: { “type”: “messenger”, “id”: “YOUR_FB_ID” }, “to”: { “type”: “messenger”, “id”: “RECIPIENT_FB_ID” },
Messages API ‣ Channels “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “from”: { “type”: “mms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “mms”, “number”: “DESTINATION_NUMBER” }, “from”: { “type”: “whatsapp”, “number”: “YOUR_WHATSAPP_NUMBER” }, “to”: { “type”: “whatsapp”, “number”: “DESTINATION_NUMBER” }, “from”: { “type”: “messenger”, “id”: “YOUR_FB_ID” }, “to”: { “type”: “messenger”, “id”: “RECIPIENT_FB_ID” }, “from”: { “type”: “viber_service_msg”, “id”: “YOUR_VIBER_ID” }, “to”: { “type”: “viber_service_msg”, “number”: “DESTINATION_NUMBER” },
Messages API ‣ Channels SMS MMS WhatsApp Facebook Messenger Viber 3200 n/a 4096 2000 1000 Image Support ✘ 2MB .jpg 640x480 pixels ✔ .jpg, .png and .gif .jpg and .png Video Support ✘ ✘ ✔ .mp4 ✘ Audio Support ✘ ✘ ✔ .mp3 ✘ Attachments ✘ ✘ ✔ .zip, .csv, .pdf ✘ Location ✘ ✘ ✔ ✔ ✘ Templates ✘ ✘ ✔ ✔ ✔ Customer identifier Phone number Phone number Phone number Facebook ID Phone number Text character limits
Messages API ‣ Status Single API Call that sends the message via one channel Delivery callbacks with message status, timestamp, cost or any applicable errors
Messages API ‣ Status Send message CampusDemo cb9d439f-5c97-42e4-b05c-eacd3980f38d Status Webhook
Messages API ‣ Status { “message_uuid”:”ff427083-adcf-42f3-a27b-6dda9aa8a3e4”, “to”:{ “number”:”DESTINATION_NUMBER”, “type”:”sms” }, “from”:{ “number”:”YOUR_NEXMO_NUMBER”, “type”:”sms” }, “timestamp”:”2019-09-24T23:21:21.359Z”, “status”:”submitted” }
Messages API ‣ Status { “message_uuid”:”ff427083-adcf-42f3-a27b-6dda9aa8a3e4”, “to”:{ “number”:”DESTINATION_NUMBER”, “type”:”sms” }, “from”:{ “number”:”YOUR_NEXMO_NUMBER”, “type”:”sms” }, “timestamp”:”2019-09-24T23:21:21.359Z”, “status”:”submitted” { “message_uuid”:”ff427083-adcf-42f3-a27b-6dda9aa8a3e4”, “to”:{ “number”:”DESTINATION_NUMBER”, “type”:”sms” }, “from”:{ “number”:”YOUR_NEXMO_NUMBER”, “type”:”sms” }, “timestamp”:”2019-09-24T23:21:28.664Z”, “usage”:{ “price”:”0.0333”, “currency”:”EUR” }, “status”:”delivered” } }
Messages API ‣ Inbound https://example.com/inbound Inbound message CampusDemo cb9d439f-5c97-42e4-b05c-eacd3980f38d https://example.com/status
Messages API ‣ Inbound { “message_uuid”:”7dddda83-26ae-45cd-8137-74d7647cbe22”, “to”:{ “id”:”107973713947023”, “type”:”messenger” }, “from”:{ “id”:”2019895078111911”, “type”:”messenger” }, “timestamp”:”2019-10-08T15:35:07.120Z”, “direction”:”inbound”, “message”:{ “content”:{ “type”:”text”, “text”:”I’m also at Campus!” } } }
Messages API ‣ Provider verification WhatsApp Viber
WhatsApp Provided by Nexmo Developers WhatsApp • Dedicated trial support team • Online direct support tool • Simple APIs for rapid implementation • Sales Consultation and SI services • Hosting and management (+regional hosting) • Compliance (GDPR) • Enterprise Products (Audit, Reports, Redact and Media Service) • Number and PSTN Voice management for WhatsApp Number • 24/7 Global Support • Reliability of trusted CPaaS provider • Short time to market • Low implementation complexity • Lower operability costs • Low support
Messages API ‣ WhatsApp Templates
WhatsApp Templates ‣ Message Content
WhatsApp Templates ‣ Message Variables
WhatsApp Templates ‣ Message Localization
Messages API ‣ WhatsApp Templates POST https://api.nexmo.com/v0.1/messages Authorization: Bearer YOUR_JWT Content-Type: application/json Accept: application/json { “from”: { “type”: “whatsapp”, “number”: “12012444460” }, “to”: { “type”: “whatsapp”, “number”: “447700900100” }, “message”: { “content”:{ “type”:”template”, “template”:{ “name”:”whatsapp:hsm:technology:nexmo:oh_dev_onboarding_1”, “parameters”:[ { “default”:”- Vonage Connect” }, { “default”:”Taking place in SF on Oct 29th-30th.” } ] } }, “whatsapp”: { “policy”: “deterministic”, “locale”: “en-GB” } } }
Messages API Abstracted API one API to rule them all Optimize Costs Leverage SMS and various social chat apps price points to diversify operating costs
Dispatch API
Dispatch API ‣ Optimize your Messaging Strategy Westfield SFO Single API Call that initiates your custom failover flow Not available Not arriving in time
Dispatch API ‣ Optimize your Messaging Strategy Single API Call that initiates your custom failover flow Not read within 1h Not delivered within 2h Get one Delivery callback with message status, timestamp, cost or any applicable errors
Dispatch API ‣ API Call POST https://api.nexmo.com/v0.1/dispatch Authorization: Bearer APP_JWT Content-Type: application/json Accept: application/json “template”:”failover”, “workflow”: [ … ] Not read within 1h Not delivered within 2h
Dispatch API ‣ Workflow “template”:”failover”, “workflow”: [ ] Not read within 1h Not delivered within 2h
Dispatch API ‣ Workflow “template”:”failover”, “workflow”: [ Facebook Messenger Viber SMS ] Not read within 1h Not delivered within 2h
Dispatch API ‣ Workflow “template”:”failover”, “workflow”: [ { “from”: { “type”: “messenger”, “number”: “YOUR_FB_ID” }, “to”: { “type”: “messenger”, “number”: “RECIPIENT_FB_ID” }, “message”: { “content”: { “type”: “text”, “text”: “This is a Message sent via the Dispatch API” } }, “failover”:{ “expiry_time”: 3600, “condition_status”: “read” } }, Viber SMS ] Not read within 1h Not delivered within 2h
Dispatch API ‣ Workflow Not read within 1h “template”:”failover”, “workflow”: [ Facebook Messenger { “from”: { “type”: “viber_service_msg”, “id”: “YOUR_VIBER_ID” }, “to”: { “type”: “viber_service_msg”, “number”: “DESTINATION_NUMBER” }, “message”: { “content”: { “type”: “text”, “text”: “This is a Message sent via the Dispatch API” } }, “failover”:{ “expiry_time”: 7200, “condition_status”: “delivered” } }, SMS ] Not delivered within 2h
Dispatch API ‣ Workflow “template”:”failover”, “workflow”: [ Facebook Messenger Viber { “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “message”: { “content”: { “type”: “text”, “text”: “This is a Message sent via the Dispatch API” } } } ] Not read within 1h Not delivered within 2h
Dispatch API ‣ Workflow “template”:”failover”, “workflow”: [ { “from”: { “type”: “messenger”, “number”: “YOUR_FB_ID” }, “to”: { “type”: “messenger”, “number”: “RECIPIENT_FB_ID” }, “message”: { “content”: { “type”: “text”, “text”: “This is a Message sent via the Dispatch API” } }, “failover”:{ “expiry_time”: 3600, “condition_status”: “read” } }, { “from”: { “type”: “viber_service_msg”, “id”: “YOUR_VIBER_ID” }, “to”: { “type”: “viber_service_msg”, “number”: “DESTINATION_NUMBER” }, “message”: { “content”: { “type”: “text”, “text”: “This is a Message sent via the Dispatch API” } }, “failover”:{ “expiry_time”: 7200, “condition_status”: “delivered” } }, { “from”: { “type”: “sms”, “number”: “YOUR_NEXMO_NUMBER” }, “to”: { “type”: “sms”, “number”: “DESTINATION_NUMBER” }, “message”: { “content”: { “type”: “text”, “text”: “This is a Message sent via the Dispatch API” } } } ] Not read within 1h Not delivered within 2h
Dispatch API ‣ Status
{ “template”:”failover”, “status”:”completed”, “timestamp”:”2019-10-28T04:49:56.242Z”, “usage”: {“price”:”0.0363”,”currency”:”EUR”}, “dispatch_uuid”:”c5b47800-8043-4e8b-995c-5b6c8344a95d”, “_links”:{ “messages”: [ { “message_uuid”:”67d02318-a1b4-4864-85bc-aebb7f9f2403”, “href”:”v0.1/messages/67d02318-a1b4-4864-85bc-aebb7f9f2403”, “channel”:”messenger”, “usage”:{“price”:”0.001”,”currency”:”EUR”},”status”:”delivered” }, { “message_uuid”:”0e08c318-36b2-418c-a956-fbe938edbe24”, “href”:”v0.1/messages/0e08c318-36b2-418c-a956-fbe938edbe24”, “channel”:”sms”, “usage”:{“price”:”0.0333”,”currency”:”EUR”}, “status”:”delivered” } ] } }
Dispatch API ‣ Most Engaging Formats First Smart Messaging Create a strategy to ensure the most high performing channels are prioritized first. Real-time Insights Get one final callback to see the details of the message that was sent including: social channel, timestamp, delivery status and cost. Channel Evaluations Quickly evaluate the effectiveness of each social channel to optimize the costs of your messaging strategy.
Channels Available SMS MMS Facebook Messenger WhatsApp Viber Services Messages Coming soon WeChat LINE RCS Apple Business Chat
nexmo.dev/campus-md
Thank you! devrel@nexmo.com