Gửi mobile push notifications và quản lý device tokens với ứng dụng serverless

by James Beswick | on 26 AUG 2021 | in Amazon Simple Notification Service (SNS), AWS Lambda, Serverless, Technical How-to | Permalink |  Share

Bài viết này được viết bởi Rafa Xu, Cloud Architect, Serverless and Joely Huang, Cloud Architect, Serverless.

Amazon Simple Notification Service (SNS) là dịch vụ gửi push notifications nhanh chóng, linh hoạt và hoàn toàn quản lý trên đám mây. SNS có thể gửi các push notifications trực tiếp đến ứng dụng trên các thiết bị di động như cảnh báo tin nhắn và cập nhật huy hiệu. SNS gửi các push notifications đến một mobile endpoint được tạo ra bằng cách cung cấp mobile token và ứng dụng nền tảng.

Khi xuất bản push notifications trên di động, một mã thông báo thiết bị được sử dụng để tạo ra một điểm cuối. Điều này xác định nơi mà push notifications được gửi đến (đích đến mục tiêu). Để gửi push notifications thành công, mã thông báo phải được cập nhật và điểm cuối phải được xác thực và kích hoạt.

Một thách thức phổ biến khi đẩy thông báo là giữ cho mã thông báo luôn được cập nhật. Token thông báo có thể tự động thay đổi do các lý do như cập nhật hệ điều hành di động (OS) và cập nhật cửa hàng ứng dụng.

Bài viết này cung cấp một giải pháp không cần máy chủ cho thách thức này. Nó cũng cung cấp một cách để xuất bản push notifications đến người dùng cuối cụ thể bằng cách duy trì một bản đồ giữa  users, endpoints và tokens.

Tổng quan

Để xuất bản push notifications trên di động bằng SNS, bạn cần tạo một điểm cuối SNS để sử dụng làm mục tiêu đích cho push notification. Để tạo endpoint, bạn cần cung cấp:

  1. Một mobile application token: Hệ điều hành di động (OS) cung cấp token cho ứng dụng. Đó là một định danh duy nhất cho cặp ứng dụng và thiết bị di động.
  2. Platform Application Amazon Resource Name (ARN): SNS cung cấp ARN này khi bạn tạo một đối tượng ứng dụng nền tảng. Đối tượng ứng dụng nền tảng yêu cầu một bộ thông tin xác thực hợp lệ được cấp bởi nền tảng di động, mà bạn cung cấp cho SNS.

Sau khi endpoint được tạo ra, bạn có thể lưu trữ và sử dụng lại nó. Điều này ngăn ứng dụng tạo ra các endpoint vô hạn, làm cạn kiệt giới hạn endpoint của SNS.

Để tái sử dụng các endpoint và push notification thành công, có một số thách thức:

  • Các Mobile application tokens có thể thay đổi do nhiều lý do khác nhau, chẳng hạn như cập nhật ứng dụng. Do đó, nhà xuất bản phải cập nhật endpoint nền tảng để đảm bảo rằng nó sử dụng một mã thông báo được cập nhật.
  • Mobile application tokens có thể trở nên không hợp lệ. Khi điều này xảy ra, các thông báo sẽ không được xuất bản và SNS sẽ vô hiệu hóa endpoint với token không hợp lệ. Để giải quyết vấn đề này, nhà xuất bản phải lấy lại token hợp lệ và kích hoạt lại điểm cuối nền tảng.
  • Các ứng dụng di động có thể có nhiều người dùng, mỗi người dùng có thể có nhiều thiết bị hoặc một thiết bị có thể có nhiều người dùng. Để gửi push notification đến một người dùng cụ thể, một bản đồ giữa người dùng, thiết bị và endpoint nền tảng cần được duy trì.
  • Mobile applications can have many users, each user could have multiple devices, or one 

Để biết thêm thông tin về các thực hành tốt cho việc quản lý mã thông báo di động, vui lòng tham khảo bài viết này.

Hãy theo dõi bài đăng trên blog để tìm hiểu cách triển khai một quy trình làm việc không cần máy chủ để quản lý và duy trì các điểm cuối hợp lệ và bản đồ người dùng.

Giải pháp tổng quan

Giải pháp sử dụng các dịch vụ AWS sau:

  • Amazon API Gateway: Cung cấp một endpoint URL đăng ký mã thông báo được sử dụng bởi ứng dụng di động. Một khi được gọi, nó kích hoạt một hàm AWS Lambda thông qua tích hợp Lambda.
  • Amazon SNS: Tạo và duy trì endpoint mục tiêu và quản lý các đối tượng ứng dụng nền tảng.
  • Amazon DynamoDB: Cơ sở dữ liệu Serverless để lưu trữ các điểm cuối, đồng thời duy trì một bản đồ giữa người dùng, điểm cuối và hệ điều hành di động.
  • AWS Lambda: Trích xuất endpoint từ DynamoDB, xác thực và tạo ra endpoint, và push notification bằng cách thực hiện các yêu cầu đến SNS.

Biểu đồ sau đây biểu diễn một luồng tương tác đơn giản giữa các dịch vụ AWS:

Để đăng ký token, ứng dụng di động gọi token endpoint URL được tạo ra bởi Amazon API Gateway. Việc đăng ký mã thông báo xảy ra mỗi khi một người dùng đăng nhập hoặc mở ứng dụng. Điều này đảm bảo rằng mã thông báo và các điểm cuối luôn hợp lệ trong quá trình sử dụng ứng dụng.

Ứng dụng di động truyền mã thông báo, người dùng và hệ điều hành di động dưới dạng tham số cho API Gateway, sau đó API Gateway chuyển tiếp yêu cầu đến hàm Lambda.

Hàm Lambda xác thực mã thông báo và điểm cuối cho người dùng bằng cách thực hiện các cuộc gọi API đến DynamoDB và SNS:

  1. Hàm Lambda kiểm tra DynamoDB để xem xem endpoint đã được tạo trước đó chưa.

1.Nếu điểm cuối không tồn tại, nó tạo một endpoint nền tảng qua SNS.

  1. Lấy các thuộc tính của endpoint từ SNS:

1. Kiểm tra thuộc tính “enabled” của endpoint và đặt thành “true” để kích hoạt điểm cuối nền tảng, nếu cần thiết.

2. Xác thực thuộc tính “token” của endpoint với token được cung cấp trong yêu cầu API Gateway. Nếu không khớp, cập nhật thuộc tính “token”.

3. Gửi một yêu cầu đến SNS để cập nhật các thuộc tính của endpoint.

   3. Nếu một điểm cuối mới được tạo ra, cập nhật DynamoDB với endpoint mới.

   4. Trả về một phản hồi thành công cho API Gateway.

Triển khai mẫu AWS Serverless Application Model (AWS SAM)

Trước khi triển khai mẫu AWS SAM, đầu tiên tạo một ứng dụng nền tảng trong SNS.

  1. Di chuyển đến SNS console. Chọn Push Notifications trong menu bên trái để tạo một ứng dụng nền tảng:
  1. Đây là quá trình tạo một ứng dụng nền tảng cho các ứng dụng iOS:
  1. Để cài đặt AWS SAM, truy cập trang cài đặt
  2. Để triển khai AWS SAM template, điều hướng đến thư mục chứa mẫu. Chạy các lệnh trong terminal:
git clone https://github.com/aws-samples/serverless-mobile-push-notification
cd serverless-mobile-push-notification
sam build
sam deploy –guided

Lambda function code snippets

Phần tiếp theo giải thích mã từ hàm Lambda cho quy trình làm việc.

Tạo một endpoint nền tảng

Nếu điểm cuối tồn tại, lưu trữ nó như một biến trong token. Nếu endpoint nền tảng không tồn tại trong cơ sở dữ liệu DynamoDB, tạo một  endpoint mới:

need_update_ddb = False
        response = table.get_item(Key={‘username’: username, ‘appos’: appos})
        if ‘Item’ not in response:
            # create endpoint
            response = snsClient.create_platform_endpoint(
                PlatformApplicationArn=SUPPORTED_PLATFORM[appos],
                Token=token,
            )
            devicePushEndpoint = response[‘EndpointArn’]
            need_update_ddb = True
        else:
            # update the endpoint
            devicePushEndpoint = response[‘Item’][‘endpoint’]

