Delen via


Notification Hubs gebruiken vanuit Python

U hebt toegang tot alle Notification Hubs-functies vanuit een Back-end van Java/PHP/Python/Ruby met behulp van de Rest-interface van Notification Hub, zoals beschreven in het MSDN-artikel Notification Hubs REST API's.

Notitie

Dit is een voorbeeld van een referentie-implementatie voor het implementeren van de meldingen in Python en is niet de officieel ondersteunde Notifications Hub Python SDK. Het voorbeeld is gemaakt met behulp van Python 3.4.

In dit artikel leest u informatie over:

  • Bouw een REST-client voor Notification Hubs-functies in Python.
  • Verzend meldingen met behulp van de Python-interface naar de REST API's van Notification Hub.
  • Haal een dump op van de HTTP REST-aanvraag/-reactie voor foutopsporing/educatieve doeleinden.

U kunt de zelfstudie Aan de slag volgen voor het mobiele platform van uw keuze, waarbij u het back-endgedeelte in Python implementeert.

Notitie

Het bereik van het voorbeeld is alleen beperkt tot het verzenden van meldingen en er wordt geen registratiebeheer uitgevoerd.

Clientinterface

De hoofdclientinterface kan dezelfde methoden bieden die beschikbaar zijn in de .NET Notification Hubs SDK. Met deze interface kunt u alle zelfstudies en voorbeelden die momenteel beschikbaar zijn op deze site en die zijn bijgedragen door de community op internet, rechtstreeks vertalen.

U vindt alle beschikbare code in het Python REST-wrapper-voorbeeld.

Als u bijvoorbeeld een client wilt maken, gaat u als volgt te werk:

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

Een pop-upmelding voor Windows verzenden:

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

Implementatie

Als u dat nog niet hebt gedaan, volgt u de zelfstudie Aan de slag tot de laatste sectie waarin u de back-end moet implementeren.

Alle details voor het implementeren van een volledige REST-wrapper vindt u op MSDN. In deze sectie wordt de Python-implementatie beschreven van de belangrijkste stappen die nodig zijn voor toegang tot Notification Hubs REST-eindpunten en het verzenden van meldingen

  1. De verbindingsreeks parseren
  2. Het autorisatietoken genereren
  3. Een melding verzenden met behulp van HTTP REST API

De verbindingsreeks parseren

Dit is de belangrijkste klasse die de client implementeert, waarvan de constructor de connection string parseert:

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:]

Beveiligingstoken maken

De details van het maken van het beveiligingstoken vindt u hier. Voeg de volgende methoden toe aan de NotificationHub klasse om het token te maken op basis van de URI van de huidige aanvraag en de referenties die zijn geëxtraheerd uit de connection string.

@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

Een melding verzenden met behulp van HTTP REST API

Notitie

Microsoft Push Notification Service (MPNS) is afgeschaft en wordt niet meer ondersteund.

Laten we eerst een klasse definiëren die een melding vertegenwoordigt.

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

Deze klasse is een container voor een systeemeigen meldingshoofdtekst of een set eigenschappen van een sjabloonmelding, een set headers, die de indeling (systeemeigen platform of sjabloon) en platformspecifieke eigenschappen (zoals apple vervaldatum-eigenschap en WNS-headers) bevat.

Raadpleeg de documentatie voor Notification Hubs REST API's en de indelingen van de specifieke meldingsplatforms voor alle beschikbare opties.

Schrijf nu met deze klasse de methoden voor het verzenden van meldingen in de NotificationHub klasse.

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)

Deze methoden verzenden een HTTP POST-aanvraag naar het /messages-eindpunt van uw Notification Hub, met de juiste hoofdtekst en headers om de melding te verzenden.

De eigenschap foutopsporing gebruiken om gedetailleerde logboekregistratie in te schakelen

Als u de foutopsporingseigenschap inschakelt tijdens het initialiseren van de Notification Hub, worden gedetailleerde logboekgegevens over de HTTP-aanvraag- en antwoorddump en gedetailleerde resultaten van het verzenden van meldingsberichten weggeschreven. De eigenschap TestSend van Notification Hubs retourneert gedetailleerde informatie over het resultaat van het verzenden van meldingen. Als u deze wilt gebruiken, initialiseert u met behulp van de volgende code:

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

De HTTP-URL voor De aanvraag verzenden van Notification Hub wordt als resultaat toegevoegd met een 'test'-queryreeks.

De zelfstudie voltooien

U kunt nu de zelfstudie Aan de slag voltooien door de melding te verzenden vanuit een Python-back-end.

Initialiseer uw Notification Hubs-client (vervang de connection string en de hubnaam zoals aangegeven in de zelfstudie Aan de slag):

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

Voeg vervolgens de verzendcode toe, afhankelijk van uw mobiele doelplatform. In dit voorbeeld worden ook methoden op een hoger niveau toegevoegd om het verzenden van meldingen op basis van het platform mogelijk te maken, bijvoorbeeld send_windows_notification voor Windows; send_apple_notification (voor appel) etc.

Windows Store en Windows Phone 8.1 (niet-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 en 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)

Als u uw Python-code uitvoert, wordt er een melding weergegeven op uw doelapparaat.

Voorbeelden

De eigenschap inschakelen debug

Wanneer u de foutopsporingsvlag inschakelt tijdens het initialiseren van NotificationHub, ziet u gedetailleerde HTTP-aanvraag- en antwoorddump, evenals NotificationOutcome, zoals hieronder, waarin u kunt begrijpen welke HTTP-headers worden doorgegeven in de aanvraag en welk HTTP-antwoord is ontvangen van de Notification Hub:

Schermopname van een console met details van de H T T P-aanvraag- en antwoorddumpberichten en meldingsresultaten in rood gemarkeerd.

U ziet bijvoorbeeld een gedetailleerd resultaat van Notification Hub.

  • wanneer het bericht is verzonden naar de Push Notification Service.
    <Outcome>The Notification was successfully sent to the Push Notification System</Outcome>
    
  • Als er geen doelen zijn gevonden voor een pushmelding, ziet u waarschijnlijk de volgende uitvoer als antwoord (wat aangeeft dat er geen registraties zijn gevonden om de melding te leveren, waarschijnlijk omdat de registraties een aantal niet-overeenkomende tags hadden)
    '<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>'
    

Pop-upmelding uitzenden naar Windows

Let op de headers die worden verzonden wanneer u een pop-upmelding voor uitzending naar de Windows-client verzendt.

hub.send_windows_notification(wns_payload)

Schermopname van een console met details van de H T T P-aanvraag en de waarden voor Service Bus Notification Format en X W N S Type rood gemarkeerd.

Melding verzenden waarin een tag (of tagexpressie) wordt opgegeven

Let op de HTTP-header Tags, die wordt toegevoegd aan de HTTP-aanvraag (in het onderstaande voorbeeld wordt de melding alleen verzonden naar registraties met 'sports'-nettolading)

hub.send_windows_notification(wns_payload, "sports")

Schermopname van een console met details van de H T T P-aanvraag en de Service Bus-meldingsindeling, een Service Bus-meldingstag en X W N S Type-waarden die rood zijn gemarkeerd.

Melding verzenden waarin meerdere tags worden opgegeven

U ziet hoe de HTTP-header van tags verandert wanneer meerdere tags worden verzonden.

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

Schermopname van een console met details van de H T T P-aanvraag en de Service Bus-meldingsindeling, meerdere Service Bus-meldingstags en X W N S Type-waarden die rood zijn gemarkeerd.

Sjabloonmelding

U ziet dat de HTTP-header format wordt gewijzigd en dat de nettoladingtekst wordt verzonden als onderdeel van de HTTP-aanvraagbody:

Clientzijde - geregistreerde sjabloon:

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

Serverzijde: de nettolading verzenden:

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

Schermopname van een console met details van de H T T P-aanvraag en de waarden voor Inhoudstype en Service Bus Notification Format rood gemarkeerd.

Volgende stappen

In dit artikel is beschreven hoe u een Python REST-client maakt voor Notification Hubs. Hier kunt u het volgende doen: