Introduction
The Avaya Communications APIs PubSub service enables developers to use Avaya Communications APIs without exposing their network to outside traffic. This is especially important in a corporate environment.
The idea is that HTTP connections are supposed to be short-lived and that most corporate firewalls allow HTTP out on well know ports (80, 443). HTTP connections are also one-way outbound.
Traditional Avaya Communications APIs Webhook approach
Incoming Call webhook
The webhook approach has the benefit of being efficient. When a call is answered or an SMS is received, the user's webserver can be notified without any added delay. The downside is the user must open the HTTP ports up to the world for Avaya Communications APIs to reach the webserver that is receiving the webhooks.
Long-Poll Approach
The user server continuously asks the Avaya Communications APIs pubsub server if there are any new events. If there are, they will be returned as a list. If there aren't the connection will be kept alive for a whie by not returning anything until it either times out or new events are passed. Since both systems are going outbound, there are no concerns of blocking incoming traffic.
Authentication
Get Session Token:
$ curl https://pubsub-us.cpaas.avayacloud.com/auth -u <AccountSid>:<AuthToken>
5ff34c5d-5048-468b-b6c2-384d88efbb4d
Before subscribing to topics, you'll need to generate a session token. You'll pass this as either the Authorization
header or the session
GET parameter. The output is a raw text string.
URL: /auth
Method: GET
, POST
Parameters
Name | Description | Examples |
---|---|---|
ttl | How long the session is valid for | 10m , 2h |
HTTP Response Codes
Code | Meaning |
---|---|
401 | Check Account Sid and Auth Token |
Subscription
Subscribe to a topic:
$ curl -v 'https://pubsub-us.cpaas.avayacloud.com/AC948550ad81934a1a9bcd33b689c0c236/a/b?session=5ff34c5d-5048-468b-b6c2-384d88efbb4d&timeout=5s'
* Trying 172.64.153.30:443...
* Connected to pubsub-us.cpaas.avayacloud.com (172.64.153.30) port 443 (#0)
> GET /AC948550ad81934a1a9bcd33b689c0c236/a/b?session=5ff34c5d-5048-468b-b6c2-384d88efbb4d&timeout=5s HTTP/1.1
> Host: pubsub-us.cpaas.avayacloud.com
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Cache-Control: no-cache
< Connection: keep-alive
< Content-Type: application/json
< Date: Tue, 06 Dec 2016 16:52:13 GMT
< Transfer-Encoding: chunked
<
[
{
"Hostname": "pubsub-us.cpaas.avayacloud.com",
"AccountSid": "",
"Url": "/<AccountSid>/a/b",
"FormParams": {
"Custom": "123",
"Param": "abc"
},
"Created": "2022-12-06T11:52:13.114436515-05:00"
}
]
URL: /<AccountSid>/<QueueName>/
Method: GET
Any valid path may be used as the QueueName
. Examples are: /Calls/
or /Call/Dial/Action
or /node-1/critical/
. The subscriber will only see messages sent to this topic. Up to 10
messages can be received. The response is a JSON list.
If the client is capable of streaming chunked transfers, it will benefit from reduced latency and be able to parse JSON messages as they are streamed.
The messages are generally FIFO but order is not guaranteed. Messages are generally deduplicated, but the application should be idempotent in the event a message is re-delivered.
Headers
Send the session token in the Authorization
header.
Publishing
URL: /<AccountSid>/<QueueName>/
Method: POST
The queue name needs to match the name of the queue that the subscriber is listening on. The same rules apply.
If there are no subscribers available immediately, the message is put into an unbound queue which will retain messages for up to 7 days.
SMS Example
Step 1:
Set the URL on your Avaya Communications APIs Phone Number
- Go to number management) on the dashboard and click a number.
- Click SMS Settings
- Set the URL to something like
https://pubsub-us.cpaas.avayacloud.com/AC948550ad81934a1a9bcd33b689c0c236/SMS
- Click
Save
Step 2:
Generate Session Token
$ curl https://pubsub-us.cpaas.avayacloud.com/auth -u AC948550ad81934a1a9bcd33b689c0c236:$ZANG_AUTH_TOKEN
3874f087-36ab-4d1b-bf43-dd8f2b8e460f
Step 3:
Subscribe to the Topic
$ until curl 'https://pubsub-us.cpaas.avayacloud.com/AC948550ad81934a1a9bcd33b689c0c236/SMS?session=3874f087-36ab-4d1b-bf43-dd8f2b8e460f' | grep Sid;
do
echo "No messages yet.";
done
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:15 --:--:-- 0
No messages yet.
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 411 0 411 0 0 86 0 --:--:-- 0:00:04 --:--:-- 86
{
"Hostname": "pubsub-us.cpaas.avayacloud.com",
"AccountSid": "AC948550ad81934a1a9bcd33b689c0c236",
"Url": "/AC948550ad81934a1a9bcd33b689c0c236/SMS",
"FormParams": {
"AccountSid": "AC948550ad81934a1a9bcd33b689c0c236",
"ApiVersion": "v2",
"Body": "Hello from my cell phone",
"From": "+18457026652",
"SmsSid": "SM8f889084f5aa1b237844487f86ff699d",
"SmsStatus": "received",
"To": "+14083511240"
},
"Created": "2016-12-06T13:26:19.042258199-05:00"
}
The Message sent from Avaya Communications APIs to PubSub:
POST /SMS HTTP/1.1
Host: 815cba68.ngrok.io
User-Agent: Avaya Communications APIs/2.0.1
Content-Length: 172
Accept: application/xml,text/html,application/xhtml+xml,text/plain
Accept: application/xml
Agent: Avaya Communications APIs/3.0.0
Content-Type: application/x-www-form-urlencoded
X-Avaya Communications APIs-Attempt: 5
X-Avaya Communications APIs-Failover: false
X-Avaya Communications APIs-Signature: Z2DCRjSFNnVSUsVaAeuZEAzYeII=
Accept-Encoding: gzip
X-Forwarded-Proto: https
X-Forwarded-For: 159.203.69.75
AccountSid=AC948550ad81934a1a9bcd33b689c0c236&ApiVersion=v2&Body=Test+sms&From=%2B18457026652&SmsSid=SM7c889084ee9850fdbfd14d9f987d48d6&SmsStatus=received&To=%2B14089132984
Call XML Example: Hello World
When the Publish URL sees the extension .xml
and there is a CallSid
parameter POSTed to it, the server will interpret it as a call control request. This means it will not respond right away, but instead it will publish the event on the queue and then long-poll on the queue named /<AccountSid>/call.xml/<CallSid>
.
While the Call XML URL is being long-polled, another process can then POST XML to the Call's queue while will be sent to Avaya Communications APIs.
If the long-poll times out, the long poller will return XML such as the following to keep the call alive:
<Response>
<Redirect>/call.xml/$CallSid/</Redirect>
</Response>
Hello World Call Control
Set a phone number's voice URL to point to https://pubsub-us.cpaas.avayacloud.com/$ZANG_ACCOUNT_SID/call.xml in your dashboard. Then run the following and call it.
# Answer URL = https://pubsub-us.cpaas.avayacloud.com/$ZANG_ACCOUNT_SID/call.xml
session=`curl https://pubsub-us.cpaas.avayacloud.com/auth -u $ZANG_ACCOUNT_SID:$ZANG_AUTH_TOKEN`
req=`curl "https://pubsub-us.cpaas.avayacloud.com/$ZANG_ACCOUNT_SID/call.xml?session=$session&timeout=10s"`
call_sid=`echo "$req" | grep -oh "CA\w*" | head -n 1`
curl "https://pubsub-us.cpaas.avayacloud.com/$ZANG_ACCOUNT_SID/call.xml/$call_sid" \
-H "Content-Type: application/xml" \
-d "<Response>
<Say>Unit test successful</Say>
<Redirect>/$ZANG_ACCOUNT_SID/call.xml</Redirect>
</Response>"
Call XML Example: Gather
Set a phone number to pint to https://pubsub-us.cpaas.avayacloud.com/$ZANG_ACCOUNT_SID/call.xml in your dashboard. Then run the following and call it.
#!/usr/bin/env sh
echo "Getting the auth token..."
session=`curl -s https://pubsub-us.cpaas.avayacloud.com/auth -u $ZANG_ACCOUNT_SID:$ZANG_AUTH_TOKEN`
echo "Waiting for the call to be answered..."
req=`curl -s "https://pubsub-us.cpaas.avayacloud.com/$ZANG_ACCOUNT_SID/call.xml?session=$session&timeout=10s"`
call_sid=`echo "$req" | grep -oh "CA\w*" | head -n 1`
echo "Call Call Answered: $call_sid"
echo "================"
echo "Executing Gather XML on the call..."
cat <<EOF | curl -s "https://pubsub-us.cpaas.avayacloud.com/$ZANG_ACCOUNT_SID/call.xml/$call_sid" -H "Content-Type: application/xml" -d @-
<Response>
<Gather action="https://pubsub-us.cpaas.avayacloud.com/$ZANG_ACCOUNT_SID/calls/events/NodeId-11/$call_sid.xml?event-type=gather-action&callId=callID&routeId=routeId&mediaRequestID=requestId" timeout="10" finishOnKey="#" numDigits="2">
<Say loop="2" voice="woman">hello hello I am here</Say>
</Gather>
<Say>No digits detected</Say>
<Hangup />
</Response>
EOF
echo "================"
echo "Waiting for digits to be pressed..."
req=`curl -s "https://pubsub-us.cpaas.avayacloud.com/$ZANG_ACCOUNT_SID/calls/events/NodeId-11/$call_sid.xml?session=$session&timeout=30s"`
digits=`echo "$req" | grep -oh "\"Digits\":\"\w*" | cut -d '"' -f 4`
echo "Got Digits: $digits"
echo "================"
echo "Executing Thank You XML on the call..."
cat <<EOF | curl -s "https://pubsub-us.cpaas.avayacloud.com/$ZANG_ACCOUNT_SID/calls/events/NodeId-11/$call_sid.xml/$call_sid" -H "Content-Type: application/xml" -d @-
<Response>
<Say>You pressed $digits. Good bye.</Say>
<Hangup />
</Response>
EOF
echo "================"