Skip to main content
Automation API を使用して実験とその結果を取得し、それらを Notion のページプロパティに変換して、単一の Python スクリプトを使用してレコードを Notion データベースにアップサートします。

ゴール

このチュートリアルでは、kameleoon_to_notion.py スクリプトの動作をステップごとに説明します。Kameleoon の実験 ID と Notion のデータベース ID を指定すると、スクリプトは実験のメタデータと統計結果を取得し、最も成果の良いバリエーションを判断して、データを Notion の Experiments データベースにマッピングし、レコードを Notion に書き戻します。同じ実験に対してスクリプトを再実行すると、重複を作成する代わりに既存のページを更新します。 ステップ 1〜5 は、Airtable エクスポートのチュートリアル と同じリクエストとポーリングのフローを再利用します。変わるのは書き込み先のみです。
Notion の API にはネイティブなアップサート機能がありません。スクリプトは、データベースのデータソースに対して実験名と一致するタイトルを持つページを問い合わせ、見つかった場合はそのページを更新し、見つからない場合は新しいページを作成することで、アップサートをエミュレートします。本チュートリアルは、各データベースを 1 つ以上のデータソースを中心に整理する Notion API バージョン 2025-09-03 を対象としています。

要件

  • Kameleoon API の認証情報。 Automation API にはアクセストークンが必要です。スクリプトは client_credentials グラントを使用して、client_idclient_secret からプログラムでアクセストークンを取得します。アクセストークンを取得する を参照してください。
  • Notion の内部インテグレーショントークン。 notion.so/my-integrations でインテグレーションを作成し、そのトークンをコピーします。
  • Experiments スキーマを持つ Notion データベース。次のプロパティが必要です: Experiment Name(title)、Status(select)、Start date(date)、End date(date)、Notes(rich text)、Actual(number)、Probability(select)、Result(select)。
  • Notion のデータベース ID。 データベースをフルページとして開きます(ID は URL 内の ?v= ビューパラメータの前にある 32 文字の文字列です)。
  • Python 3.9 以上requests ライブラリを含む(pip install requests)。
データベースをインテグレーションと共有してください。共有しないと、すべてのリクエストが object_not_found を返します。データベースを開き、••• → Connections → Add connections に進んで、インテグレーションを選択します。
すべての認証情報は環境変数に保存してください。スクリプトにシークレットをハードコードしないでください。
このチュートリアルでは、例として実験 Product Page Redesign(ID 188308)を使用します。オリジナルバリエーションに加えて、Redesign 1(ID 828220)と Redesign 2(ID 828221)の 2 つのバリエーションがあります。

1. Automation API で認証する

エンドポイント: トークンエンドポイントに POST リクエストを送信して、アクセストークンを取得します。
例:
レスポンス:
返された access_token は、以降のすべての Automation API リクエストで Bearer トークンとして送信されます。アクセストークンはデフォルトで 2 時間有効です。

2. 実験を取得する

エンドポイント: Get an experiment エンドポイントに GET リクエストを送信して、実験のメタデータを取得します。
例:
レスポンス(一部省略):
スクリプトは、Notion のページ用に namestatusdateStarteddateEndeddescription を読み取り、次のステップで結果リクエストの範囲を絞り込むために mainGoalId を読み取ります。
API はデフォルトで mainGoalId を返すため、これを読み取るために optionalFields パラメータは必要ありません。Automation API は status フィールドの固定された列挙値を公開しておらず、トークンは今後変わる可能性があります。ステップ 7 では status を大文字・小文字を区別せずにマッチングするため、アカウント間の大文字・小文字の違いによってマッピングが破綻することはありません。

3. 実験の結果をリクエストする

エンドポイント: Request experiment’s results エンドポイントに POST リクエストを送信して、結果レポートの生成をトリガーします。
例:
レスポンス:
Kameleoon はレポートを非同期で生成します。エンドポイントは dataCode を返し、次のステップではこれを使用して結果をポーリングします。
このスクリプトには bayesian: true が必要で、sequentialTesting: false を設定します。bayesiansequentialTesting は有意性を算出するための代替手法であり、このチュートリアルはベイズ成功確率をレポートします。ベイズ推定を有効にすると、レポートの reliability の値にベイズ成功確率(あるバリエーションが参照バリエーションに勝る確率)が反映され、スクリプトはこの値を Probability プロパティにマッピングします。アカウントが別のデフォルトの統計手法を使用している場合は、Kameleoon アプリ内の同じレポートと照らして値を確認してください。

4. 結果をポーリングする

エンドポイント: Poll results エンドポイントに GET リクエストを送信し、レポートが準備できるまで取得を繰り返します。
レスポンスの status は、レポートが計算されている間は WAITING、データが利用可能になると READY、失敗時は ERROR または TIMEOUT になります。ステータスが ERROR または TIMEOUT の場合、レスポンスにはトップレベルの errorDescription が含まれます。スクリプトは、ステータスが READY になるまで一定の間隔でポーリングします。 例:
レスポンス(一部省略):

5. 最も成果の良いバリエーションを選択する

