Introduction
Open Channels support notifications to any medium that can accept a JSON payload, through either the Urban Airship API or dashboard UI.
Unlike natively supported channels such as iOS, Android and web, Open Channels are not backed by an Urban Airship SDK. In the absence of an SDK, it's up to you, the developer, to A) register end users with our Open Channels API and B) determine how to parse and display the notification payloads in the available interface.
Leverage the features such as segmentation, scheduling,
and local time delivery, while sending notifications to any messaging channels
you choose. You can send to natively supported channels, e.g., Android or iOS,
and open messaging channels in combination or in isolation, using our familiar
device_types
selector and platform-specific payloads.
Open Channels is an extension of the Channels API. See the Intro to Channels for more information.
Use Cases
The simplest use case for a notification is the one we are all familiar with: displaying
the text of an alert. But there are many other uses for a notification payload, which,
depending on the target interface or OS, may be handled in different ways. For example,
our SDKs for iOS and Android support the interactive features of those operating systems
through our API. Our API also supports an extra
field, which lets you to pass any
key/value pair to handle how you see fit, e.g., update a config file or trigger a different
process.
An open channel can be any non-native platform or interface where you'd like to reach users, or for that matter any client capable of receiving a payload over the Internet. The end message doesn't need to be human-readable alert text as you might see on an iPhone. Alerts are usually intended for people, but in the case of a machine, you could tell it to update its firmware, increment a counter in a database, or perform some other action.
Open channel example use cases
- Automated Slack Message using Slack incoming webhooks
- Chatbot notifications
- Firmware updates for IOT devices
- Integrate with third-party messaging APIs, e.g, Twitter
Integration Points
There are three integration points required to set up a new Open Channel:
- Webhook Server
Accepts the Urban Airship Open Channels payload, translates and routes your request. - Channel Registration API
Because Open Channels aren't supported by a client SDK, you must register new open channels in the Urban Airship system directly. - Push API
Deliver message payloads using our API, specifying open channels in your request.
API Resources
Open Delivery Payload
Webhook POST Request Body
Here is an example request body with two objects, each containing all possible keys:
POST /hooks/ua/example_hook/push HTTP/1.1
Content-encoding: gzip
Data-Attribute: values
Content-Type: application/vnd.urbanairship+json; version=3;
{
"values": [
{
"send_id": "ff76bb85-74bc-4511-a3bf-11b6117784db",
"app_key": "ZGIwZTY3YjEtZTRiMi00ZG",
"target": {
"address": "221B Baker Street",
"channel_id": "a61448e1-be63-43ee-84eb-19446ba743f0",
"identifiers": {
"cid": "1234567",
"com.example.test_token": "a61448e1-be63-43ee-84eb-19446ba743f0"
}
},
"payload": {
"alert": "Giant StayPuft Marshmallow Man On a Rampage",
"title": "Breaking News!",
"extra": {
"url": "https://www.example.com/"
}
}
},
{
"send_id": "647e799e-3b15-46f0-b4f1-12360d51ce4a",
"app_key": "ZGIwZTY3YjEtZTRiMi00ZG",
"target": {
"address": "1600 Pennsylvania Avenue",
"channel_id": "5b7e9f63-df28-43f4-8182-b762c628c4c4",
"identifiers": {
"cid": "7654321",
"com.example.test_token": "503640e8-88f7-4dee-9245-7479ac1a8501"
}
},
"payload": {
"alert": "Giant StayPuft Marshmallow Man On a Rampage",
"title": "Breaking News!",
"extra": {
"url": "https://www.example.com/"
}
}
}
]
}
Here is an example request body with one object, containing only the required keys:
POST /hooks/ua/example_hook/push HTTP/1.1
Content-encoding: gzip
Data-Attribute: values
Content-Type: application/vnd.urbanairship+json; version=3;
{
"values": [
{
"send_id": "ff76bb85-74bc-4511-a3bf-11b6117784db",
"app_key": "ZGIwZTY3YjEtZTRiMi00ZG",
"target": {
"address": "test@example.com",
"channel_id": "a61448e1-be63-43ee-84eb-19446ba743f0",
},
"payload": {
"alert":"Giant StayPuft Marshmallow Man On a Rampage",
}
}
]
}
The request body itself is a JSON object containing a single top level key, "values"
, pointing to an array of up to 1,000 JSON objects. Urban Airship will break up large pushes into groups of 1000.
Each object in the array is required to have the following keys:
"send_id"
—UUID version 4 string. Uniquely identifies the object."app_key"
—22 character string containing the characters: [-_A-Za-z0-9]."payload"
—push payload with all"open"
overrides for the delivery type applied."target"
—A target object containing theaddress
and a string->string map of alternative identifiers.
Target Object
{
"identifiers": {
"com.urbanairship.aaid": "94b0c28e-0f00-4601-af28-e70322f46a75",
"friend": "ship",
"ice": "cream",
"session_id": "5abe6b52-7dcf-4fec-b0a5-d24cb4deaafe",
"com.urbanairship.limited_ad_tracking_enabled": "false"
},
"channel_id": "1e215090-e692-4d89-ab7f-1f2ace2a229b",
"address": "+1 5558675309"
}
Information pertaining to the target related to a webhook payload is defined under the "target"
key in each response item.
Target objects are required to have both of following keys:
"channel_id"
—string, the channel identifier for the target."address"
— string, the customer-provided delivery address for the target.
Target objects may have the following keys:
"identifiers"
—A JSON object with identifiers specified by the app. Common uses are IDFA or the primary key in your CMS. The values of the keys and values in this object are up to you, however Urban Airship may make additional functionality available using keys prefixed with "com.urbanairship." so keys using that prefix should be avoided.
Payload Object
The payload to deliver to the target.
"alert"
—required, string. The primary message to deliver to the target."title"
—optional, string. The title of the payload. A good example use case would be an email header for an open email notification."extra"
—optional, a string-to-string map of additional values to deliver to the target. Can contain any additional information that users want to deliver to the target.
Getting Started
These are the steps to setting up your open channels integration:
- Set up your webhook server.
- Configure your new webhook in the Urban Airship dashboard.
- Register a channel to your Open Platform.
- Send a push.
Set Up Your Webhook Server
You need to do this first because the Open Channel configuration in the next step requires your webhook URL.
The webhook server must:
Accept HTTPS connections. Accepted Cipher Suites:
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
When receiving an authorized
GET
request to<webhook_root>/validate
:- Return a 200 response code.
- Return a
Content-Type
of"application/json"
. - Return a JSON body with the form:
{"confirmation_code":"559384cd-6284-4e3e-9e4e-7c260019a251"}
.
When receiving an authorized POST request to
<webhook_root>/push
:- Return a 200 response code.
- Return a 200 response code.
The webhook server should:
Sample Payload:
{
"values": [
{
"send_id": "ff76bb85-74bc-4511-a3bf-11b6117784db",
"app_key": "ZGIwZTY3YjEtZTRiMi00ZG",
"target": {
"address": "SOME_INTERNAL_ID",
"channel_id": "a61448e1-be63-43ee-84eb-19446ba743f0",
"identifiers": {
"cid": "1234567",
"com.example.token": "a61448e1-be63-43ee-84eb-19446ba743f0"
}
},
"payload": {
"alert": "Giant StayPuft Marshmallow Man On a Rampage",
"title": "Breaking News!",
"extra": {
"url": "https://www.example.com/"
}
}
},
{
"send_id": "647e799e-3b15-46f0-b4f1-12360d51ce4a",
"app_key": "ZGIwZTY3YjEtZTRiMi00ZG",
"target": {
"address": "SOME_OTHER_INTERNAL_ID",
"channel_id": "5b7e9f63-df28-43f4-8182-b762c628c4c4",
"identifiers": {
"cid": "7654321",
"com.example.token": "503640e8-88f7-4dee-9245-7479ac1a8501"
}
},
"payload": {
"alert": "Giant StayPuft Marshmallow Man On a Rampage",
"title": "Breaking News!",
"extra": {
"url": "https://www.example.com/"
}
}
}
]
}
- Expect to process payloads in the format of the samples to the right.
- Point to an array of Send Objects with the top level
"values"
key.
Send Object
"send_id"
- Required, UUID uniquely identifying the send. Can be used for de-duplication in the event of a retry, logging, or tracing.
"app_key"
- Required, the 22-character identifier of the Urban Airship project associated with the open channel.
"target"
required, a Target Object with the following attributes:
“address”
Required, string. The address of the open channel.“channel_id”
Required, the Urban Airship Channel ID of the Open Channel.“identifiers”
Optional, an Object with up to 100 string:string identifiers associated with the Open Channel.
"payload"
Required, a Payload Object with the following attributes:
“alert”
Required, string. The alert message for the notification.“title”
Optional, string. Optional title, useful for email subject lines or headers.“extra”
Optional, an object of user-supplied string:string key:value pairs associated with the push.
Signature Hash and Security
Request headers with secret key
POST /hooks/ua/sendgrid_hook/push HTTP/1.1
Content-Type: application/vnd.urbanairship+json; version=3;
Content-encoding: gzip
X-UA-TIMESTAMP: 1536947409
X-UA-SIGNATURE: 68688b9dbd5c381851d3cd51dba3093c6633ceef58e6fee6ad4757f857f59aea
Data-Attribute: values
Rather than basic authentication, you can configure open channels to include a signature that your webhook server can use to verify that requests come from Urban Airship.
To enable this signature, select Signature Hash authorization and set a secret_key
when configuring your open channel in the Urban Airship dashboard. See the
Configure Open Channels page for help
configuring an open channel and enabling Signature Hash authentication in the dashboard.
When you enable and set a secret_key
, outgoing requests include a hash-based
message authentication code, computed using the sha256 hash function in an X-
UA-SIGNATURE
header. You can use this same algorithm to verify the signature
on the receiving server.
X-UA-SIGNATURE
is composed of the secret_key
and a message
, both of
which must be UTF-8 encoded. The message
is a concatenation of the following
string values:
- The
X-UA-TIMESTAMP
header — the unix timestamp when the request was sent. - The
:
character. - The JSON request body.
To prevent replay attacks, you should validate the X-UA-TIMESTAMP
within a threshold of the current time. It is recommended that you use a 5-minute threshold to account for time drift, though Urban Airship uses NTP and it is recommended that your webhook servers do the same.
To prevent timing attacks, you should employ a constant time-compare function when checking signatures.
Urban Airship Setup
Begin by configuring your new webhook in the dashboard. Complete the steps in Configure Open Channels.
When you complete the steps, you will receive a validation code that must
be returned by the webhook server at <webhook_root>/validate
. See:
Set Up Your Webhook Server.
When completing the configuration steps above, be sure to check the "Check to enable this for API use" box for your new open platform. If it is not enabled for the platform, you will be able to register a new open channel with the corresponding platform type but you will not be able to send a push to that platform using our API.
Register a Channel to Your Open Platform
Sample Payload:
{
"channel": {
"type": "open",
"opt_in": true,
"address": "Number Four",
"tags": [
"toaster",
"caprica"
],
"timezone": "America/Los_Angeles",
"locale_country": "US",
"locale_language": "en",
"open": {
"open_platform_name": "cylon",
"identifiers": {
"model": "4"
}
}
}
}
Next, you’ll need to populate your audience in our system.
This registration step is handled automatically in our mobile and web SDKs, but you are responsible for populating the Urban Airship system with users on open platforms.
To register a channel, send request to the Open Channel Registration API> The request body must contain an the following keys:
"type"
- Required, string. Currently the only only valid value for
type
is"open"
. "opt_in"
- Required, boolean. A flag to determine if the owner of this device still wants to receive notifications. If false, no open channels payloads will be delivered to the webhook for this channel.
"address"
- Required, string. The primary identifier of a record. For example, in an SMS integration, it could be the end user's phone number. 128 character maximum.
"tags"
- Optional, array of strings. Can be used for audience segmentation.
"timezone"
- Optional, string. An IANA tzdata identifier for the timezone as a string, e.g.,
"America/Los Angeles"
. Will set thetimezone
tag group tag with the specified value. “locale_country”
- Optional, string. The two-letter country locale shortcode. Will set the
ua_locale_country
tag group to the specified value. “locale_language”
- Optional, string. Tthe two-letter language locale shortcode. Will set the
ua_locale_language
tag group to the specified value. "open"
Required, object. Open Platform Options Object. Contains the following keys:
"open_platform_name"
: Required, string. The name of the open platform to which you are registering this channel."identifiers"
- Optional map of string values. These will be delivered in open channels payloads, but cannot be used for segmentation. Maximum of 100 pairs of string values. This map should be exhaustive whenever this key is present. Values will not be unioned with existing identifiers; they will replace them.
Push To Your New Channel
Example Request:
{
"notification": {
"alert": "Pop!"
},
"audience": {
"open_channel": "32c99a88-0df1-4eed-9ac3-abc8ee5314ed"
},
"device_types": [
"open::toaster"
]
}
To push to your channel, simply push like you would to any other channel,
using the open_channel
identifier as your audience selector. See
Audience Selection
for more detail.
The key difference in an Open Channels API push is the namespacing of the device_types
identifier for
your configured platform. Prepend the new device_types
identifier with open::
, e.g., for
your new toaster's channel, use "open::toaster"
.
Associate a Named User
Associate Channel ID with Named User:
POST /api/named_users/associate HTTP/1.1
Authorization: Basic <application or master authorization string>
Accept: application/vnd.urbanairship+json; version=3;
Content-type: application/json
{
"channel_id": "5b7e9f63-df28-43f4-8182-b762c628c4c4",
"named_user_id": "igorstravinsky"
}
You can also associate your channel with a named user using the Association endpoint, and then use that for targeting.
Fan out
Fan out a message to all devices associated with the named user:
{
"notification": {
"alert": "Pop!"
},
"audience": {
"named_user": "igorstravinsky"
},
"device_types": [
"ios",
"android",
"open::toaster"
]
}
Now that you have registered your channel, and mapped a named user to it, you need only target the named
user and enumerate the configured device_types
on which you would like to reach your named user.
The named user mapping will fan out to all devices on supported platforms for the given named user.
View Send Counts
Example Push Response. Use the
push_id
in your request
{
"ok": true,
"operation_id": "6b5e94f5-9c85-486a-a76e-67d18b3eaf05",
"push_ids": [
"362b7e8d-af82-4a67-ac76-49e5ea2f7f59"
],
"message_ids": [],
"content_urls": []
}
Response API request, using
push_id
from previous example:
GET /api/reports/responses/362b7e8d-af82-4a67-ac76-49e5ea2f7f59 HTTP/1.1
Authorization: Basic <master authorization string>
Example response returns the
open_channels_sends
, broken out by open platform
{
"push_uuid": "362b7e8d-af82-4a67-ac76-49e5ea2f7f59",
"push_time": "2017-08-08 1659",
"push_type": "SEGMENTS_PUSH",
"direct_responses": 0,
"sends": 0,
"open_channels_sends": {
"platforms": [
{
"id": "sms",
"sends": 1
},
{
"id": "toaster",
"sends": 1
}
]
}
}
After you've sent a push notification to your open channel, use the Push Response Report endpoint to retrieve send counts broken out by open platform.