Getting Started

Set up your webhook server and Airship before sending your first push notification.

Open Channels support notifications to any medium that can accept a JSON payload, through either the Airship API or web dashboard.

Unlike natively supported channels such as iOS, Android and web, Open Channels are not backed by an 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 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.

API Resources

These are the steps to setting up your open channels integration:

  1. Set up your webhook server.
  2. Configure your new webhook in the Airship dashboard.
  3. Register a channel to your Open Platform.
  4. Send a push.

Set Up Your Webhook Server

 Important

You need to do this first because the Open Channel configuration in the next step requires your webhook URL.

The webhook server must:

  1. Accept HTTPS connections. Accepted Cipher Suites:

    • TLS_CHACHA20_POLY1305_SHA256
    • TLS_AES_256_GCM_SHA384
    • TLS_AES_128_GCM_SHA256
    • TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
    • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  2. 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"}.
  3. When receiving an authorized POST request to <webhook_root>/push:

    • Return a 200 response code.

The webhook server should:

  1. Expect to process payloads in the format of the samples below.
  2. 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 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 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.
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/"
            }
         }
      }
   ]
}

Signature Hash and Security

Rather than basic authentication, you can configure a signature that your webhook server can use to verify that requests come from Airship. To enable this signature, select Signature Hash authorization and set a secret_key when configuring your webhook or open channel.

When you enable and set a secret_key, outgoing requests include a hash-based 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. We recommend that you use a 5-minute threshold to account for time drift, though Airship uses NTP and we recommend that your webhook server does the same. To prevent timing attacks, you should employ a constant time-compare function when checking signatures.

Request headers with secret key
POST /yourWebhookServer/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

Airship Setup

Begin by configuring your new webhook in the dashboard.

  1. Go to Settings » Channels » Open Channels.
  2. Click Configure new Open Channel and complete the form. All fields are required.
    • Display Name: Enter a user-friendly name for the channel, e.g., “Alexa,” “Smart Toaster Dev.” This is the name of the channel as it will appear in the Airship dashboard.
    • Name: Enter a name indicative of the platform, e.g., slack or sms. This is the canonical name that will be used for programmatic use through our API. 20-character maximum. A-Z, a-z, 0-9, _, and - only.
    • Webhook URL: Enter the URL + path to which we will deliver message payloads, e.g., https://acme-toaster.appspot.com/api/channels/production.
    • Authentication: Select the authentication mechanism for your webhook server.
      • None
      • Basic: Enter the username and password for the webhook server.
      • Signature Hash: Enter a secret key for use as a part of the X-UA-SIGNATURE header. See Signature Hash and Security for more information.
  3. Click Save. After saving, a Validation Code field appears, containing a 36-character UUID. This code must be returned by the webhook server at <webhook_root>/validate. See: Set Up Your Webhook Server.
  4. Check the Enabled box to enable the open channel for use, then click Update.
     Important

    If the channel is not enabled, 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.

 Note

We do not validate the endpoint until you enable and save the configuration. We will revalidate it each time you update the configuration, as long as it remains enabled.

Register a Channel to Your Open Platform

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 Airship system with users on open platforms.

To register a channel, send a request to the Open Channel Registration API. The request body must contain 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 the timezone tag group tag with the specified value.
"locale_country"
Optional, string. The two-letter country locale short code. Will set the ua_locale_country tag group to the specified value.
"locale_language"
Optional, string. The two-letter language locale short code. 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.
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"
         }
      }
   }
}

Push To Your New Channel

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".

Example Request
{
   "notification": {
      "alert": "Pop!"
   },
   "audience": {
      "open_channel": "32c99a88-0df1-4eed-9ac3-abc8ee5314ed"
   },
   "device_types": [
      "open::toaster"
   ]
}

Associate a Named User

You can also associate your channel with a named user using the Association endpoint, and then use that for targeting.

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"
}

Fan out

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.

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"
   ]
}

View Send Counts

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.

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 16:41:59",
    "push_type": "SEGMENTS_PUSH",
    "direct_responses": 0,
    "sends": 0,
    "open_channels_sends": {
        "platforms": [
            {
                "id": "sms",
                "sends": 1
            },
            {
                "id": "toaster",
                "sends": 1
            }
        ]
    }
}