1. 概要
本記事では「API連携」による通知について解説します。
2. SlackからWebHook URLを取得
2-1. Slackから「Add apps」をクリック
2-2. 「Incoming WebHooks」を検索し、「Add」ボタンをクリック
2-3. 「Add to Slack」をクリック
2-4. 「通知するチャンネルを選択」し、「Add Incoming WebHooks integration」ボタンをクリック後、「WebHook URL」(*6-3)を取得
- 「https://hooks.slack.com/services/~」
3. サンプルコード
3-1. ファイル構成(GitHubで管理 )
- notification/slack/scraping_blog_to_slack.gs
- メインコード
- notification/slack/gas_properties.gsheet
- 「WebHook URL」を含め、コード内に書かない方が良いデータ(ID、PASSWORD、KEY等)をプロパティとして保存
3-2. スプレッドシートIDの取得
3-3. GAS Editorの開け方
※「+新規」をクリック
3-4. コード & 解説
※複数のプログラムよりプロパティファイルを共有する為、敢えてスタンドアロン型(*5-2)を採用する
// SlackのWebHook URLが記載されているスプレッドシートのID
const bookId = '1j2z-S●●●●●●●●●●●●●●●●●●●●●●●●●●●●cQk';
// Slackへ通知する際の名前
const username = 'Notification';
let ranking = new Map();
// Mainメソッド
// Blog記事一覧よりデータを取得&ランキングし、Slackへ通知
const main = () => {
const targetUrl = getValueOfProperty('D20');
const articles = scrapingBlog(targetUrl);
const targetMonth = getTargetMonth(-1);
const summary = getSummary(articles, targetMonth);
const rankingTxt = sortRanking();
const title = '先月の記事投稿ランキングです。';
const desc = '■明細';
sendToSlack(`${title}\n${rankingTxt}\n${desc}\n${summary}`);
}
// Blog記事一覧よりデータを取得
const scrapingBlog = (targetUrl) => {
const html = getHtml(targetUrl);
return Parser.data(html).from('<ol class="blog_list">').to('</ol>').build();
}
// サマリー
const getSummary = (articles, targetMonth) => {
let summary = '';
const timeTag = 'time';
const aTag = 'a';
const articleTitles = Parser.data(articles).from('<p class="title">').to('</p>').iterate();
const articleDates = Parser.data(articles).from('<li class="date">').to('</li>').iterate();
let idx = 0;
articleDates.forEach((date) => {
const dateValue = getValueInTag(date, timeTag);
if (dateValue.indexOf(targetMonth) > -1) {
const articleHtml = getHtml(getArticleLink(articleTitles[idx]));
const authorName = Parser.data(articleHtml).from('<span id="authorName" class="authorName">').to('</span>').build();
summary = `${summary}[${dateValue}]<${authorName}>${getValueInTag(articleTitles[idx], aTag)}\n`;
// ランキング用のマップを設定
if (ranking.has(authorName)) {
ranking.set(authorName, ranking.get(authorName) + 1);
} else {
ranking.set(authorName, 1);
}
}
idx++;
});
return summary;
}
// ランキングのソート
const sortRanking = () => {
let rankingTxt = '';
ranking = new Map([...ranking.entries()].sort((a, b) => a[1] < b[1] ? 1 : -1));
ranking.forEach((value, key) => {
rankingTxt = `${rankingTxt}●${key}さん:${value}件、ありがとうございます!\n`;
});
return rankingTxt;
}
// 対象月を取得
const getTargetMonth = (number) => {
const now = new Date();
now.setMonth(now.getMonth() + (number || 0));
return Utilities.formatDate(now, 'JST', 'YYYY.MM');
}
// 対象URLからHTMLを取得
const getHtml = (targetUrl) => {
const response = UrlFetchApp.fetch(targetUrl);
return response.getContentText('UTF-8');
}
// タグ内の値を取得
const getValueInTag = (html, tag) => {
const startIdx = html.indexOf('>') + 1;
return html.substring(startIdx, html.length - tag.length - 3);
}
// Aタグのリンクを取得
const getArticleLink = (html) => {
const href = '<a href="';
const endIdx = html.indexOf('"', href.length);
return html.substring(href.length, endIdx);
}
// 指定のスプレッドシートに記載されているプロパティの値を取得
const getValueOfProperty = (cell) => {
const sheet = SpreadsheetApp.openById(bookId).getSheetByName('Properties');
return sheet.getRange(cell).getValue();
}
// メッセージをSlackへ通知
const sendToSlack = (msg) => {
const webhookUrl = getValueOfProperty('C20');
// 通知する内容
const param = {
'username': username,
'text': msg
};
// paramをJSON文字列に変換
const payload = JSON.stringify(param);
// APIを叩くにあたってどのような仕様で通信を行うか、どのような情報を送るかを指定
const options = {
'method': 'post',
'headers': {
'Content-Type': 'application/json'
},
'payload': payload
};
// APIの呼び出し(ここで実際に通知される)
UrlFetchApp.fetch(webhookUrl, options);
}
4. 実行結果例
5. 参考
5-1. GAS(Google Apps Script)とは
- https://workspace.google.co.jp/intl/ja/products/apps-script/
- https://developers.google.com/apps-script?hl=ja
5-2. 2種類の方式
- コンテナバインド型(スプレッドシートやフォームに紐づくタイプ)
- スタンドアロン型(独立タイプ)
5-3. Webhookとは
5-4. 「UrlFetchApp.fetch()」について
投稿者プロフィール
-
開発好きなシステムエンジニアです。
卓球にハマってます。