Udostępnij za pośrednictwem


Jak używać usługi Notification Hubs z poziomu języka Python

Dostęp do wszystkich funkcji usługi Notification Hubs można uzyskać z poziomu zaplecza Java/PHP/Python/Ruby przy użyciu interfejsu REST centrum powiadomień zgodnie z opisem w artykule Interfejsy REST usługi Notification Hubs w witrynie MSDN.

Uwaga

Jest to przykładowa implementacja referencyjna implementacji wysyłania powiadomień w języku Python i nie jest oficjalnie obsługiwanym zestawem SDK języka Python usługi Notifications Hub. Przykład został utworzony przy użyciu języka Python 3.4.

W tym artykule wyjaśniono, jak:

  • Tworzenie klienta REST dla funkcji usługi Notification Hubs w języku Python.
  • Wysyłanie powiadomień przy użyciu interfejsu języka Python do interfejsów API REST usługi Notification Hub.
  • Pobierz zrzut żądania/odpowiedzi REST HTTP na potrzeby debugowania/edukacji.

Możesz skorzystać z samouczka Wprowadzenie dla wybranej platformy mobilnej, implementowania części zaplecza w języku Python.

Uwaga

Zakres przykładu jest ograniczony tylko do wysyłania powiadomień i nie wykonuje żadnego zarządzania rejestracją.

Interfejs klienta

Główny interfejs klienta może zapewnić te same metody, które są dostępne w zestawie SDK usługi Notification Hubs platformy .NET. Ten interfejs umożliwia bezpośrednie tłumaczenie wszystkich samouczków i przykładów dostępnych obecnie na tej stronie oraz współautorów przez społeczność w Internecie.

Cały kod dostępny w przykładzie otoki REST języka Python można znaleźć.

Aby na przykład utworzyć klienta:

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

Aby wysłać wyskakujące powiadomienie systemu Windows:

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

Implementacja

Jeśli jeszcze tego nie zrobiono, postępuj zgodnie z samouczkiem Wprowadzenie do ostatniej sekcji, w której musisz zaimplementować zaplecze.

Wszystkie szczegóły implementacji pełnej otoki REST można znaleźć w witrynie MSDN. W tej sekcji opisano implementację języka Python głównych kroków wymaganych do uzyskania dostępu do punktów końcowych REST usługi Notification Hubs i wysyłania powiadomień

  1. Analizowanie parametrów połączenia
  2. Generowanie tokenu autoryzacji
  3. Wysyłanie powiadomienia przy użyciu interfejsu API REST protokołu HTTP

Analizowanie parametrów połączenia

Oto klasa główna implementujący klienta, którego konstruktor analizuje parametry połączenia:

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

Tworzenie tokenu zabezpieczającego

Szczegóły tworzenia tokenu zabezpieczającego są dostępne tutaj. Dodaj następujące metody do klasy, NotificationHub aby utworzyć token na podstawie identyfikatora URI bieżącego żądania i poświadczeń wyodrębnionych z parametrów połączenia.

@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

Wysyłanie powiadomienia przy użyciu interfejsu API REST protokołu HTTP

Uwaga

Usługa powiadomień wypychanych firmy Microsoft (MPNS) została przestarzała i nie jest już obsługiwana.

Najpierw należy użyć definiowania klasy reprezentującej powiadomienie.

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

Ta klasa jest kontenerem dla natywnej treści powiadomień lub zestawu właściwości powiadomienia szablonu, zestawu nagłówków, który zawiera format (natywna platforma lub szablon) i właściwości specyficzne dla platformy (takie jak właściwość wygasania firmy Apple i nagłówki WNS).

Zapoznaj się z dokumentacją interfejsów API REST usługi Notification Hubs i formatami określonych platform powiadomień, aby zapoznać się ze wszystkimi dostępnymi opcjami.

Teraz przy użyciu tej klasy napisz metody wysyłania powiadomień w NotificationHub klasie .

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)

Te metody wysyłają żądanie HTTP POST do punktu końcowego /messages centrum powiadomień z prawidłową treścią i nagłówkami w celu wysłania powiadomienia.

Używanie właściwości debugowania do włączania szczegółowego rejestrowania

Włączenie właściwości debugowania podczas inicjowania centrum powiadomień zapisuje szczegółowe informacje rejestrowania dotyczące żądania HTTP i zrzutu odpowiedzi, a także szczegółowy wynik wysyłania komunikatów powiadomień. Właściwość TestSend usługi Notification Hubs zwraca szczegółowe informacje o wyniku wysyłania powiadomień. Aby go użyć — zainicjuj przy użyciu następującego kodu:

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

Adres URL żądania wysyłania żądania w usłudze Notification Hub jest dołączany z ciągiem zapytania "test" w wyniku.

Ukończ samouczek

Teraz możesz ukończyć samouczek Wprowadzenie, wysyłając powiadomienie z zaplecza języka Python.

Zainicjuj klienta usługi Notification Hubs (zastąp parametry połączenia i nazwę centrum zgodnie z instrukcją w samouczku Wprowadzenie):

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

Następnie dodaj kod wysyłania w zależności od docelowej platformy mobilnej. Ten przykład dodaje również metody wyższego poziomu, aby umożliwić wysyłanie powiadomień na podstawie platformy, na przykład send_windows_notification dla okien; send_apple_notification (dla apple) itp.

Sklep Windows i Windows Phone 8.1 (inne niż 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 i 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)

Uruchomienie kodu w języku Python powinno spowodować wyświetlenie powiadomienia na urządzeniu docelowym.

Przykłady

Włączanie debug właściwości

Po włączeniu flagi debugowania podczas inicjowania usługi NotificationHub zobaczysz szczegółowe żądanie HTTP i zrzut odpowiedzi, a także powiadomienieOutcome, jak pokazano poniżej, gdzie można zrozumieć, jakie nagłówki HTTP są przekazywane w żądaniu i jakie odpowiedzi HTTP zostały odebrane z centrum powiadomień:

Zrzut ekranu przedstawiający konsolę ze szczegółami żądania T T T P I zrzutu odpowiedzi oraz komunikatów wynik powiadomienia opisanych na czerwono.

Zobaczysz na przykład szczegółowy wynik usługi Notification Hub.

  • po pomyślnym wysłaniu komunikatu do usługi powiadomień wypychanych.
    <Outcome>The Notification was successfully sent to the Push Notification System</Outcome>
    
  • Jeśli nie znaleziono żadnych elementów docelowych dla żadnego powiadomienia wypychanego, prawdopodobnie zobaczysz następujące dane wyjściowe jako odpowiedź (co wskazuje, że nie znaleziono żadnych rejestracji w celu dostarczenia powiadomienia prawdopodobnie, ponieważ rejestracje miały niedopasowane tagi)
    '<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>'
    

Rozgłaszaj wyskakujące powiadomienie do systemu Windows

Zwróć uwagę na nagłówki wysyłane podczas wysyłania wyskakujących powiadomień wyskakujących emisji do klienta systemu Windows.

hub.send_windows_notification(wns_payload)

Zrzut ekranu przedstawiający konsolę ze szczegółami żądania T T P H T P oraz wartościami formatu powiadomień usługi Service Bus i X W N S Type opisanymi na czerwono.

Wysyłanie powiadomienia określającego tag (lub wyrażenie tagu)

Zwróć uwagę na nagłówek HTTP Tagów, który jest dodawany do żądania HTTP (w poniższym przykładzie powiadomienie jest wysyłane tylko do rejestracji z ładunkiem "sport")

hub.send_windows_notification(wns_payload, "sports")

Zrzut ekranu przedstawiający konsolę ze szczegółami żądania T T P H T P oraz formatem powiadomień usługi Service Bus, tagiem powiadomień usługi Service Bus i wartościami typu X W N S określonymi na czerwono.

Wysyłanie powiadomienia określającego wiele tagów

Zwróć uwagę, jak nagłówek HTTP tagów zmienia się po wysłaniu wielu tagów.

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

Zrzut ekranu konsoli ze szczegółami żądania T T P H T P oraz formatem powiadomień usługi Service Bus, wieloma tagami powiadomień usługi Service Bus i wartościami typu X W N S opisanymi na czerwono.

Powiadomienie z szablonem

Zwróć uwagę, że format nagłówka HTTP zmienia się i treść ładunku jest wysyłana w ramach treści żądania HTTP:

Strona klienta — zarejestrowany szablon:

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

Strona serwera — wysyłanie ładunku:

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

Zrzut ekranu przedstawiający konsolę ze szczegółami żądania T T P H T P oraz wartościami Typ zawartości i Format powiadomień usługi Service Bus opisanymi na czerwono.

Następne kroki

W tym artykule pokazano, jak utworzyć klienta REST języka Python dla usługi Notification Hubs. W tym miejscu można wykonać następujące czynności: