はじめに
弊社(株式会社コードユニット)は、技術記事投稿の文化を根付けるためにQiita Organizationを始めました。
そこで、Organization内のユーザーが投稿したら弊社Teamsに通知をすることにより、社員同士の投稿を確認しやすくなるのでは・・・?
と思い、BOTを作ってみました。
内々で使用するBOTなので、仕組みはちょっと甘めですが、参考になれば幸いです!
使用技術
- Teams Incomming Webhook
- GAS
- Qiita API
作り方
TeamsのIncomming Webhookを設定する
Teamsで任意のチャンネルを右クリック
こちらの チャネルの管理
を押下し、コネクタの編集
を押下します。
Incomming Webhook の構成を押下し、各情報を入力します。
払い出されたWebhook URLをメモしておきましょう。
GASで定期実行の処理を書く
処理内容としては以下のようになります。
今回はGASで10分毎の定期実行としました。
Qiita APIをコール
https://qiita.com/api/v2/items
でQiitaの全ての投稿が取得できます。
https://qiita.com/api/v2/docs
こちらによると、クエリパラメータで query=${}で、
https://help.qiita.com/ja/articles/qiita-search-options
の検索オプションが使えそうということがわかりましたので、試してみました。
結果、 https://qiita.com/api/v2/items?query=org:codeunit のようにOrganization名でも検索ができましたので、こちらを採用します。
https://qiita.com/fkooo/items/9f8e566c027bb833c29e
こちらを参考に、失敗回避のため、以下のオプションを追記しました。
headers: {
'Accept-Encoding': 'identity',
},
キャッシュに保存する
今回は、処理を定期実行するにあたって、APIから取得した前回の値と、今回取得した値に変更があった場合に処理をしたいと考えました。
https://qiita.com/golyat/items/ba5d9ce38ec3308d3757
上記を参考に、100分間キャッシュすることにしました。
比較
キャッシュデータと今回取得したデータを比較して、
追加のあった記事のみを取得します。
Teamsに通知
追加のあった記事の内容を
先ほど取得したWebhook URLに対してPOSTでメッセージを送信します。
ソースコード全文
function makeCache() {
const cache = CacheService.getScriptCache();
return {
get: function (key) {
const value = cache.get(key);
return value ? JSON.parse(value) : null;
},
put: function (key, value, sec) {
cache.put(key, JSON.stringify(value), sec || 6000);
return value;
}
};
}
// Qiita APIのエンドポイント
const qiitaApiUrl = 'https://qiita.com/api/v2/items?query=org:codeunit';
// Teams WebhookのURL
const teamsWebhookUrl = 'ここに先ほどコピーしたWebhook URLを書きます';
// キャッシュを作成
const cache = makeCache();
// Qiita APIを呼び出してデータを取得
function fetchData() {
const options = {
headers: {
'Accept-Encoding': 'identity',
},
};
const response = UrlFetchApp.fetch(qiitaApiUrl, options);
const data = JSON.parse(response.getContentText());
return data.map(item => ({
title: item.title,
url: item.url,
user: {
id: item.user.id,
},
}));
}
// 前回のデータと比較して新しい記事を通知する
function notifyNewArticles() {
const currentData = fetchData();
const previousData = cache.get('qiitaData') || [];
// 前回のデータと比較して新しい記事を取得
const newArticles = currentData.filter(item => !previousData.some(prevItem => prevItem.url === item.url));
// 新しい記事がある場合、Teamsに通知する
if (newArticles.length > 0) {
newArticles.forEach(article => {
const message = `${article.user.id} さんが新しい記事を投稿したよ <br> タイトル: ${article.title} <br> URL: ${article.url}`;
postToTeams(message);
});
// 新しいデータをキャッシュとして保存
cache.put('qiitaData', currentData);
}
}
// Teamsにメッセージを投稿する
function postToTeams(message) {
const payload = {
text: message,
};
const options = {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload),
};
UrlFetchApp.fetch(teamsWebhookUrl, options);
}
結果
追伸
株式会社コードユニットでは北海道札幌市で一緒に働けるメンバーを絶賛募集中です!
起業したばかりのベンチャーですが、和気あいあいと楽しく仕事をしています!
ご興味のある方は一度ご連絡ください!