所要時間:20〜30分

本ガイドでは、Sequence Builderのアナリティクス機能を活用し、サーバーレスなCloudflare Workerを使って、特定プロジェクトのユーザー利用状況をクエリする方法を解説します。

コミュニティに成果を示すために、Duneのダッシュボードで状況を公開できます。また、生成したAPIを利用し、ユーザー分析に基づくインテリジェントなフィードバックループをゲームに組み込むこともできます。

このガイドの出力例はこちらで確認できます。

  1. アクセスキー管理:Sequenceスタックと連携するためのシークレットアクセスキーを取得
  2. Cloudflare Worker:Sequenceスタックにクエリし、プロジェクト固有のデータポイントを生成する関数を作成
  3. Duneダッシュボード:データを可視化し、共有可能なダッシュボードを作成

テンプレートコードの参考例は こちらをご覧ください。

1. アクセスキー管理

プロジェクトのアプリケーションをSequenceスタックで認証するために、シークレットアクセスキーを取得する必要があります。以下の手順に従ってください。

シークレットアクセスキーの作成

1

設定画面を開く

まず設定画面を開き、「API Keys」カードを選択します。

2

サービスアカウントの追加

画面を下にスクロールし、+ Add Service Accountを選択します。

3

書き込み権限の選択

次に権限をWriteに変更し、+ Add Service AccountをクリックしてからConfirmを選択します。

最後にキーをコピーし、安全な場所に保管してください。このキーは後からSequence Builderで再取得できないため、安全な場所に保管してください。

2. Cloudflare Worker

この例では、Cloudflare Workerを使うことでダッシュボード利用に応じた自動スケーリングやCLIからの簡単なデプロイが可能ですが、ご自身のバックエンドや他のサーバーレスサービスもご利用いただけます。

1

プロジェクトの作成

まず、mkdirでディレクトリを作成し、cdでそのディレクトリに移動し、pnpm initpackage.jsonを作成します。

2

「Hello World」Worker

プロジェクトにwrangler CLIがインストールされていることを確認し、ローカルのbashセッションでwranglerキーワードをエイリアスとして設定してください。

pnpm install wrangler --save-dev
alias wrangler='./node_modules/.bin/wrangler'

Cloudflareサイトでアカウントを作成し、ログインしてCloudflareダッシュボードにアクセスし、Cloudflareプラットフォームをローカル開発環境と接続します。

wrangler login

ログイン後、ディレクトリでwrangler initコマンドを実行し、好みのランダムなプロジェクトフォルダ名を選択してプロンプトに従い、git管理されたTypeScriptの「Hello World」Workerアプリケーションを初期化します。

wrangler init

このステップを完了するには、wrangler init後にエンターを4回押し、最後の2つの質問にはNoと答えてgitバージョン管理とデプロイをスキップしてください。

これにより、クラウドにコードをデプロイできるスターターリポジトリがクローンされます。

ローカルAPIテスト
ガイドの任意のタイミングで、プロジェクトフォルダ内でwrangler devコマンドを使いローカルテストが可能です。

デプロイテスト

最後に、ランダムに生成されたプロジェクトフォルダにcdで移動し、wrangler deployコマンドを実行します。

これによりURLが表示されるので、ブラウザでhttps://<app>.<account>.workers.devにアクセスし、「Hello World!」の結果を確認できます。

3

設定ファイル、ルート、モック関数の準備

プロジェクトのセットアップが完了したら、wrangler.tomlに以下の変数を追加します。ここで、DAYSは分析対象となる期間(日数)を指定します。

[vars]
SECRET_API_ACCESS_KEY = "<SECRET_API_ACCESS_KEY>"
PROJECT_ID = <PROJECT_ID>
DAYS = <DAYS>

次に、index.tsに変数を含めたEnv型を追加します。

export interface Env {
  PROJECT_ID: number;
  SECRET_API_ACCESS_KEY: string;
  DAYS: number;
}

既存のfetch関数を、以下のモック関数呼び出しに置き換えます。

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    const url = new URL(request.url);

    // Handle different endpoints
    if (url.pathname === "/dailyActiveUsers") {
      return handleDailyWallets(env, request);
    } else if (url.pathname === "/totalTransactionsSent") {
      return handleTotalTxns(env, request);
    } else {
      return new Response("No function for this URL", {status: 405});
    }
  }
};

以下の関数を使用します。

const handleDailyWallets = async (env: Env, request: Request) => {
  return new Response(JSON.stringify({endpoint: "daily"}), {status: 200});
};

const handleTotalTxns = async (env: Env, request: Request) => {
  return new Response(JSON.stringify({endpoint: "total"}), {status: 200});
};
4

日付フォーマット

次に、wrangler.tomlDAYS変数に設定された最新の値から正しい日付をパースするためのユーティリティ関数を追加します。

const endDate = () => {
  const today = new Date();
  return today.toISOString().substring(0, 10); // only including the YYYY-MM-DD date
};