Kiểm tra và cập nhật các thuộc tính của endpoint

Kiểm tra rằng thuộc tính mã thông báo cho endpointv nền tảng khớp với token  nhận được từ ứng dụng di động thông qua yêu cầu. Điều này cũng kiểm tra thuộc tính “enabled” của điểm cuối và kích hoạt lại điểm cuối nếu cần thiết:

response = snsClient.get_endpoint_attributes(
                EndpointArn=devicePushEndpoint
            )
            endpointAttributes = response[‘Attributes’]

            previousToken = endpointAttributes[‘Token’]
            previousStatus = endpointAttributes[‘Enabled’]
            if previousStatus.lower() != ‘true’ or previousToken != token:
                snsClient.set_endpoint_attributes(
                    EndpointArn=devicePushEndpoint,
                    Attributes={
                        ‘Token’: token,
                        ‘Enabled’: ‘true’
                    }
                )

Cập nhật bảng DynamoDB với endpoint mới được tạo ra

Nếu một endpoint nền tảng mới được tạo ra, có nghĩa là không có mục nào trong bảng DynamoDB, tạo một mục mới trong bảng:

if need_update_ddb:
            table.update_item(
                Key={
                    ‘username’: username,
                    ‘appos’: appos
                },
                UpdateExpression=”set endpoint=:e”,
                ExpressionAttributeValues={
                    ‘:e’: devicePushEndpoint
                },
                ReturnValues=”UPDATED_NEW”
            )

Là thực hành tốt nhất, code sẽ dọn dẹp bảng, trong trường hợp có nhiều mục cho cùng một endpoint được ánh xạ với các người dùng khác nhau. Điều này có thể xảy ra khi ứng dụng di động được sử dụng bởi nhiều người dùng trên cùng một thiết bị. Khi một người dùng đăng xuất và một người dùng khác đăng nhập, điều này tạo ra một mục mới trong bảng DynamoDB để ánh xạ điểm cuối với người dùng mới.

Do đó, bạn phải loại bỏ mục ánh xạ cùng một endpoint với người dùng đã đăng nhập trước đó. Điều này giúp bạn chỉ giữ lại endpoint phù hợp với người dùng được cung cấp bởi ứng dụng di động thông qua yêu cầu.

result = table.query(
    # Add the name of the index you want to use in your query.
        IndexName=”endpoint-index”,
        KeyConditionExpression=Key(‘endpoint’).eq(devicePushEndpoint),
    )
    for item in result[‘Items’]:
        if item[‘username’] != username and item[‘appos’] == appos:
            print(f”deleting orphan item: username {username}, os {appos}”.format(username=item[‘username’], appos=appos))
            table.delete_item(
                Key={
                    ‘username’: item[‘username’],
                    ‘appos’: appos
                },
            )

Kết luận

Blog này chỉ ra cách triển khai một giải pháp serverless để xác thực và quản lý các điểm cuối và mã thông báo của nền tảng SNS. Để xuất bản thông báo đẩy thành công, sử dụng SNS để kiểm tra thuộc tính của điểm cuối và đảm bảo nó được ánh xạ với mã thông báo chính xác và điểm cuối đã được kích hoạt.

Phương pháp này sử dụng DynamoDB để lưu trữ mã thông báo thiết bị và điểm cuối nền tảng cho mỗi người dùng. Điều này cho phép bạn gửi thông báo đẩy đến người dùng cụ thể, lấy và tái sử dụng cá endpoint đã tạo trước đó. Bạn tạo một hàm Lambda để tạo điều kiện cho quy trình làm việc, bao gồm xác thực mục DynamoDB để lưu trữ mã thông báo được kích hoạt và được cập nhật.

Truy cập liên kết này để tìm hiểu thêm về mobile push notifications của Amazon SNS: http://docs.aws.amazon.com/sns/latest/dg/SNSMobilePush.html

Để tìm hiểu thêm về các nguồn tài nguyên học tập về serverless, hãy truy cập Serverless Land.