🔁

GASでSlackに通知されたNotionのメッセージをDiscordに転送する

2024/10/01に公開

概要

Notionにはデータベースの更新を検知して特定の処理を行うautomationsという機能があり、その中にSlackに通知するものもあります。

https://www.notion.so/help/database-automations

実際に動作させるとこんな感じになります。

slack notification example

ただ、残念ながらSlack以外に未対応で、Discordをメインに使っている身にとって歯がゆい思いをしています。
そこで、Slackに飛んできたメッセージをDiscordに転送することで通知を飛ばすようにしてみました。
また、お金を掛けずに運用したいためGASを使っています。

実装

これらの記事を参考にSlack Botの用意とGASとの連携、DiscordのWebhookの作成を行ってください。

https://qiita.com/flowernotfound/items/318daa37b72558175b4a
https://zenn.dev/lambta/articles/5edbda4ccb1ec6#webhook作成

また実行するスクリプトは以下のコードになります。
webhookUrlに取得したURLを入れるとの、payloadのfieldsを要件に合わせてカスタマイズする必要があります。

function sendToDiscord(jsonData) {
  var webhookUrl = "https://discord.com/api/webhooks/...";
  
  var payload = generateDiscordPayload(jsonData);
  
  var options = {
    "method": "POST",
    "contentType": "application/json",
    "payload": payload
  };
  
  UrlFetchApp.fetch(webhookUrl, options);
}

function generateDiscordPayload(jsonData) {
  var data = JSON.parse(jsonData);
  var event = data.event;

  var payload = {
    "content": "",
    "embeds": [{
      "title": event.blocks[1].fields[0].text.split('|')[1].slice(0, -1).replace('>', ''),
      "url": event.blocks[1].fields[0].text.split('|')[0].slice(2, -1),
      "thumbnail": {
        "url": event.blocks[0].elements[0].image_url
      },
      "color": parseInt("006e54", 16),
      "fields": [
        {
          "name": "Status",
          "value": event.blocks[1].fields[2].text.replace('*Status*\n', '').replace(/~/g, ''),
          "inline": false
        },
        {
          "name": "Deadline",
          "value": event.blocks[2].elements[0].text.split('*Deadline* ')[1].split('    ')[0],
          "inline": false
        },
        {
          "name": "Assign",
          "value": event.blocks[2].elements[0].text.split('*Assign* ')[1],
          "inline": false
        },
        {
          "name": "Editor",
          "value": event.blocks[0].elements[1].text.split('*')[1],
          "inline": false
        }
      ],
      "footer": {
        "icon_url": event.bot_profile.icons.image_72,
        "text": "Updated at " + new Date(parseFloat(event.ts) * 1000).toLocaleString("ja-JP")
      }
    }]
  };

  return JSON.stringify(payload);
}

function doPost(e) {
  const jsonStr = e.postData.getDataAsString();
  
  try {
    sendToDiscord(jsonStr);
  } catch (error) {
    console.log("Error sending to Discord: " + error.message);
  }

  var params = JSON.parse(e.postData.getDataAsString());
  return ContentService.createTextOutput(params.challenge);
}

実行されると以下のような通知がDiscordに飛んできます🥰

discord notification example

GitHubで編集を提案

Discussion