3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TROCCOの転送先カスタムコネクタでNotion Databaseに外部からデータ連携する

Posted at

はじめに

本記事は、TROCCO&COMETA Advent Calendar 2025の13日目の記事になります。

TROCCOでは、昨季(2024/11~2025/10)に転送元の大幅な拡充を進めてきました。これによってデータを取得できる対象は広がってきましたが、一方で従来からあるデータベース/ストレージやMA/SFAなどだけでなく、広告オーディエンスリスト連携といったデータによる業務の自動化を進めていくデータアクティベーションの領域にも対応を広げています。

その一環として、2025/12/11に独自の転送先コネクタを作成できる転送先カスタムコネクタ(*)がリリースされました。

これまで「Connector Builder」と呼ばれていたものが、「カスタムコネクタ」と名称が変更になり転送先の機能が追加されています。

転送先カスタムコネクタについては以下の記事で概要を説明しています。

また、複数レコードに対して1リクエストを行う事例として、LINE Messaging APIを利用した以下の記事も公開しています。

これらの記事は全て新規作成のみを行う処理だったのですが、転送先カスタムコネクタでは作成APIと更新APIを組み合わせて、Upsertの処理を行うこともできます。本記事では、Upsert処理の例としてNotion Databaseへのデータ連携の事例を取り上げます。

こんな方におすすめ

  • 転送先カスタムコネクタの概要を知りたい方
  • 転送先カスタムコネクタを使うことによって何ができそうかを考えたい方
  • Upsertモードの設定方法を確認したい方

本記事でご紹介する機能は執筆時点のものであり、機能拡充に伴い仕様が変更される可能性があります。

Notion Databaseにデータを連携する

Notionでは、GUIでリッチな視覚的表現をできる反面、裏側のデータの保持の仕方が非常に複雑になっています。それによって、APIも取り回しが難しいです。

そこで、本記事では外部で管理しているデータをNotionで読み取り専用の形で利用する形とします。以下のようなイメージです。

転送先Connector Builderを利用したNotion DatabaseのUpsert処理.png

例としてはスプレッドシートでデータを保持する形にしていますが、考え方としては他のデータソースにも適用できるかと思います。

スプレッドシート→BigQueryのデータ転送については割愛しますが、わかりやすさのためフィルターをかけてレコード数を制限しています。

ソースデータを準備する

ソースのデータとしては、データサイエンス100本ノックのstoreのデータを利用します。これをスプレッドシートに記載しておきます。

ソースデータのBigQueryへの転送時に、store_cdの末尾が「0」のもののみにフィルタリングしています。

Notionと接続する準備をする

シークレットの発行方法等については、以下の記事を参考にしてください。転送元として利用するにも、転送先として利用するにも設定方法としては共通です。

データベースも事前に設定しておきます。

image.png

カスタムコネクタを作成する(基本情報)

各種項目を設定していきます。認証種別はAPIキーを選択します。

image.png

この段階で一度保存し、次は接続情報を作成します。

接続情報を作成する

APIキーや認証トークンとしてインテグレーションシークレットを入力します。

image.png

カスタムコネクタを作成する(エンドポイント)

今回はUpsertの設定をするため、作成APIと更新APIの2種類を作成する必要があります。

作成API

以下のエンドポイントになります。

リクエストテンプレートは以下の通りです。ややこしいのはAPI仕様がややこしいので・・・。とはいえAIに依頼すればこれくらいは全然書いてくれます。

{%- assign title_column = "store_cd" -%}
{%- assign text_columns = "store_name,prefecture,address,address_kana" | split: "," -%}
{%- assign number_columns = "prefecture_cd,longitude,latitude,floor_area" | split: "," -%}
{%- assign phone_columns = "tel_no" | split: "," -%}
{%- assign other_columns = text_columns | concat: number_columns | concat: phone_columns -%}
{
    "parent": {
        "database_id": "{{ row.database_id }}"
    },
    "properties": {
        "{{ title_column }}": {
            "title": [
                {
                    "text": {
                        "content": "{{ row[title_column] }}"
                    }
                }
            ]
        }{% for col in text_columns %},
        "{{ col }}": {
            "rich_text": [
                {
                    "text": {
                        "content": "{{ row[col] }}"
                    }
                }
            ]
        }{% endfor %}{% for col in number_columns %},
        "{{ col }}": {
            "number": {{ row[col] }}
        }{% endfor %}{% for col in phone_columns %},
        "{{ col }}": {
            "phone_number": "{{ row[col] }}"
        }{% endfor %}
    }
}

image.png

なお、テンプレートを書くのが大変すぎたので変数を活用して設定している関係で、接続確認時にキーの値が自動では出てきませんが、入力すれば利用可能です。

更新API

以下のエンドポイントになります。

こちらは既存のレコードに対して更新をかけるので、パスにpage_idを指定してPATCHでリクエストを送る形になっています。リクエストテンプレートは以下の通りです。こちらもややこし(以下略)

{%- assign title_column = "store_cd" -%}
{%- assign text_columns = "store_name,prefecture,address,address_kana" | split: "," -%}
{%- assign number_columns = "prefecture_cd,longitude,latitude,floor_area" | split: "," -%}
{%- assign phone_columns = "tel_no" | split: "," -%}
{%- assign other_columns = text_columns | concat: number_columns | concat: phone_columns -%}
{
    "properties": {
        "{{ title_column }}": {
            "title": [
                {
                    "text": {
                        "content": "{{ row[title_column] }}"
                    }
                }
            ]
        }{% for col in text_columns %},
        "{{ col }}": {
            "rich_text": [
                {
                    "text": {
                        "content": "{{ row[col] }}"
                    }
                }
            ]
        }{% endfor %}{% for col in number_columns %},
        "{{ col }}": {
            "number": {{ row[col] }}
        }{% endfor %}{% for col in phone_columns %},
        "{{ col }}": {
            "phone_number": "{{ row[col] }}"
        }{% endfor %}
    }
}

image.png

ここまでできればカスタムコネクタの作成は完了です。

転送設定を作成する

続いて、転送設定を作成し転送ジョブを実行します。転送元BigQuery→転送先カスタムコネクタとして転送設定を作成します。

image.png

SQLは以下の通りです。

初期設定
select
  '$database_id$' as database_id,
  null as page_id,
  s.*
from
  `<project_id>.<dataset_id>.raw_spreadsheet__store` s
更新後(転送元Notionのデータも合わせて活用)
select
  '$database_id$' as database_id,
  n.id as page_id,
  s.*
from
  `<project_id>.<dataset_id>.raw_spreadsheet__store` s
inner join
  `<project_id>.<dataset_id>.raw_notion__store` n
  on
    s.store_cd = json_value(json_query_array(n.properties__store_cd__title)[0], '$.text.content')

union all

select
  '$database_id$' as database_id,
  null as page_id,
  s.*
from
  `<project_id>.<dataset_id>.raw_spreadsheet__store` s
left join
  `<project_id>.<dataset_id>.raw_notion__store` n
  on
    s.store_cd = json_value(json_query_array(n.properties__store_cd__title)[0], '$.text.content')
where
  n.id is null

image.png

image.png

カスタムコネクタとしては、UPSERTモードを選択します。これにより、page_idの有無に応じて、なければ作成API、あれば更新APIに対してリクエストが行われるようになります。

image.png

プレビューに進むと、カスタムコネクタで設定したテンプレートの通りにリクエストで送られるデータが表示されます。

image.png

問題なければこれで保存します。

データを転送する

保存した転送設定を実行します。無事成功です!

image.png

実際、Notion Databaseにデータが連携されています!

image.png

既存レコードをUpdateする

既存のレコードについては作成ではなく更新処理を行うため、転送元Notionを利用して連携済みのデータを取得し、それとスプレッドシートのデータを合わせて処理できるようワークフローを組みます。

image.png

この状態で、スプレッドシートのS14010のstore_nameを「店名が変わりました!!!」に変更してみましょう。

image.png

この状態でワークフローを実行します。すると、Notion Databaseのレコードが更新されました!

image.png

なお、今回は未変更レコードの除外処理をしていないので、更新処理は既存のレコード全てに対して適用されています。

差分処理に変更するには、Notionから取得したデータとスプレッドシートから取得したデータに差分があるかの判定を入れる必要が出てきます。

おわりに

ここまで、Notion Databaseを例に読み取り専用のUpsert処理を行う方法を解説しました。Notion Database以外でも考え方としては使えるので、参考にしてみてください。

また、途中で触れてもいますがNotionはそもそものデータ構造/APIの仕様が複雑であることと、作成/更新ともに1レコード1リクエストの形式になっているため、パフォーマンス上の課題も想定されます。初期取込は切り分けをする、差分更新に処理を最適化するなど、対応方法の検討が必要になるでしょう。

3
0
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
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?