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

【GAS】Slackのリアクション追加をトリガーに、Notionデータベースにアイテムを追加する

Last updated at Posted at 2024-12-08

これはAcompany😎 Advent Calendar 2024の8日目の記事です。

背景

私の記憶力はゴミです。
タスクを覚えておく、ということがまったくできません。
なので全てのタスクをNotionにメモしているのですが、会社のSlackコミュニケーションが活発なので、半分くらいのタスクはSlackでのやりとりから発生します。
手でタスク表に追加したり、Slackのブックマーク機能を使ったりしていたのですが、どうにも非効率だなと感じたので、Slackのリアクションをトリガーに、Notionデータベースにアイテムを追加したいなと考えました。

作るもの

メッセージにリアクションを追加する

データベースにアイテムが追加される

手順

GASでアプリをデプロイ

以下URLからプロジェクトを新規作成します。

以下のスクリプトを貼って、デプロイしてください。

script.js
function doPost(e){
  var params = JSON.parse(e.postData.getDataAsString());
  if (params.type === "url_verification") {
      return ContentService.createTextOutput(params.challenge);
  }

image.png
アクセスできるユーザーは、全員にしてください。

Slackアプリを作る

以下のURLからアプリを新規作成

アプリ設定

  • Basic Information

    • Display Information
      • アプリの表示名を入力
    • image.png
  • OAuth & Permissions

    • Scopes
      • Bot Token Scopes
        • 以下の権限を追加
          • channels:history
          • reactions:read
        • image.png
  • Event Subscriptions

    • Subscribe to bot events
      • reaction_addedを追加
    • Enabel Events
      • Request URL
        • 先ほどデプロイしたGASアプリのウェブアプリURLを貼る
        • image.png
        • Verifiedと表示されたら成功

Slackワークスペースにアプリを追加

  • Install APP
    • ワークスペースにアプリをインストールする

Notionインテグレーションを追加

上記手順に沿ってインテグレーションを追加してください。

スクリプト

先程のスクリプトを消して、以下のスクリプトを貼り付けてください。
DATABASE_ID, NOTION_TOKEN, SLACK_APP_TOKENはそれぞれきにゅうしてください。

script.js
const post_url = 'https://api.notion.com/v1/pages';
const url_replies = "https://slack.com/api/conversations.replies";
const url_getPermalink = "https://slack.com/api/chat.getPermalink";
const DATABASE_ID = "XXXX"; // NotionのデータベースID
const NOTION_TOKEN = "XXXX"; // Notionアプリのトークン
const SLACK_APP_TOKEN ="XXXX"; // SlackアプリのBotトークン
const query_url = 'https://api.notion.com/v1/databases/' + DATABASE_ID + '/query';
const properties = PropertiesService.getScriptProperties();

function doPost(e){

  let json = JSON.parse(e.postData.getDataAsString());
  let event = json.event;
  let reaction = event.reaction;
  let ts = event.item.ts;
  let channel = event.item.channel;
  let type = event.type;
  let event_ts = event.event_ts;
  
  if(properties.getProperty("event_ts") != event_ts){
    if(type == "reaction_added"){
      if(reaction == "takedayaru"){
        properties.setProperty("event_ts", event_ts);
        getMessage(ts, channel);
      } 
    }
  };
};

function getMessage(ts, channel){
  
  let options_replies = {
    "method" : "get",
    "contentType": "application/x-www-form-urlencoded",
    "payload" : { 
      "token": SLACK_APP_TOKEN,
      "channel": channel,
      "ts":ts
    }
  };
  
  
  let options_getPermalink = {
    "method" : "get",
    "contentType": "application/x-www-form-urlencoded",
    "payload" : { 
      "token": SLACK_APP_TOKEN,
      "channel": channel,
      "message_ts":ts
    }
  };

  // メッセージテキストを取得
  let responseReplies = UrlFetchApp.fetch(url_replies, options_replies);
  let jsonResponseReplies = JSON.parse(responseReplies);
  let text = jsonResponseReplies.messages[0].text;
  
  // メッセージリンクを取得
  let responsePermalink = UrlFetchApp.fetch(url_getPermalink, options_getPermalink)
  let jsonResponsePermalink = JSON.parse(responsePermalink);
  let link = jsonResponsePermalink.permalink;
  
  addTask(text, link);

};

function addTask(text, link){
  let today = new Date();
  
  // 日付をフォーマット
  let formattedDate = today.getFullYear() + '-' +
                        String(today.getMonth() + 1).padStart(2, '0') + '-' +
                          String(today.getDate()).padStart(2, '0');
  let dueDate = new Date(formattedDate);
  
  let json = {
    parent: {
      database_id: DATABASE_ID,
    },
    properties: {
      "名前": {
        "title": [{
          "text": {
            "content": text
          }
        }]
      },
      "期日": {
        "date": {
          "start": formattedDate
        }
      },
      "URL": {
        "url": link
      }
    }
  }

  let options_post = {
    "method": "POST",
    "headers": {
      "Content-type": "application/json",
      "Authorization": "Bearer " + NOTION_TOKEN,
      "Notion-Version": '2022-06-28',
    },
    "payload": JSON.stringify(json),
  };

  UrlFetchApp.fetch(post_url, options_post);

};

プロジェクトの設定スクリプトプロパティから、プロパティを作成しevent_tsと入力してください。
image.png

なぜかリアクションを1回押しただけなのに、イベントが2回発生して、タスクが2レコード生成されることがありました。
その防止策として、最初にリアクション追加タイムスタンプを条件分岐に使用しています。

再度デプロイします。

完成

これで完成です。
Be Hackerなタスク管理で、クリスマスを待ちましょう!

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