NotionAPIとGoogle Apps Scriptを使って、Notionのページを自動的にSlack通知する方法
こんにちは!
電話自動応答サービスIVRyのQAエンジニアの関です。
IVRyでは、QAの設計からテストまで担当しています。
QA時の不具合報告フローを改善する際に、NotionAPIとGoogle Apps Scriptを活用することで、簡単に自動化できたので記事にまとめてみました。
元々、IVRyではテスト中に発見した不具合をSlackにてエンジニアチームへ報告し、その後notionのデータベースに不具合ページを作成し、不具合ページのリンクをスレッド内で共有するという冗長なフローを行っていました。
それらを改善するために、NotionAPIとGoogle Apps Scriptを使って、不具合ページが作成されたタイミングで、自動的にSlackへ通知されるようにしてみました。
処理のながれ
[Google Apps Scriptの] の処理のながれは、以下になります。
-
[Notion] からデータを取得する。(NotionAPI を使い、特定の条件を満たすデータを取得します。)
-
「手順1」から取得したNotionページのデータを、 [Spreadsheet] 内に保存されているデータと比較することで、自動的にNotionページが過去に投稿されたものと重複していないか確認します。(Spreadsheet内では、過去に投稿されたページのIDが管理されています)
-
[Slack] に、不具合ページを投稿する。
-
[Spreadsheet] に、 [Notion] のページIDを書き込む。
仕様について
- Notionのページ作成後、5分以内にSlackへ通知される
- Notionのページが重複して通知されない
- フィルター
- ページプロパティの「Category」に"QA結果"が含まれる
- ページプロパティの「最終更新日」が"過去1週間以内"
- 日付フィルター条件については、こちらを参照ください
- ページプロパティの「Publish」が"true"になっている
- 作成中のページが通知されないために、フラグを設定しています
やること
-
Slackにて、通知先のchannelを作成し、Webhookを取得する。
-
Notionにて、データベースを作成し、NotionAPIの作成・設定を行う。
-
重複チェック用のSpreadsheetを作成する。
-
Google Apps Scriptにコードを書き込み、トリガーを設定する。
💡 注意ポイント
NotionAPIを作成するには、admin権限が必要になります。
それでは、詳しく解説していきます!
1. Slackにて、通知先のchannelを作成し、Webhookを取得する
(1) まずは、Slackを開き、通知先のチャンネルを作成します。
(2) 「Incoming WebHooks」を設定します。
・ チーム名をクリックし、設定と管理 > アプリを管理するを選択します。
・ 検索窓に「Incoming」と入力し、「Incoming Webhooks」を選択します。
・ そこから、「Slackに追加」→「チャンネルを選択」→「インテグレーションの追加」の順番でクリックします。
・ 作成完了後、Webhook URL
の項目に表示されているURLをコピーします。
設定は、以上です。
2. Notionにて、データベースを作成し、NotionAPIの作成・設定を行う
(1) Notion Developerを開きます。
(2) 「New integration」 をクリックします。
(3) 各項目を入力します。
・ 「Name」 を入力します。
・ Capabilities > Content Capabilitiesは、 「Read Content」 のみチェックします。
・ User Capabilities > は、「Read user information without email addresses」 にチェックします。
3. Spreadsheetを作成する
(1) Spreadsheetを開きます。
(2) シート名を 「list」 に変更します。
4. Google Apps Scriptのエディタにコードを反映し、トリガーを設定する
(1) 先ほどのSpreadSheetのメニューバー > 機能拡張から 「Apps Script」 をクリックします。
(2) 以下のコードを 「スクリプトエディタ」 にコピペします。
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('list');
const props = PropertiesService.getScriptProperties();
const slack_webhook = props.getProperty('SLACK_WEBHOOK');
const database_id = props.getProperty('NOTION_DATABASE_ID');
const token = props.getProperty('NOTION_TOKEN');
const messageCategory = '不具合ページ';
const messageIcon = 'ticket';
// スプレッドシートから以前に取得したデータを取得し、Notionからデータを取得する。その後、取得したデータをスプレッドシートに保存し、Slackに通知する
function main() {
//スプレッドシートから以前に取得したデータを取得
const pastData = getPastDataFromSpreadSheet();
//Notionからデータを取得
getNotionData().then(data => {
data.results.forEach(record => {
//以前に取得したデータに重複していないかチェック
if (!pastData.includes(record.id)) {
const title = record.properties.Name.title[0].plain_text;
const url = record.url;
const user = record.properties['Created by'].created_by.name;
const image = record.properties['Created by'].created_by.avatar_url;
const jsonData = {
'username' : `Notion by ${user}`,
'icon_url': image,
'text' : `*[${messageCategory}]* \n <${url}|${title}> を作成しました。 \n 不具合内容のご確認お願いします。`
};
postToSlack(jsonData);
setSpreadSheet(record.id);
}
});
});
}
// スプレッドシートから過去に取得したデータを取得し、配列に格納する
function getPastDataFromSpreadSheet() {
// スプレッドシートから過去に取得したデータを取得する
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getDataRange().getValues();
// 過去に取得したデータのIDのみを配列に格納する
const pastData = data.map(row => row[0]);
return pastData;
}
// NotionAPIを使用して、特定の条件を満たすデータを取得し、それらのデータを返す
async function getNotionData() {
const url = `https://api.notion.com/v1/databases/${database_id}/query`;
const headers = {
'content-type': 'application/json; charset=UTF-8',
Authorization: `Bearer ${token}`,
'Notion-Version': '2021-08-16',
};
const filter = {
filter: {
and: [
{
property: 'Publish',
checkbox: {
equals: true,
},
},
{
property: 'LastEditedTime',
last_edited_time: {
past_week: {},
},
},
{
property: 'Category',
multi_select: {
contains: 'QA結果',
},
},
],
},
};
const options = {
method: 'post',
headers,
payload: JSON.stringify(filter),
};
const data = await UrlFetchApp.fetch(url, options);
const parsedData = JSON.parse(data);
return parsedData;
}
// Slackに投稿する関数
function postToSlack(jsonData) {
const options = {
'method' : 'post',
'payload' : JSON.stringify(jsonData)
};
UrlFetchApp.fetch(postUrl, options);
}
// Spreadsheetに取得したデータのIDを追加する関数(NotionのページID)
function setSpreadSheet(id) {
spreadsheet.appendRow([id]);
}
(2) 次に、「スクリプトプロパティ」 を設定します。
プロジェクトの設定から「スクリプトプロパティ」に、NOTION_DATABASE_ID、NOTION_TOKEN、SLACK_WEBHOOKを設定します。
(3) 最後に、5分おきに実行されるように 「トリガー」 を設定します。
まとめ
NotionAPIとGoogle Apps Scriptを組み合わせることで、Notionで作成したページが自動的にSlackへ通知されるようになり、不具合発見時のエンジニアチームへの報告フローが改善されました。
フィルターやトリガーをうまく活用することで、さまざまなシーンで利用することも可能です。
IVRyでは、プロダクト開発だけではなく、積極的に運用改善なども行っています。
最後に、IVRyでは一緒にプロダクト開発を行うメンバーを募集しています!
ご興味を持った方は、ぜひお申し込みください。
Discussion