1
3

RevenueCat WebhookをAWS API Gateway、Rust Lambda、DynamoDBで処理する

Last updated at Posted at 2024-09-17

RevenueCatは、iOS、Android、Webなど様々なプラットフォームでアプリ内サブスクリプションを簡素化する強力なサブスクリプション管理サービスです。その主要機能の1つは、購入、更新、キャンセルなどのサブスクリプションイベントについてバックエンドに通知するWebhookを送信する能力です。この記事では、AWS API Gateway、AWS Lambda(Rustで実装)、およびストレージ層としてDynamoDBを使用して、RevenueCat Webhookを処理する方法を探ります。

RevenueCat-Webhooks with AWS.jpg

アーキテクチャ概要

アーキテクチャは以下の主要コンポーネントで構成されています:

  1. RevenueCat Webhook:RevenueCatはWebhookイベント(サブスクリプションの更新など)をAWS API Gatewayに送信します。
  2. AWS API Gateway:API Gatewayは、Webhookリクエストのエントリーポイントとして機能し、それらをLambda関数にルーティングします。
  3. AWS Lambda(Rust):RustでUnixmplemented Implementation of 関を処理し、保存に適した構造に変換します。
  4. DynamoDB:この NoSQL データベースは、将来の参照と分析のためにサブスクリプション関連データを保存します。

前提条件

  • Rustがインストールされ、AWS Lambda環境へのクロスコンパイルの準備ができていること。
  • AWS CLIがインストールされ、設定されていること。
  • インフラストラクチャ・アズ・コードのデプロイメントのためのTerraform(オプションですが、強く推奨されます)。

ステップバイステップガイド

ステップ1:API Gatewayのセットアップ

API GatewayはRevenueCatがサブスクリプションイベントが発生したときに呼び出すパブリックエンドポイントとして機能します。以下は設定方法です:

  1. API Gatewayの作成
    AWSコンソール、CLI、またはTerraformなどのインフラストラクチャ・アズ・コードツールを使用してHTTP APIを作成できます。このガイドでは、API Gatewayをセットアップするためのterraformコードを示します。

    resource "aws_api_gateway_rest_api" "revenue_cat_webhook" {
      name = "revenue-cat-webhook"
    }
    
    resource "aws_api_gateway_resource" "webhook_resource" {
      rest_api_id = aws_api_gateway_rest_api.revenue_cat_webhook.id
      parent_id   = aws_api_gateway_rest_api.revenue_cat_webhook.root_resource_id
      path_part   = "webhook"
    }
    
    resource "aws_api_gateway_method" "webhook_post" {
      rest_api_id   = aws_api_gateway_rest_api.revenue_cat_webhook.id
      resource_id   = aws_api_gateway_resource.webhook_resource.id
      http_method   = "POST"
      authorization = "NONE"
    }
    
  2. Lambdaとの統合
    POSTメソッドは、後で設定するLambda関数をトリガーする必要があります。

    resource "aws_api_gateway_integration" "lambda_integration" {
      rest_api_id             = aws_api_gateway_rest_api.revenue_cat_webhook.id
      resource_id             = aws_api_gateway_resource.webhook_resource.id
      http_method             = aws_api_gateway_method.webhook_post.http_method
      integration_http_method = "POST"
      type                    = "AWS_PROXY"
      uri                     = aws_lambda_function.revenue_cat_lambda.invoke_arn
    }
    

ステップ2:Rust Lambda関数の実装

