Dela via


Använda Notification Hubs från Python

Du kan komma åt alla Notification Hubs-funktioner från en Java/PHP/Python/Ruby-serverdel med hjälp av Notification Hub REST-gränssnittet enligt beskrivningen i MSDN-artikeln Notification Hubs REST API:er.

Anmärkning

Det här är en exempelreferensimplementering för implementering av meddelandet som skickas i Python och är inte den officiellt stödda Python-SDK:t för Notifications Hub. Exemplet skapades med Python 3.4.

Den här artikeln visar hur du gör följande:

  • Skapa en REST-klient för Notification Hubs-funktioner i Python.
  • Skicka meddelanden med Python-gränssnittet till REST-API:erna för Notification Hub.
  • Hämta en dump av HTTP REST-begäran/-svaret för felsökning/utbildningsändamål.

Du kan följa Kom igång-självstudien för valfri mobilplattform genom att implementera back-end-delen i Python.

Anmärkning

Omfånget för exemplet är bara begränsat till att skicka meddelanden och det utför ingen registreringshantering.

Klientgränssnitt

Huvudklientgränssnittet kan tillhandahålla samma metoder som är tillgängliga i .NET Notification Hubs SDK. Med det här gränssnittet kan du direkt översätta alla handledningar och exempel som för närvarande är tillgängliga på den här webbplatsen och bidragna av gemenskapen på Internet.

Du hittar all kod som är tillgänglig i Python REST-omslutningsexemplet.

Om du till exempel vill skapa en klient:

isDebug = True
hub = NotificationHub("myConnectionString", "myNotificationHubName", isDebug)

Så här skickar du ett toast-meddelande i Windows:

wns_payload = """<toast><visual><binding template=\"ToastText01\"><text id=\"1\">Hello world!</text></binding></visual></toast>"""
hub.send_windows_notification(wns_payload)

Genomförande

Om du inte redan har gjort det, följ Kom igång-självstudien fram till och med det sista avsnittet där du måste implementera serverdelen.

All information för att implementera en fullständig REST-omslutning finns på MSDN. Det här avsnittet beskriver Python-implementeringen av de viktigaste stegen som krävs för att få åtkomst till Notification Hubs REST-slutpunkter och skicka meddelanden

  1. Analysera anslutningssträngen
  2. Generera auktoriseringstoken
  3. Skicka ett meddelande med HTTP REST API

Analysera anslutningssträngen

Här är huvudklassen som implementerar klienten, vars konstruktor parsar anslutningssträngen:

class NotificationHub:
    API_VERSION = "?api-version=2013-10"
    DEBUG_SEND = "&test"

    def __init__(self, connection_string=None, hub_name=None, debug=0):
        self.HubName = hub_name
        self.Debug = debug

        # Parse connection string
        parts = connection_string.split(';')
        if len(parts) != 3:
            raise Exception("Invalid ConnectionString.")

        for part in parts:
            if part.startswith('Endpoint'):
                self.Endpoint = 'https' + part[11:].lower()
            if part.startswith('SharedAccessKeyName'):
                self.SasKeyName = part[20:]
            if part.startswith('SharedAccessKey'):
                self.SasKeyValue = part[16:]

Skapa säkerhetstoken

Information om hur du skapar säkerhetstoken finns här. Lägg till följande metoder i NotificationHub klassen för att skapa token baserat på URI:n för den aktuella begäran och de autentiseringsuppgifter som extraheras från anslutningssträngen.

@staticmethod
def get_expiry():
    # By default returns an expiration of 5 minutes (=300 seconds) from now
    return int(round(time.time() + 300))


@staticmethod
def encode_base64(data):
    return base64.b64encode(data)


def sign_string(self, to_sign):
    key = self.SasKeyValue.encode('utf-8')
    to_sign = to_sign.encode('utf-8')
    signed_hmac_sha256 = hmac.HMAC(key, to_sign, hashlib.sha256)
    digest = signed_hmac_sha256.digest()
    encoded_digest = self.encode_base64(digest)
    return encoded_digest


def generate_sas_token(self):
    target_uri = self.Endpoint + self.HubName
    my_uri = urllib.parse.quote(target_uri, '').lower()
    expiry = str(self.get_expiry())
    to_sign = my_uri + '\n' + expiry
    signature = urllib.parse.quote(self.sign_string(to_sign))
    auth_format = 'SharedAccessSignature sig={0}&se={1}&skn={2}&sr={3}'
    sas_token = auth_format.format(signature, expiry, self.SasKeyName, my_uri)
    return sas_token

Skicka ett meddelande med HTTP REST API

Anmärkning

Microsoft Push Notification Service (MPNS) har blivit inaktuell och stöds inte längre.

Börja med att definiera en klass som representerar ett meddelande.

class Notification:
    def __init__(self, notification_format=None, payload=None, debug=0):
        valid_formats = ['template', 'apple', 'gcm',
                         'windows', 'windowsphone', "adm", "baidu"]
        if not any(x in notification_format for x in valid_formats):
            raise Exception(
                "Invalid Notification format. " +
                "Must be one of the following - 'template', 'apple', 'gcm', 'windows', 'windowsphone', 'adm', 'baidu'")

        self.format = notification_format
        self.payload = payload

        # array with keynames for headers
        # Note: Some headers are mandatory: Windows: X-WNS-Type, WindowsPhone: X-NotificationType
        # Note: For Apple you can set Expiry with header: ServiceBusNotification-ApnsExpiry
        # in W3C DTF, YYYY-MM-DDThh:mmTZD (for example, 1997-07-16T19:20+01:00).
        self.headers = None

Den här klassen är en behållare för en inbyggd meddelandekropp eller en uppsättning egenskaper för en mallavisering, en uppsättning huvuddelar som innehåller format (nativ plattform eller mall) och plattformsspecifika egenskaper (till exempel Apple-förfalloegenskap och WNS-huvuden).

Se dokumentationen för Notification Hubs REST API:er och de specifika meddelandeplattformarnas format för alla tillgängliga alternativ.

Nu med den här klassen skriver du metoderna för att skicka meddelanden i NotificationHub klassen.

def make_http_request(self, url, payload, headers):
    parsed_url = urllib.parse.urlparse(url)
    connection = http.client.HTTPSConnection(
        parsed_url.hostname, parsed_url.port)

    if self.Debug > 0:
        connection.set_debuglevel(self.Debug)
        # adding this querystring parameter gets detailed information about the PNS send notification outcome
        url += self.DEBUG_SEND
        print("--- REQUEST ---")
        print("URI: " + url)
        print("Headers: " + json.dumps(headers, sort_keys=True,
                                       indent=4, separators=(' ', ': ')))
        print("--- END REQUEST ---\n")

    connection.request('POST', url, payload, headers)
    response = connection.getresponse()

    if self.Debug > 0:
        # print out detailed response information for debugging purpose
        print("\n\n--- RESPONSE ---")
        print(str(response.status) + " " + response.reason)
        print(response.msg)
        print(response.read())
        print("--- END RESPONSE ---")

    elif response.status != 201:
        # Successful outcome of send message is HTTP 201 - Created
        raise Exception(
            "Error sending notification. Received HTTP code " + str(response.status) + " " + response.reason)

    connection.close()


def send_notification(self, notification, tag_or_tag_expression=None):
    url = self.Endpoint + self.HubName + '/messages' + self.API_VERSION

    json_platforms = ['template', 'apple', 'gcm', 'adm', 'baidu']

    if any(x in notification.format for x in json_platforms):
        content_type = "application/json"
        payload_to_send = json.dumps(notification.payload)
    else:
        content_type = "application/xml"
        payload_to_send = notification.payload

    headers = {
        'Content-type': content_type,
        'Authorization': self.generate_sas_token(),
        'ServiceBusNotification-Format': notification.format
    }

    if isinstance(tag_or_tag_expression, set):
        tag_list = ' || '.join(tag_or_tag_expression)
    else:
        tag_list = tag_or_tag_expression

    # add the tags/tag expressions to the headers collection
    if tag_list != "":
        headers.update({'ServiceBusNotification-Tags': tag_list})

    # add any custom headers to the headers collection that the user may have added
    if notification.headers is not None:
        headers.update(notification.headers)

    self.make_http_request(url, payload_to_send, headers)


def send_apple_notification(self, payload, tags=""):
    nh = Notification("apple", payload)
    self.send_notification(nh, tags)


def send_google_notification(self, payload, tags=""):
    nh = Notification("gcm", payload)
    self.send_notification(nh, tags)


def send_adm_notification(self, payload, tags=""):
    nh = Notification("adm", payload)
    self.send_notification(nh, tags)


def send_baidu_notification(self, payload, tags=""):
    nh = Notification("baidu", payload)
    self.send_notification(nh, tags)


def send_mpns_notification(self, payload, tags=""):
    nh = Notification("windowsphone", payload)

    if "<wp:Toast>" in payload:
        nh.headers = {'X-WindowsPhone-Target': 'toast',
                      'X-NotificationClass': '2'}
    elif "<wp:Tile>" in payload:
        nh.headers = {'X-WindowsPhone-Target': 'tile',
                      'X-NotificationClass': '1'}

    self.send_notification(nh, tags)


def send_windows_notification(self, payload, tags=""):
    nh = Notification("windows", payload)

    if "<toast>" in payload:
        nh.headers = {'X-WNS-Type': 'wns/toast'}
    elif "<tile>" in payload:
        nh.headers = {'X-WNS-Type': 'wns/tile'}
    elif "<badge>" in payload:
        nh.headers = {'X-WNS-Type': 'wns/badge'}

    self.send_notification(nh, tags)


def send_template_notification(self, properties, tags=""):
    nh = Notification("template", properties)
    self.send_notification(nh, tags)

Dessa metoder skickar en HTTP POST-begäran till slutpunkten /messages i meddelandehubben med rätt brödtext och rubriker för att skicka meddelandet.

Använda felsökningsegenskap för att aktivera detaljerad loggning

När du aktiverar felsökningsinställningen vid initiering av Notification Hub skrivs detaljerad logginformation om HTTP-förfrågan och -svars-dump samt detaljerade resultat av meddelandesändningen. Egenskapen Notification Hubs TestSend returnerar detaljerad information om meddelandets sändningsresultat. Så här använder du det – initiera med hjälp av följande kod:

hub = NotificationHub("myConnectionString", "myNotificationHubName", isDebug)

HTTP-URL:en för meddelandehubbens skicka begäran läggs till med en "test"-frågesträng som ett resultat.

Slutför handledningen

Nu kan du slutföra handledningen Komma igång genom att skicka meddelandet från en Python-backend.

Initiera Notification Hubs-klienten (ersätt anslutningssträngen och hubbens namn enligt instruktionerna i självstudiekursen Komma igång):

hub = NotificationHub("myConnectionString", "myNotificationHubName")

Lägg sedan till sändningskoden beroende på din mobila målplattform. Det här exemplet lägger också till metoder på högre nivå för att aktivera sändning av meddelanden baserat på plattformen, till exempel send_windows_notification för windows. send_apple_notification (för äpple) osv.

Windows Store och Windows Phone 8.1 (icke-Silverlight)

wns_payload = """<toast><visual><binding template=\"ToastText01\"><text id=\"1\">Test</text></binding></visual></toast>"""
hub.send_windows_notification(wns_payload)

Windows Phone 8.0 och 8.1 Silverlight

hub.send_mpns_notification(toast)

Ios

alert_payload = {
    'data':
        {
            'msg': 'Hello!'
        }
}
hub.send_apple_notification(alert_payload)

Android

gcm_payload = {
    'data':
        {
            'msg': 'Hello!'
        }
}
hub.send_google_notification(gcm_payload)

Kindle Fire

adm_payload = {
    'data':
        {
            'msg': 'Hello!'
        }
}
hub.send_adm_notification(adm_payload)

Baidu

baidu_payload = {
    'data':
        {
            'msg': 'Hello!'
        }
}
hub.send_baidu_notification(baidu_payload)

När du kör Python-koden bör ett meddelande visas på målenheten.

Exempel

Aktivera egenskapen debug

När du aktiverar felsökningsflaggan när du initierar NotificationHub ser du detaljerad HTTP-begärande- och svarsdump samt NotificationOutcome som följande där du kan förstå vilka HTTP-huvuden som skickas i begäran och vilket HTTP-svar som togs emot från Notification Hub:

Skärmbild av en konsol med information om HTTP-begäran och svarsdump och meddelanden om notifikationsresultat markerade i rött.

Du ser till exempel ett detaljerat Notification Hub-resultat.

  • när meddelandet har skickats till push-meddelandetjänsten.
    <Outcome>The Notification was successfully sent to the Push Notification System</Outcome>
    
  • Om inga mål hittades för push-meddelanden kommer du förmodligen att se följande utdata som svar (vilket indikerar att det inte fanns några registreringar för att leverera meddelandet förmodligen eftersom registreringarna hade några felmatchade taggar)
    '<NotificationOutcome xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" xmlns:i="https://www.w3.org/2001/XMLSchema-instance"><Success>0</Success><Failure>0</Failure><Results i:nil="true"/></NotificationOutcome>'
    

Sänd toastmeddelande till Windows

Observera rubrikerna som skickas ut när du skickar en sändande toast-notifikation till Windows-klienter.

hub.send_windows_notification(wns_payload)

Skärmbild av en konsol med information om H T T P-begäran och Service Bus Notification Format och X W N S Type-värden som beskrivs i rött.

Skicka meddelande som anger en tagg (eller tagguttryck)

Observera HTTP-rubriken Taggar som läggs till i HTTP-begäran (i exemplet nedan skickas meddelandet endast till registreringar med nyttolasten "sport")

hub.send_windows_notification(wns_payload, "sports")

Skärmbild av en konsol med information om H T T P-begäran och Service Bus-meddelandeformatet, en Service Bus-meddelandetagg och X W N S-typvärden som beskrivs i rött.

Skicka meddelande som anger flera taggar

Observera hur Tags HTTP-rubriken ändras när flera taggar skickas.

tags = {'sports', 'politics'}
hub.send_windows_notification(wns_payload, tags)

Skärmbild av en konsol med information om H T T P-begäran och Service Bus-meddelandeformatet, flera Service Bus-meddelandetaggar och X W N S-typvärden som beskrivs i rött.

Mallmeddelande

Observera att FORMAT HTTP-huvudet ändras och nyttolasttexten skickas som en del av HTTP-begärandetexten:

Klientsidan – registrerad mall:

var template = @"<toast><visual><binding template=""ToastText01""><text id=""1"">$(greeting_en)</text></binding></visual></toast>";

Serversidan – skickar nyttolasten:

template_payload = {'greeting_en': 'Hello', 'greeting_fr': 'Salut'}
hub.send_template_notification(template_payload)

Skärmbild av en konsol med information om H T T P-begäran och värden för innehållstyp och Service Bus-meddelandeformat som beskrivs i rött.

Nästa steg

Den här artikeln visade hur du skapar en Python REST-klient för Notification Hubs. Härifrån kan du: