Cara menggunakan Notification Hubs dari Python

Anda dapat mengakses semua fitur Notification Hubs dari back-end Java/PHP/Python/Ruby menggunakan antarmuka Notification Hub REST seperti yang dijelaskan dalam artikel MSDN Notification Hubs REST API.

Catatan

Ini adalah implementasi referensi sampel untuk mengimplementasikan pengiriman pemberitahuan di Python dan bukan Notification Hub Python SDK yang didukung secara resmi. Sampel dibuat menggunakan Python 3.4.

Artikel ini menunjukkan cara:

  • Bangun klien REST untuk fitur Notification Hubs di Python.
  • Kirim pemberitahuan menggunakan antarmuka Python ke Notification Hub REST API.
  • Dapatkan dump permintaan/respons HTTP REST untuk tujuan debugging/pendidikan.

Anda dapat mengikuti tutorial Memulai untuk platform seluler pilihan Anda, menerapkan bagian back-end di Python.

Catatan

Cakupan sampel hanya terbatas untuk mengirim pemberitahuan dan tidak melakukan manajemen pendaftaran apa pun.

Antarmuka klien

Antarmuka klien utama dapat menyediakan metode yang sama yang tersedia di .NET Notification Hubs SDK. Antarmuka ini memungkinkan Anda untuk secara langsung menerjemahkan semua tutorial dan sampel yang saat ini tersedia di situs ini, dan dikontribusikan oleh komunitas di internet.

Anda dapat menemukan semua kode yang tersedia dalam sampel pembungkus Python REST.

Misalnya, untuk membuat klien:

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

Untuk mengirim pemberitahuan sembul Windows:

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

Implementasi

Jika Anda belum melakukannya, ikuti Tutorial memulai hingga bagian terakhir untuk cara mengimplementasikan backend.

Semua detail untuk mengimplementasikan pembungkus REST lengkap dapat ditemukan di MSDN. Bagian ini menjelaskan implementasi Python dari langkah-langkah utama yang diperlukan untuk mengakses titik akhir Notification Hubs REST dan mengirim pemberitahuan

  1. Uraikan string koneksi
  2. Buat token otorisasi
  3. Kirim pemberitahuan menggunakan HTTP REST API

Uraikan string koneksi

Berikut adalah kelas utama yang mengimplementasikan klien, yang konstruktornya mengurai string koneksi:

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

Buat peran keamanan

Detail pembuatan token keamanan tersedia di sini. Tambahkan metode berikut ke kelas NotificationHub untuk membuat token berdasarkan URI permintaan saat ini dan informasi masuk yang diekstrak dari string koneksi.

@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

Kirim pemberitahuan menggunakan HTTP REST API

Catatan

Microsoft Push Notification Service (MPNS) telah dihentikan dan tidak lagi didukung.

Pertama, mari kita mendefinisikan kelas yang mewakili pemberitahuan.

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

Kelas ini adalah kontainer untuk badan pemberitahuan asli, atau sekumpulan properti pada kasus pemberitahuan templat, dan satu set header, yang berisi format (platform atau templat asli) dan properti khusus platform (seperti properti kedaluwarsa Apple dan header WNS).

Lihat dokumentasi API REST Microsoft Azure Notification Hubs dan format platform notifikasi tertentu untuk semua opsi yang tersedia.

Berbekal kelas ini, tulis metode kirim pemberitahuan di dalam kelas NotificationHub.

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)

Metode ini mengirim permintaan HTTP POST ke titik akhir pesan hub notifikasi Anda, dengan isi dan header yang benar untuk mengirim pemberitahuan.

Menggunakan properti debug untuk mengaktifkan pencatatan terperinci

Mengaktifkan properti debug saat menginisialisasi Hub Pemberitahuan menuliskan informasi pembuatan log terperinci tentang permintaan HTTP dan crash dump respons serta hasil pengiriman pesan Pemberitahuan terperinci. Properti Notification Hubs TestSend mengembalikan informasi terperinci tentang hasil pengiriman pemberitahuan. Untuk menggunakannya - inisialisasi menggunakan kode berikut:

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

URL HTTP permintaan Kirim Notification Hub akan ditambahkan dengan string kueri "uji" sebagai hasilnya.

Selesaikan tutorial

Sekarang Anda dapat menyelesaikan tutorial Memulai dengan mengirim pemberitahuan dari backend Python.

Inisialisasi klien Azure Notification Hubs Anda (ganti string koneksi dan nama hub seperti yang diinstruksikan dalam Tutorial memulai):

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

Kemudian tambahkan kode kirim tergantung platform seluler target Anda. Sampel ini juga menambahkan metode tingkat yang lebih tinggi untuk memungkinkan pengiriman pemberitahuan berdasarkan platform, misalnya, send_windows_notification untuk Windows; send_apple_notification (untuk Apple), dll.

Windows Store dan Windows Phone 8.1 (non-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 dan 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)

Menjalankan kode Phyton Anda sekarang akan menghasilkan pemberitahuan yang muncul di perangkat target Anda.

Contoh

Mengaktifkan debug properti

Saat Anda mengaktifkan bendera debug saat menginisialisasi NotificationHub, Anda melihat permintaan HTTP terperinci dan dump respons serta NotificationOutcome seperti berikut ini di mana Anda dapat memahami header HTTP apa yang diteruskan dalam permintaan dan respons HTTP apa yang diterima dari Hub Pemberitahuan:

Cuplikan layar konsol dengan detail permintaan H T T P dan crash dump respons dan pesan Hasil Pemberitahuan yang ditampilkan dalam kotak merah.

Contoh hasil Hub Pemberitahuan terperinci yang Anda lihat.

  • ketika pesan berhasil dikirim ke Layanan Pemberitahuan Push.
    <Outcome>The Notification was successfully sent to the Push Notification System</Outcome>
    
  • Jika tidak ada target yang ditemukan untuk pemberitahuan push apa pun, maka Anda mungkin akan melihat output berikut sebagai respons (yang menunjukkan bahwa tidak ada pendaftaran yang ditemukan untuk mengirimkan pemberitahuan mungkin karena pendaftaran memiliki beberapa tag yang tidak cocok)
    '<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>'
    

Siarkan pemberitahuan toast ke Windows

Perhatikan header yang dikirim ketika Anda mengirim pemberitahuan sembul siaran ke klien Windows.

hub.send_windows_notification(wns_payload)

Cuplikan layar konsol dengan detail permintaan H T T P dan Format Pemberitahuan Bus Layanan dan nilai X W N S Type ditampilkan dalam kotak merah.

Kirim pemberitahuan yang menentukan tag (atau ekspresi tag)

Perhatikan header HTTP Tag yang ditambahkan ke permintaan HTTP (dalam contoh di bawah ini, pemberitahuan dikirim hanya ke pendaftaran dengan payload 'sports')

hub.send_windows_notification(wns_payload, "sports")

Cuplikan layar konsol dengan detail permintaan H T T P dan Format Pemberitahuan Bus Layanan, Tag Pemberitahuan Bus Layanan, dan nilai X W N S Type ditampilkan dalam kotak merah.

Kirim pemberitahuan yang menentukan beberapa tag

Perhatikan bagaimana header HTTP Tag berubah ketika beberapa tag dikirim.

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

Cuplikan layar konsol dengan detail permintaan H T T P dan Format Pemberitahuan Bus Layanan, beberapa Tag Pemberitahuan Bus Layanan, dan nilai X W N S Type ditampilkan dalam kotak merah.

Pemberitahuan bertemplat

Perhatikan bahwa header HTTP Format berubah dan isi payload dikirim sebagai bagian dari isi permintaan HTTP:

Sisi klien - templat terdaftar:

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

Sisi server - mengirim payload:

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

Cuplikan layar konsol dengan detail permintaan H T T P dan jenis Konten dan nilai Format Pemberitahuan Bus Layanan ditampilkan dalam kotak merah.

Langkah berikutnya

Artikel ini memperlihatkan cara membuat klien Python REST untuk Notification Hubs. Setelahnya, Anda bisa: