slackワークフロー▶NotionDBへ自動反映 非エンジニアでもできるよ!
目的
slackでフローとして、流れていってしまう情報を、うまくストックとしてナレッジ活用できる形にできないか?
をNotion/GoogleSpreadSheetを利用して実現する方法を、非エンジニアでも理解できる形で説明します。
試行錯誤含めて、2〜3時間で実行可能です。詰まったらご連絡ください。
前提/準備
・slackは有料版(ワークフローを利用するため)
・slackの管理者権限(アプリ追加&ワークフロー作成
・notionの管理者権限(インテグレーショントークンを発行するため)
・googleアカウント
概要
Notionにつなげるための情報(インテグレーショントークン)を取得する
Notionに情報を保存するデータベースを用意し、作成したインテグレーションを追加する
GoogleSpreadSheetを作成する
slackにGoogle Sheets for Workflow Builderアプリを追加する
slackにワークフローを追加し、入力情報をGoogleSpreadSheetへ保存されるようにする。
GoogleSpreadSheetにGAS(Google Apps Script)を追加し、GoogleSpreadSheetへデータ追加時に自動的にNotionへ反映させる
詳細
1.Notionにつなげるための情報(インテグレーショントークン)を取得する
a.https://www.notion.so/my-integrations へアクセス
b.新しいインテグレーションを作成
c.名前をつける(例:源田たまらん)

d.送信を押す
e.インテグレーショントークンを表示し、コピーする(GASで利用する)

これで1つ目は完了です。ストゼロでもいっぱい引っ掛けましょう。
2.Notionに情報を保存するデータベースを用意し、作成したインテグレーションを追加する
a.fullデータベースを作る (インラインは使わないほうがいいです)

b.名前をつけて、プロパティ(カラムのこと)に、
質問、質問者(テキスト)、解決希望(テキスト)、回答(テキスト)、ステータス(チェックボックス)となるように設定する。

c.さっき作成したインテグレーションを追加する

※これを追加することで、インテグレーショントークンを利用して、GASからNotionのデータベースへアクセスできるようになる。
d.データベースIDを取得する。

データベースのリンクをコピーして、データベースIDをコピーする(GASで利用する)
以下のようなURLだと、4085e51b23b34e98bc343daf9bb4c30b がデータベースIDになります。 ?より前の文字列。
https://www.notion.so/kiyogon/4085e51b23b34e98bc343daf9bb4c30b?v=0fad4c4fdde7478eacbe31a1602a2ee0&pvs=4
これで2つ目は完了です。ストゼロ2本目行きましょう。
3.GoogleSpreadSheetを作成する
a.スプレッドシートを起動

b.新しいスプレッドシートを作成

c.名前をつけておきましょう

d.ヘッダとして、質問、質問者、回答、解決希望 を記入する

これで3つ目は完了です。ストゼロ3本目行きましょう。
4.slackにGoogle Sheets for Workflow Builderアプリを追加する
a.slackのAppから、googleで検索して「Google Sheets for Workflow Builder」を追加する


これで4つ目は完了です。そろそろウィスキー行きますか。
5.slackにワークフローを追加し、入力情報をGoogleSpreadSheetへ保存されるようにする。
a.slackのワークスペース名をクリックして、ツールからワークフロービルダーを起動

b.「作成」ボタン▶ワークフローに名前をつける(例:ダルビッシュたまらん)

c.ショートカットを選択

d.チャネルを選択&名前を記入(例:大谷たまらん)


e.ステップを追加▶フォームを送信するを追加

f.なんか質問、長い回答 ▶質問の追加

g.優先順位、一覧から選択、リストアイテムに項目作る▶終了▶保存する

h.ステップを追加▶Add a spreadsheet row を追加

i. googleアカウントを連携し、先ほど作成したスプレッドシートを選択&Sheetを選択(シート1)

j.Column name質問に、変数を挿入する、から、先程作成した「なんか質問」を選択
※これで、slackのワークフローの「なんか質問」に回答された値が、googleworksheetの「質問」のところに入力される。

k.Add Columnボタンを押して、Column name解決希望に、変数を挿入する、から、先程作成した「優先順位」を選択
※これで、slackのワークフローの「優先順位」に回答された値が、googleworksheetの「解決希望」のところに入力される。

l.Add Columnボタンを押して、Column name質問者に、変数を挿入する、から、「フォームを提出したメンバー」を選択し、保存
※これで、slackのワークフローに回答した人の名前が、googleworksheetの「質問者」のところに入力される。

m.おまけではあるが、フォーム入力後に、ステップを追加して、質問に回答すべき担当者宛にメッセージを送るとよい。

n.実際に上記のワークフローを実施し、フォームに入力したものが、googlespreadsheetに保存されていることを確認する。

これで5つ目は完了です。ここまででslackのワークフローからgooglespreadsheetまでのデータ連携ができるようになりました。
そろそろウィスキー2杯目!
6.GoogleSpreadSheetにGAS(Google Apps Script)を追加し、GoogleSpreadSheetへデータ追加時に自動的にNotionへ反映させる
さて、最後GASはプログラミングになるので難しいですが、コピペで動くはずなのでがんばりましょう。
a.GoogleSpreadSheetの「slackNotion連携テスト」を開き、拡張機能から、「Apps Script」を選択して、プロジェクトに名前をつける。


b.以下をコピーしてコード.gsのところに貼り付ける(元のコードは消してよい)。Notionのインテグレーショントークンと、データベースIDを貼り付ける。
// NotionのIntegration Tokenを""内に入力
const NOTION_TOKEN = "";
// NotionのDatabaseIDを""内に入力。DatabaseのURLの「〜〜so/【DatabaseID】?v=〜〜」
const DATABASE_ID = "";
function main() {
// スプレッドシートからアクティブなシートを取得する
const ss = SpreadsheetApp.getActiveSpreadsheet();
//最初の1行をhedersに入れる
const headers = ss.getDataRange().getValues()[0];
Logger.log("headers:")
Logger.log(headers)
//slice(1)で2行目以降を対象とし、ヘッダ+データの組み合わせに変換する。
const js = ss.getDataRange().getValues().slice(1).map(
function (row) {
const obj = {};
headers.forEach(function (header, i) {
obj[header] = row[i];
});
return obj;
});
Logger.log("js形式(ヘッダ+データ)になったやつ:")
Logger.log(js)
//最後の1行だけを取得
const lastRow = [js[js.length - 1]];
Logger.log("最後の項目:")
Logger.log(lastRow);
// Notionのデータベースにデータを登録する
lastRow.forEach(function (elem, index) {
const notionProperties = {
"質問": {
"title": [
{
"text": {
"content": elem.質問
}
}
]
},
"質問者": {
"rich_text": [
{
"text": {
"content": elem.質問者
}
}
]
},
"解決希望": {
"rich_text": [
{
"text": {
"content": elem.解決希望
}
}
]
}
};
const notionRequestBody = {
"parent": {
"database_id": DATABASE_ID
},
"properties": notionProperties
};
// postNotion関数を呼び出す
postNotion(notionRequestBody);
Utilities.sleep(1000);
});
}
// Notion APIを呼び出してデータを登録する
function postNotion(requestBody) {
const options = {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Notion-Version': '2022-06-28',
'Authorization': 'Bearer ' + NOTION_TOKEN
},
payload: JSON.stringify(requestBody)
};
try {
const response = UrlFetchApp.fetch('https://api.notion.com/v1/pages', options);
Logger.log(response)
} catch(e) {
// 例外エラー処理
Logger.log('Error:')
Logger.log(e)
}
}
c.プロジェクトを保存する

d.実行すると、なんか出るので、権限を確認▶詳細▶gasテスト(安全ではないページ)に移動▶許可




e.実行されると、ログが出ます。実行完了になったらOK。


f.notionのデータベースに反映していることを確認しましょう。

g.トリガーから、「トリガーを追加」▶イベントの種類を「変更時」にして保存しましょう。※これで、データ追加時に自動的にGASが起動します。
その後、改めて、slackのワークフローからGoogleSpreadSheet▶Notionデータベースへと反映されることを確認しましょう。


g.運用としては、以下のように考えています。
・質問したい人がslackのワークフローをショートカットから起動し、フォーうに入力
・回答する人はslackのスレッドで対応する
・対応が完了したら、notionのデータベースにサマリを記入する。(slackのスレッドへのリンクも張っておく)
・このデータベースを社内に公開することで、過去にあった質問と対応内容が把握できる。
h.おまけ。chatGPTに、上記のコードをそのままはりつけて、リファクタリングしてくれ、って言ったら以下が出てきてそのまま動作した(ゴクリ)
const NOTION_TOKEN = "";
const DATABASE_ID = "";
function main() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getActiveSheet();
const data = sheet.getDataRange().getValues();
const headers = data.shift();
const js = data.map(row => {
const obj = {};
headers.forEach((header, i) => obj[header] = row[i]);
return obj;
});
const lastRow = js[js.length - 1];
const notionProperties = {
"質問": { "title": [{ "text": { "content": lastRow.質問 } }] },
"質問者": { "rich_text": [{ "text": { "content": lastRow.質問者 } }] },
"解決希望": { "rich_text": [{ "text": { "content": lastRow.解決希望 } }] }
};
const requestBody = {
"parent": { "database_id": DATABASE_ID },
"properties": notionProperties
};
postNotion(requestBody);
}
function postNotion(requestBody) {
const options = {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Notion-Version': '2022-06-28',
'Authorization': 'Bearer ' + NOTION_TOKEN
},
payload: JSON.stringify(requestBody)
};
try {
const response = UrlFetchApp.fetch('https://api.notion.com/v1/pages', options);
Logger.log(response);
Utilities.sleep(1000);
} catch(e) {
Logger.log('Error:');
Logger.log(e);
}
}
chatGPTのコメントは以下

これで完了です。お疲れさまでした。
いい感じに酔ってきましたか?テンション上げて引き続き飲んでくださいね!
ここまで完成できたらとても偉いです。1個1個ステップの内容を理解したあとは、自分流にカスタマイズしてください!一緒に頑張りましょう!