結果には、variationData の下にバリエーションごとに 1 つのエントリと、オリジナルページ用の _reference の行が含まれます。各バリエーションについて、リクエストしたゴールの指標は breakdownData._reference.generalData.goalsData[goalId] の下にあります。 スクリプトは _reference エントリをスキップし、各バリエーションの improvementRatereliability(ベイズ成功確率)を読み取り、改善率が最も高いバリエーションを最も成果の良いものとして選択します。あるバリエーションの goalsData に要求したゴール ID が含まれていない場合、スクリプトは存在するゴールにフォールバックします。ステップ 3goalsIds によりリクエストを単一のゴールに絞り込んでいるため、このフォールバックには通常ほかに選択できるゴールがありません。後でマッピングされる Result プロパティには、そのバリエーションが十分に高い成功確率と正の上昇率を達成し、正真正銘の勝利と見なせるかどうかが記録されます。 例:
この例では、両方のバリエーションが 100% のベイズ成功確率に達していますが、Redesign 1828220)は +211.48% の改善を示しているのに対し、Redesign 2 は -43.33% です。したがって、Redesign 1 が最も成果の良いバリエーションであり、95% を超える確率と正の上昇率を伴う正真正銘の勝者です。

6. Notion のデータソースを解決する

バージョン 2025-09-03 以降、Notion データベースは 1 つ以上のデータソースを格納するコンテナとなり、ページの書き込みとクエリはデータベース ID ではなくデータソース ID を対象とします。この 2 つの ID は相互に置き換えることができません。 エンドポイント: Retrieve a database エンドポイントに GET リクエストを送信して、データベースを取得し、そのデータソースを確認します。
Notion へのすべてのリクエストは、インテグレーショントークンを Bearer トークンとして、また Notion-Version ヘッダーとともに送信します。 例:
レスポンス(一部省略):
スクリプトは最初のデータソースを使用します。データベースに複数のデータソースが存在する場合は、Experiments のプロパティと一致するスキーマを持つものを選択してください。

7. データを Notion プロパティにマッピングする

スクリプトは、実験のメタデータと最も成果の良いバリエーションの指標を、Notion のプロパティ値に変換します。各プロパティタイプには、それぞれ固有の JSON 形式があります。 スクリプトは空の値を省略するため、更新時に既存のプロパティ値が空欄で上書きされることはありません。Notion は不足している select の選択肢を自動的に作成しますが、プロパティ自体は正しい型でデータソースのスキーマにあらかじめ存在している必要があります。 例:
Notion では、データソースごとに 1 つの title プロパティしか許可されません。スクリプトは Experiment Name という名前のプロパティをキーにしてアップサートを行います。title プロパティの名前が異なる場合は、ここと ステップ 8 のクエリフィルタの両方でその名前に変更してください。

8. ページを Notion にアップサートする

Notion にはアップサート用のエンドポイントがないため、スクリプトはデータソースに対して Experiment Name が一致するページを問い合わせ、見つかった場合はそのページを更新し、見つからない場合は新しいページを作成します。 検索: Query a data source エンドポイントを使用して、タイトルフィルタでデータソースに問い合わせます。
作成: Create a page エンドポイントを使用して、データソースを親とするページを追加します。
更新: Update page properties エンドポイントを使用して、一致したページのプロパティを上書きします。
例:
レスポンス(一部省略):

9. スクリプトを実行する

実験 ID と Notion のデータベース ID を引数として渡します:
スクリプトは、認証、取得した実験、最も成果の良いバリエーション、解決されたデータソース、マッピングされたプロパティ、そして Notion のページを作成したか更新したかという各ステップを出力します。

カスタマイズに関する注意事項

  • ステータスマッピングSTATUS_MAP 定数にあり、API が返すステータストークンをキーとし、大文字・小文字を区別せずにマッチングします。Status の選択肢が Running / Implementing / Completed / Defunct と異なる場合はターゲットの値を調整し、単一の GET /experiments/{experimentId} でアカウントが返すトークンを確認してください。
  • Probability は測定されたベイズ成功確率からマッピングされ、結果リクエストで bayesian: true が必要です。Probability プロパティが実験前の見積もりを手動で入力するものである場合は、build_notion_properties から Probability のブロックを削除してください。
  • ゴールの選択 には実験の mainGoalId を使用します。別のゴールについてレポートするには、そのゴール ID を request_resultspick_best_variation に渡してください。
  • アップサートキー。 タイトルの照合は厳密に一致させるため、Experiment Name の大文字・小文字や空白の違いは、既存のページを更新する代わりに新しいページを作成してしまいます。検索してから書き込むフローはアトミックではないため、同じ実験に対して 2 つのエクスポートを同時に実行しないでください。
  • API バージョン。 スクリプトは Notion-Version: 2025-09-03 に固定されています。後でデータベースに 2 つ目のデータソースを追加した場合は、get_data_source_id を更新して名前で正しいものを選択するようにしてください。
  • レート制限。 Automation API は 10 秒あたり最大 50 リクエスト、1 時間あたり最大 1,000 リクエストまで許可しており、Notion API の平均は 1 秒あたり約 3 リクエストです。多数の実験をまとめて処理する場合は、トークンをキャッシュし、スロットリングを追加してください。