LoginSignup
0
1

More than 1 year has passed since last update.

Notion APIのタイトル取得の癖を解消する

Last updated at Posted at 2023-01-31

こんにちは。
Notionの案件でNotionのタイトル周りでの癖に悩まされた話と、解決策を書かせていただきます。

Notion APIでページ一覧を取得

Notion APIでは以下のようにしてページ一覧を取得できます。
取得できるのは、インテグレーションをコネクトしたページ、およびインテグレーションをコネクトしたデータベースにぶら下がっているページです。
実際に使用したコードを適当にバラしただけですので、見にくい上に実際に動くかどうか分かりませんが、ご愛嬌で笑ってご容赦いただければと思います。

 const token="";
 const NOTION_VERSION="";

 _post(endPoint, payload) {
    const options = {
      method: 'post',
      headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer ' + token,
          'Notion-Version': NOTION_VERSION,},
    }

    if (payload)
      options.payload = JSON.stringify(payload);

    const resp = UrlFetchApp.fetch(endPoint, options)
    const result = JSON.parse(resp.getContentText());
    return result;
  }

  search(filter = null, start_cursor = undefined) {
    if (!filter) filter = {};
    filter.start_cursor = start_cursor; //undefinedはAPIが許容する

    let result = this._post(`https://api.notion.com/v1/search`, filter);

    //続きがあれば取得
    if (result.has_more) {
      return [...result.results, ...this.search(filter, result.next_cursor)];
    }

    return result.results;
  }

Notion APIの癖

上記のようにしてページ一覧を取得できるのはいいのですが、ここから難がありました。
タイトルが、、、

Notion APIのドキュメントより引用です。propertiesに関する記述です。

If parent.type is "page_id" or "workspace", then the only valid key is title.
If parent.type is "database_id", then the keys and values of this field are determined by the >properties of the database this page belongs to.
https://developers.notion.com/reference/page

これによると、親のタイプがpage_idもしくはworkspaceの場合のみ、確実にtitle属性がつくそうです。
しかし親のタイプがdatabase_idなら、そのデータベースに依存するとあります。

始め私のテスト環境では、親がデータベースの場合取得したページオブジェクトの「名前」属性で取れてたんですね。ですがそれが問題で、たまたま私のデータベースのタイトル部分が「名前」になっていただけで、そうでない場合もあるわけです。

そこで解決策として、propertiesオブジェクト全てを走査し、type属性がtitleのものを抽出する必要があるわけです。具体的なコードは以下になります。

  /**
   * アイテムからタイトルを取得
   */
  function getTitle(item) {
      if (item.object == "database")
        return item.title[0].plain_text;
      for (let prp of Object.values(item.properties)) {
        if (prp.type == "title") {
          return prp.title[0].plain_text;
        }
      }
  }

うーむ、なんと。初めからtitle属性付けておいてくれたら良いのにと思います。
ちなみにtitleがなぜ配列になっているのか、いまだに理解できていません。
一つのページまたはデータベースで、複数のタイトルが付く事ってあるのでしょうか。
詳しい方、コメントで教えていただけましたらこれ幸いです。

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