見出し画像

NotionのDBの変更をDiscordに通知する方法_2023_07_17

この記事ではGAS(Google Apps Script)を使用したNotionのDBの変更をDiscordに通知する方法を解説します。
NotionやDiscordなどのアカウントは既にあり、基本操作は理解しているものとして進めます。


手順

  • Notionにデータベースを用意。列のプロパティに以下を追加する。

    • テキストプロパティ:「タスク名」

    • ユーザープロパティ:「担当者」

    • チェックボックスプロパティ「通知済み」

note: 他に何か要素があっても大丈夫です

  • データベースのIDをメモ(URLの太字の部分)

    • https://www.notion.so/detabase_id123456789?v=xxxxxxxxxxxxx

  • 通知を送りたいDiscordのチャンネルにWebHookの作成を行いURLをメモ

チャンネルの歯車アイコン(チャンネルの編集)から開ける
  • Notionの私のインテグレーションから作成したデータベースのあるワークスペースを選択する。その後インテグレーションシークレットを作成しメモする。

  • 作成したインテグレーションページの機能から以下の設定をする

    • 「コメントの読み取り」をオン

    • 「コメントを挿入」をオン

    • 「メールアドレスを含むユーザー情報を読み取る」をオン

  • Notionのコネクトの追加から作成したインテグレーションを追加する

  • Notionのインテグレーションシークレットキーと
    DiscordのWebHookURL、データベースのIDを使用し通知を送るためのGASをGoogleドライブに作成し配置する

    • GASは右クリックしてその他の中にあります

//以下の定数をメモしたものに置き換えてください
NOTION_DATABASE_ID
NOTION_SECRET_KEY
DISCORD_WEBHOOK_URL

//Notionのユーザ名をDiscordのIDに変換するための配列です。置き換えてください
discordUsernames
  • 以下GASの全文

// データベースID、Notionの秘密鍵、DiscordのWebhookURLを設定
const NOTION_DATABASE_ID = "";
const NOTION_SECRET_KEY = "";
const DISCORD_WEBHOOK_URL = "";

// 前回のデータベースの内容を記録するためのグローバル変数
let previousDatabaseContents = "";

// Notionのユーザー名とDiscordのユーザー名の対応表
const discordUsernames = {
  "Notionのユーザー名": "<@DiscordのID> ", //DiscordのIDは123456789みたいな数字の羅列の方
  //...人数に応じて追加
};

function convertToDiscordUsername(name) {
  return discordUsernames[name] || name;
}

function checkNotionDatabaseChanges() {
  const URL = `https://api.notion.com/v1/databases/${NOTION_DATABASE_ID}/query`;

  const notionResponse = UrlFetchApp.fetch(URL, {
    method: "POST",
    headers: {"Authorization": `Bearer ${NOTION_SECRET_KEY}`, "Notion-Version": "2022-06-28"},
  });
  
  const databaseContents = JSON.parse(notionResponse.getContentText());

  // データベースの内容が前回と異なる場合、Discordにメッセージを送信
  if (JSON.stringify(databaseContents) !== JSON.stringify(previousDatabaseContents)) {
    databaseContents.results.forEach((page) => {
      // 通知済みのカラムがチェックされていない場合のみ処理を行う
      if (!page.properties['通知済み'].checkbox) {
        let taskName = "Not available";
        let assignee = "Not available";

        // タスク名が存在し、値がある場合のみ取得
        if (page.properties['タスク名'] && page.properties['タスク名'].title[0]) {
          taskName = page.properties['タスク名'].title[0].plain_text;
        }

        // 担当者が存在し、値がある場合のみ取得
        if (page.properties['担当者'] && page.properties['担当者'].people.length > 0) {
          assignee = page.properties['担当者'].people.map(person => convertToDiscordUsername(person.name)).join(', ');
        } else {
          // 担当者がいない場合は処理をスキップ
          return;
        }

        UrlFetchApp.fetch(DISCORD_WEBHOOK_URL, {
          method: "POST",
          contentType: "application/json",
          payload: JSON.stringify({
            "content": `==============================================================================================\n⭐️タスクが更新されました! \n <DBのリンク> \nタスク名: ${taskName}\n担当者: ${assignee}\n=============================================================================================`
          }),
        });

        // 通知済みのカラムにチェックを入れる
        let headers = {
          "content-type": "application/json",
          "Authorization": "Bearer " + NOTION_SECRET_KEY,
          "Notion-Version": "2022-06-28",
        };
        
        let payload = {
          "properties" : {"通知済み":{"checkbox": true}}
        }

        const updateURL = `https://api.notion.com/v1/pages/${page.id}`;

        let options = {
          "method": "patch",
          "headers": headers,
          "payload" : JSON.stringify(payload),
          "muteHttpExceptions": true,
        };

        UrlFetchApp.fetch(updateURL, options);
      }
    });

    // データベースの内容を更新
    previousDatabaseContents = databaseContents;
  }
}

// 1分ごとにチェックするトリガーを設定
function setTrigger() {
  // 過去のトリガーを全て消す
  const triggers = ScriptApp.getProjectTriggers();
  for (let i = 0; i < triggers.length; i++) {
    ScriptApp.deleteTrigger(triggers[i]);
  }

  // トリガーの作成
  ScriptApp.newTrigger('checkNotionDatabaseChanges')
    .timeBased()
    .everyMinutes(1)
    .create();
}

// トリガーを設定する関数を呼び出す
setTrigger();

GASの解説

  • 担当者が設定されていて、通知済みにチェックが入っていない場合に通知がきます。 通知が来たら自動的にチェックが入ります。 データベースの変更は1分毎にチェックしているので、リアルタイムではありません。

note: NotionAPIでDBの変更を監視しなくても通知できるか不明だったので、DBの変更を確認し、変更があれば通知するようにしている。
Notion-Versionも時々チェックしたほうがいいかも。
それとGASの実行時間制限にも注意

  • GASを実行すると警告画面が出るので、詳細をクリックし、安全ではないページに移動から許可する

結果

参考記事:
https://zenn.dev/suzuhiki/articles/4c0e2af773e00f


この記事が気に入ったらサポートをしてみませんか?