こんにちは。最後にブログを書いたのは秋頃だったでしょうか。久しぶりにブログを書いております佐々木です。
推しは丹生ちゃんです。いつのまにか丹生ちゃんの心を失ってしまったため、丹生ちゃんのあの明るさが心に刺さります。
それは盛ってるで!と言われそうなので本題に行きましょう。
今日は、日向坂のメンバーがブログを更新したら、自動でSlackに通知するようにした[1]過去を遡ると、2019年7月ころに作成したのに、怠惰すぎて今頃ブログを書いてますので、それのやり方を書いていきたいと思います。
「いやいやSmartNewsで十分だろ!」と言われたらその通りなのですが、Slackのチャンネルに投稿することで、Slackの中でコミュニケーションが活性化されます。(無理やり
「LINEにして!」という方には申し訳ないですが、そこまではできてないので、ここあたりのブログを参考に頑張ってみてください。
GAS × LINE Notifyで電車の遅延情報を通知するbotを作ってみた。
何を作るか
まずは完成イメージです。
以下のように、スプレッドシートにブログ更新をしたら通知してほしいメンバーの名前を書いておきます。

そのシートに書いたメンバーについて、ブログ更新があったら、Slackに通知します。

30分おきに更新がないかを自動で見に行って、更新があれば通知してくれます。
いち早く情報が欲しい人は1分おきでもできるので、調整してください。
ひなあいで制作の手の込んだテロップを毎週目にしている皆さんは目が肥えているのでわかったかもしれませんが、Slackの通知では、メンバーの顔写真の隣に、メンバーのペンライトカラー(っぽい色)を入れてます (地味に)。
あとSlackのアイコンは日向坂のロゴにしてます。この辺りも好きなように変更できます。
これらのおかげで、ガムランボールを鳴らした時のように少しSlackが華やかに。
どうするのか
使うのは以下の3つです。
- Googleスプレッドシート
- Google Apps Script
- Slack
Google Apps Scriptは聞いたことがない人も多いかもしれませんが、気にせず大丈夫です。
さて、ここからは具体的にどうやっているのかは書かず、最短で取得するまで一気に書きます。
飛行機がどう動いてるか分からないけど、乗るという目的が達成できればいいわけです。その気持ちでいきます。
Slack 側の準備
以下の画面のように、Slack 画面左上の下三角をクリックし、「Customize [Workspace名] 」を選択します。

Slackのカスタマイズページに飛ぶと思うので、左のメニューから「configure apps」(日本語だとApp管理?)を選択します。
Appの画面が開くので、「Incoming WebHooks」と検索して、選択します。

アプリの説明画面に行くので、左の「Add configuration」(日本語だと設定を追加?)を押します。
「チャンネルへの投稿」が表示されると思うので、Post to Channel に 送信したいチャンネル名 (まだ作ってない場合は、チャンネル選択の下のところから可能です)を選択してください。
設定が終わったら、「Add Incoming Webhooks integration」を押します。
次の画面で以下を任意に設定してください。
- Webhook URL: 何もしません。このURLをどこかにコピーしておいてください。あとで使います。
- Descriptive Label: この機能の説明。 例.日向坂のブログ更新を自動で通知する
- Customize Name: この機能の名前。 例. hinata-incoming-webhook
- Customize Icon: 特に何もしなくても良いです。自動で投稿されるときのアイコンは、後ほどコードの方で対応します。ある人が日向坂にハマったきっかけと言っているロゴとかにしましょう。
後ほど、アイコンを設定するので、Slackの絵文字にそれ用の絵文字を追加しておいてください。
絵文字の追加はこちらを参考にしてください。
絵文字の名前を :日向坂アイコン:
にしておくとコードを変えなくてよいので楽です。
ここまで設定できたら、Slack側は一旦OKです。
Google Spread Sheet の準備
スプシを作成します。以下のようにシートは2つ作ってください。
シート名は変えても良いですが、後々のGoogle Apps Scriptのコードで変更しないといけない部分も出てきてしまうので、強固な意志がなければ、同じようにすることをお勧めします。
- スプシの名前: 日向坂ブログ
- シート1: 「最新ブログ」
- シート2: 「メンバー」 ← 運用するのはこのシートだけ

後で使用するので、スプシのURLの一部分をどこかにメモっておいてください。この緑の部分。(以下のURLは適当に作ったものです)
URL: https://docs.google.com/spreadsheets/d/jfklagiagiiajfi29r923u438991/edit#gid=8012859128
「メンバー」シートには、あなたがフォローしたいメンバーの「名前」「ブログのURL」「カラーコード」を書いておいてください。
- 「名前」: A列 : かすが
- 「ブログのURL」 : B列 : https://www.hinatazaka46.com/s/official/diary/member/list?ima=0000&ct=16
- 「カラーコード」 : C列 : #7cc7e8 (これは空色) [2]カラーコードはこのサイト辺りを参考にしてください
ブログの URL は各メンバーのページです。間違ったページのURLを入れないように注意してください。
Google App Script にスクリプトを書く
先ほど作成したスプシを開き、メニューバーのツールから、「スクリプトエディタ」を開きます。
以降、途中途中で何度か権限の承認を求められると思いますが、すべて承認しちゃってください。[3]大丈夫なはずですが、自己責任でお願いします
コード貼り付け前の準備
右上から「以前のエディタを使用」をクリックし、メニューの「ファイル」から「ファイルのプロパティ」を選択してください。
「情報」タブの「名前」に適当な名前を付けます。例.blogPushSlack
続いて「スクリプトのプロパティ」タブで、2つのプロパティを追加します。値はさっきメモった2つです。
- SHEET_ID : スプシのURLの一部のやーつ(さっきの緑の)。例. jfklagiagiiajfi29r923u438991
- SLACK_INCOMING_URL : Slack の Incoming Webhook の URL のやーつ。
この2つを入れたら、保存します。無駄にスペースが入ったりするとコードがうまくは知らない原因になるので注意してください。
続いて、2つのライブラリ「SlackApp」と「Parser」を追加します。
メニューから「リソース」を選択し、
SlackApp
「1on93YOYfSmV92R5q59NpKmsyWIQD8qnoLYk-gkQBI92C58SPyA2x1-bq」を入れて検索します。
SlackApp がライブラリとして追加されるので、バージョンを22にして、保存してください。
それ以外はデフォルトで良いです。
Parser
「1Mc8BthYthXx6CoIz90-JiSzSafVnT6U3t0z_W3hLTAX5ek4w0G_EIrNw」を入れて検索します。
Parser がライブラリとして追加されるので、バージョンを7にして、保存してください。
それ以外はデフォルトで良いです。
コードを張り付ける
コード.gs に以下のコードをコピペして、「Ctrl+S」などで保存してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | var SHEET_NAME = "最新ブログ" var MEMBER_SHEET_NAME = "メンバー" var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("") function main() { BLOGS = getBlogs() SLACK_INCOMING_URL = getProperty('SLACK_INCOMING_URL') for(key in BLOGS){ Logger.log(key) var link = BLOGS[key][0] var html = UrlFetchApp.fetch( link ).getContentText() var color = BLOGS[key][1] var items = Parser.data(html).from('<div class="p-blog-group">').to('<div class="p-button__blog_detail">').iterate() var item = items[0].replace(/\r?\n/g, '') var title = item.match(/<div class="c-blog-article__title">(.+?)<\/div>/)[1].replace(/^\s+/,"").replace(/\s+$/,"") var images = Parser.data(html).from('<div class="l-sub-contents--blog">').to('<div class="p-blog-member__head">').iterate() var image = images[0].replace(/\r?\n/g, '').match(/<div class="c-blog-member__icon" style="background-image:url\((.+?)\);"><\/div>/)[1] if ( isUpdated(key, title) ){ sendSlack(makeAttachment(key, link, title, color, image), key, link, SLACK_INCOMING_URL) } } } function getProperty(key){ return PropertiesService.getScriptProperties().getProperty(key) } function getBlogs(){ var myarray = [] SHEET_ID = getProperty('SHEET_ID') var SPREADSHEET = SpreadsheetApp.openById(SHEET_ID) var SHEET = SPREADSHEET.getSheetByName(MEMBER_SHEET_NAME) var ROWS = SHEET.getDataRange() var VALUES = ROWS.getValues() var obj = {} for (var i=0; i<VALUES.length; i++){ name = String( VALUES[i][0] ) link = VALUES[i][1] color = VALUES[i][2] obj[name] = [link, color] } Logger.log(obj) return obj } function isUpdated(key, title){ var SPREADSHEET = SpreadsheetApp.openById(SHEET_ID) var SHEET = SPREADSHEET.getSheetByName(SHEET_NAME) var [numCol, currentTitle] = readSpreadsheet(key, title, SHEET) if (currentTitle!=title){ UpdateSpreadsheet(numCol, key, title, SHEET) return true } else { return false } } function readSpreadsheet(key, title, SHEET){ var currentTitle = '' var ROWS = SHEET.getDataRange() var VALUES = ROWS.getValues() var ROWNUM = VALUES.length var COLNUM = VALUES[0].length var updateCol = ALPHABET[COLNUM] if (ROWNUM!=1){ for (var i=0; i<=COLNUM; i++){ var colNum = ALPHABET[i]+'2' var keyCol = ALPHABET[i]+'1' var col = SHEET.getRange(keyCol).getValue() if (col==key){ currentTitle = SHEET.getRange(colNum).getValue() updateCol = colNum } } } else { var updateCol = 'A2' } return [updateCol[0], currentTitle.toString().replace(/^\s+/,"").toString().replace(/\s+$/,"")] } function UpdateSpreadsheet(col, key, title, SHEET){ SHEET.getRange(col+'1').setValue(key) SHEET.getRange(col+'2').setValue(title) } function makeAttachment(name, link, title, color, image){ return [{ 'color': color, 'title': title, 'image_url': image, }] } function sendSlack(attachments, key, link, SLACK_INCOMING_URL) { var jsonData = { username: '日向坂ブログbot', icon_emoji: ':日向坂アイコン:', channel: '日向坂ブログ', text: 'アップデート情報です \n'+key+'さんがブログを更新しました。\n'+link, attachments: attachments, } payload = JSON.stringify(jsonData) options = { "method" : "post", "contentType" : "application/json", "payload" : payload } UrlFetchApp.fetch(SLACK_INCOMING_URL, options) |
コードの最後のここはよしなに変えてください。
- user_name: 通知時に表示されるbotの名前
- icon_emoji: 通知のアイコにしたいSlackに登録している絵文字
- channel: Slackのチャンネル名
- text: 通知時のテキスト文 (デフォルトだと、key にはスプシにかいた名前が入ります)
1 2 3 4 5 6 7 8 | function sendSlack(attachments, key, link, SLACK_INCOMING_URL) { var jsonData = { username: '日向坂ブログbot', icon_emoji: ':日向坂アイコン:', channel: '日向坂ブログ', text: 'アップデート情報です \n'+key+'さんがブログを更新しました。\n'+link, attachments: attachments, } |
シート名を変えている場合は、コードの一番はじめのシート名を変えてください。(SHEET_NAME, MEMBER_SHEET_NAME)
トリガーの設定
続いて、上のメニューのところにある時計マークを選びます。
「ファイル」「編集」などのメニューがある一段下のところの、「関数を選択」の左側にあります。
ページが切り替わったら、右下の「トリガーを追加」を選択します。
- 関数: main(デフォルト)
- 実行するデプロイを選択: Head(デフォルト)
- イベントのソースを選択: 時間主導型
- 時間ベースのトリガーのタイプを選択: 分ベースのタイマー (好きなように)
- 時間の間隔を選択(時間): 30分おき (好きなように)
- エラー通知設定: 毎日通知を受け取る (好きなように)
設定ができたら保存します。
これで今後自動的に動くとは思うのですが、念のためテストしましょう。
デバックする
コードを張り付けた画面に戻ります。
上の「関数を選択」のところを「main」にして、その左の虫のボタンを押してください。
コードが走り、Slackに通知が行くと思います。
途中で赤文字が画面上部に表示されたり、Slackに通知されなかった場合はなんらかの作業漏れがあったり、ミスが考えられるので、手順を見直してみてください。
それでも直らない場合は一旦最初から新しくやってみて、それでも直らない場合はコメントください。
問題がなければ、トリガーで設定した間隔で更新がないか確認しにいき、更新があれば通知してくれるはず!
コードの説明
気が向いたらいつか書きます。三十路になったらやるかも。
参考にさせていただいたサイト
Slackにスプレッドシートの変更がある度に内容を通知する方法 | Business Chat Master(ビジネスチャットマスター)