Getting Started

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

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_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

  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 open channels to include 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 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 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.

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

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.

 Important

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

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 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 the timezone 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.
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
            }
        ]
    }
}