Webhookを処理し、関連データを抽出してDynamoDBに保存するRustベースのAWS Lambda関数を構築します。

  1. AWS Lambda用のRustセットアップ
    Lambdaの環境へのクロスコンパイルに必要なツールを含むRustがインストールされていることを確認してください:

    rustup target add x86_64-unknown-linux-musl
    
  2. Lambda関数
    Lambda関数はRevenueCatからの着信JSONを解析し、処理して、DynamoDBに保存します。

    use lambda_http::{service_fn, Error, IntoResponse, Request};
    use serde::{Deserialize, Serialize};
    use aws_sdk_dynamodb::{Client, model::PutItemInput};
    use std::collections::HashMap;
    
    #[derive(Deserialize)]
    struct WebhookEvent {
        event: String,
        product_id: String,
        app_user_id: String,
        purchase_date: String,
    }
    
    #[derive(Serialize, Deserialize)]
    struct SubscriptionData {
        app_user_id: String,
        product_id: String,
        event: String,
        timestamp: String,
    }
    
    async fn handle_request(event: WebhookEvent, client: &Client) -> Result<impl IntoResponse, Error> {
        // サブスクリプションデータを保存するためのDynamoDBアイテムを作成
        let item = SubscriptionData {
            app_user_id: event.app_user_id.clone(),
            product_id: event.product_id.clone(),
            event: event.event.clone(),
            timestamp: event.purchase_date.clone(),
        };
    
        // アイテムをDynamoDBに適した形式に変換
        let mut item_map = HashMap::new();
        item_map.insert("app_user_id", item.app_user_id.into());
        item_map.insert("product_id", item.product_id.into());
        item_map.insert("event", item.event.into());
        item_map.insert("timestamp", item.timestamp.into());
    
        // アイテムをDynamoDBに書き込む
        client
            .put_item(PutItemInput {
                table_name: "SubscriptionEvents".to_string(),
                item: item_map,
                ..Default::default()
            })
            .await?;
    
        Ok("Success".into_response())
    }
    
    #[tokio::main]
    async fn main() -> Result<(), Error> {
        let config = aws_config::load_from_env().await;
        let client = Client::new(&config);
    
        lambda_http::run(service_fn(|request: Request| async move {
            let event: WebhookEvent = serde_json::from_slice(request.body())?;
            handle_request(event, &client).await
        }))
        .await
    }
    
  3. Lambda関数のデプロイ
    Lambda ランタイム用に関数をコンパイルします:

    cargo build --release --target x86_64-unknown-linux-musl
    

    バイナリを zip 化し、Lambda にデプロイします:

    zip lambda.zip ./target/x86_64-unknown-linux-musl/release/bootstrap
    aws lambda update-function-code --function-name revenue_cat_lambda --zip-file fileb://lambda.zip
    

ステップ3:イベント保存用のDynamoDBテーブル

RevenueCatからのサブスクリプションイベントを保存するためのDynamoDBテーブルが必要です。以下は、TerraformでDynamoDBテーブルを定義する方法です:

resource "aws_dynamodb_table" "subscription_events" {
  name           = "SubscriptionEvents"
  hash_key       = "app_user_id"
  range_key      = "timestamp"
  billing_mode   = "PAY_PER_REQUEST"

  attribute {
    name = "app_user_id"
    type = "S"
  }

  attribute {
    name = "timestamp"
    type = "S"
  }
}

ステップ4:RevenueCat Webhookの設定

API GatewayとLambda関数をデプロイしたら、RevenueCatがWebhookイベントをAPI Gatewayエンドポイントに送信するように設定する必要があります。

  1. RevenueCatダッシュボードで、Webhook設定に移動します。

  2. API Gatewayエンドポイントを指す新しいWebhook URLを追加します。URL例:

    https://your-api-id.execute-api.region.amazonaws.com/prod/webhook
    

ステップ5:Webhookのテスト

Postmanやcurlなどのツールを使用して統合をテストできます。例:

curl -X POST https://your-api-id.execute-api.region.amazonaws.com/prod/webhook \
    -H "Content-Type: application/json" \
    -d '{
        "event": "RENEWAL",
        "product_id": "com.example.premium",
        "app_user_id": "user123",
        "purchase_date": "2023-09-13T00:00:00Z"
    }'

このエンドポイントに正常にヒットすると、Lambdaはイベントをログに記録し、サブスクリプションデータをDynamoDBテーブルに保存します。


結論

AWS Lambda(Rustで実装)、API Gateway、およびDynamoDBを使用することで、RevenueCat Webhookを処理するためのスケーラブルでコスト効果の高いソリューションを構築できます。このセットアップにより、サブスクリプションイベントをリアルタイムで処理し、さらなる分析やサブスクリプション管理のためにそれらを永続化することができます。このアーキテクチャにより、サーバーレスコンピューティングと強力なサブスクリプション管理プラットフォームの最良の部分を活用しています。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3