const startDate = (env: Env) => {
  const today = new Date();

  // Format today's date as a string
  const daysBefore = new Date(today);
  daysBefore.setDate(daysBefore.getDate() - env.DAYS);

  // Format the date 7 days before as a string by only including the YYYY-MM-DD date
  const daysBeforeString = daysBefore.toISOString().substring(0, 10);
  return daysBeforeString;
};
5

デイリーアクティブユーザー

Daily Active Usersリクエストは、以下の関数を使ってSequence Analytics APIを呼び出して処理します。

const handleDailyWallets = async (env: Env, request: Request) => {
  const resp = await fetch(`https://api.sequence.build/rpc/Analytics/WalletsDaily`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${env.SECRET_API_ACCESS_KEY}`
    },
    body: JSON.stringify({
      filter: {
        dateInterval: "DAY",
        endDate: endDate(),
        projectId: env.PROJECT_ID,
        startDate: startDate(env)
      }
    })
  });

  const data: any = await resp.json();
  return new Response(JSON.stringify(data.walletStats), {status: 200});
};
6

送信されたトランザクション総数

最後に、「送信されたトランザクション総数」用の以下の関数を追加します。

const handleTotalTxns = async (env: Env, request: Request) => {
  const resp = await fetch(
    `https://api.sequence.build/rpc/Analytics/WalletsTxnSentTotal`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${env.SECRET_API_ACCESS_KEY}`
      },
      body: JSON.stringify({
        filter: {
          dateInterval: "DAY",
          endDate: endDate(),
          projectId: env.PROJECT_ID,
          startDate: startDate(env)
        }
      })
    }
  );

  const data: any = await resp.json();
  return new Response(JSON.stringify(data.walletStats), {status: 200});
};
7

ゼロデータの日付の間隔を含める

Sequence Analytics APIのレスポンスには、アクティビティがゼロの日付は含まれていません。時系列の間隔を表示する場合は、以下の関数を使ってデータがない日付も正しいフォーマットで補完できます。

const fillMissingDates = (data: any[], startDate: string, endDate: string) => {
  const filledData: {value: number; label: string}[] = [];
  const start = new Date(startDate);
  const end = new Date(endDate);

  for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
    const dateString = d.toISOString().substring(0, 10);
    const existingData = data.find((entry) => entry.label === dateString);
    if (existingData) {
      filledData.push(existingData);
    } else {
      filledData.push({value: 0, label: dateString});
    }
  }

  return filledData;
};

両方のレスポンスで、walletStatsデータを渡して以下の関数を呼び出してください。

...
	const data: any = await resp.json();
	const filledData = fillMissingDates(data.walletStats, startDate(env), endDate());
	return new Response(JSON.stringify(filledData), { status: 200 });
}

wrangler deployで再デプロイした後、ホスト名の後ろに/dailyActiveUsers/totalTransactionsSentを付けてAPIエンドポイントにアクセスし、テストできます。

Analytics APIで利用可能な他のエンドポイント例については、概要ページを参照してください。

3. Duneダッシュボード

1

Duneへのサインアップ

まず、Duneにサインアップします。

2

クエリの作成

https://dune.com/<account>にアクセスし、CreateボタンからNew queryを選択します。

3

`Daily Active Users`クエリ

以下のSQLクエリをコンソールに入力し、Runを選択します。

SELECT
  t.label as "Date", -- converting the label to "Date"
  t.value as "Count" -- converting the value field to "Count"
FROM UNNEST(
  TRY_CAST(
    JSON_PARSE(HTTP_GET('https://<URL>/dailyActiveUsers')) AS ARRAY(ROW(label VARCHAR, value DOUBLE))
  )
) AS t(label, value)

結果が返ってきたら、New visualizationを作成します。

デフォルトでBar chartが選択されている状態でAdd visualizationをクリックします(カスタマイズも可能です)。

最後にSaveをクリックし、クエリに名前を付けます。

4

`Total Transactions Sent`クエリ

前の手順と同様に進め、以下のSQLクエリを使用します。

SELECT
  t.label,
  t.value
FROM UNNEST(
  TRY_CAST(
    JSON_PARSE(HTTP_GET('https://<URL>/totalTransactionsSent')) AS ARRAY(ROW(label VARCHAR, value DOUBLE))
  )
) AS t(label, value)

結果が返ってきたら、New visualizationを作成します。

Add visualizationを選択し、CounterまでスクロールしてAPIから返された合計値を表示するカウンターウィジェットを作成します。

5

新しいダッシュボードの作成

Create > New dashboardボタンから新しいダッシュボード名を入力します。

作成後、Editをクリックし、Add visualizationから先ほどの2つのクエリを追加します。

各クエリごとにモーダルで名前を検索し、Addを選択、モーダルでDone、ダッシュボードでもDoneをクリックします。

これで、プロジェクトのデータ利用状況をチームメンバーやコミュニティと共有できるようになりました。最後にShareボタンをクリックして完了です。