ゆるおたノート

Tomorrow is another day.

【Google Apps Script × Slack】歌詞Botを作ってみた

GASを触り始めると、成果がすぐ出るので楽しい毎日です。
あとは時限トリガーとSlackなどのチャットツールさえあれば、私の代わりに毎日自動かつ正確に*1働いてくれます。しめしめ。

私もこれくらい優秀な仕事人になりたかったけど、来世までは無理そう(遠い目)なので地道に自動化の術を学んで行きたいと思います。

そんなわけで本日は、毎度おなじみ隣IT様の「名言bot」を参考に「歌詞bot Slack ver.」を作ってみました。

本日のテーマ

Google Apps Scriptでチャットワークの名言botを作る方法

準備

Spreadsheet

こんな感じ↓の表を作成します。

スマホ等の小さめの画面では以下の表が見難いことがあります。 その場合は、恐れ入りますがPC等で改めて内容をご確認いただければと思います…
<2019/05/24追記>
画像に差し替えました。クリックorタップで拡大します。

Phraseシートの画像

「歌詞Bot」とは言うものの、今のところ「歌詞」と「好きな詩・ことば」を混ぜた表です。
作成するメッセージはG列のisSong?TRUE/FALSEで判定しています。

コード

V8に対応しました。

<2020/03/09追記>
2020年2月に公開されたV8ランタイム用の文法(いわゆるES6)に対応しました。

GitHub - yuricks7/GAS_Slack_KindWordsBot_V8: This repo is written for V8 Runtime of Google Apps Script.

動作は以下のコードと同じで、新キーワードへの置き換えと少々のリファクタリングのみ行っています。
よかったらこちらも合わせてご参照ください。

Slackクラス

SlackAppライブラリ(詳しくはこちら)を導入している前提の内容です。

コンストラク
/**
 * 投稿先の設定
 * ※あらかじめ使用するプロジェクトにSlackAppライブラリを導入しておくこと!
 *
 * @param {string} 投稿先のチャンネル名
 * @param {string} 投稿に表示するユーザー名
 */
var Slack = function(channelName, displayUserName) {
  this.channelName     = channelName;
  this.displayUserName = displayUserName;
}
メソッド

今のところpostメソッドだけですが、おいおい他のメソッドも追加していきます(たぶん)。

/**
 * メッセージをSlackに投稿する
 *
 * @param {string} 作成したSlackメッセージ
 */
Slack.prototype.post = function(message) {
  if (!message) {
    var message = '「メッセージが空欄」でーす';
  }
  
  var accessToken = PropertiesService
    .getScriptProperties().getProperty('SLACK_ACCESS_TOKEN');

 //SlackAppインスタンスの取得
  var slackApp = SlackApp.create(accessToken);

  slackApp.postMessage(
    this.channelName,
    message,
    {username: this.displayUserName}
  );
};

メイン・スクリプト

メイン

var targetRow~の部分で、2行目から最終行までの範囲からランダムに送信行を選択します。
こちらは元コードから拝借しました。

/**
 * 「'Phrase'」シートに入力した言葉をランダムでSlackに送信する
 */
function SendKindWordsBot() {
  var ss          = SpreadsheetApp.getActiveSpreadsheet();  
  var phraseSheet = ss.getSheetByName('Phrase');
  
  const FIRST_DATA_ROW = 2;
  var   lastRow        = phraseSheet.getLastRow(); 
  
  var targetRow = Math.floor(Math.random() * (lastRow - 1) + FIRST_DATA_ROW);
  var values = phraseSheet.getRange(targetRow, 1, 1, 10).getValues();
  
  var message = createLyricMessage(values[0]);

  var SlackBot = new Slack('00_kind-words-bot', '優しいことばBot');  
  SlackBot.post(message);
}
メッセージを作成

歌詞じゃないフレーズの場合は「作・編曲者」等の文言は要らないので、表のG列の値をもとに作成する内容を変えます。

/**
 * 行データから送信するメッセージを作成する
 *
 * @param {array} 送信対象の行データ
 * @return {string} 作成したメッセージ
 */
var createLyricMessage = function(rowValues) {  
  const BR = '\n';
  var   m  = '';
  if (rowValues[6] === true) {
    m = 'お元気ですか?' + BR
    m += 'ちょっとこれ読んで休憩しましょ!:shushing_face:' + BR
    m += '```' + BR
    m += rowValues[0] + BR
    m += '```'+ BR
    m += rowValues[1] + ' - ' + rowValues[2] + BR
    m += '>>> '
    m += '作詞:' + rowValues[3] + BR
    m += '作曲:' + rowValues[4] + BR
    m += '編曲:' + rowValues[5] + BR
    m += BR
    m += '▼Youtube' + BR
    m += rowValues[7];

    return m;
  }

  m = 'お元気ですか?' + BR;
  m += 'ちょっとこれ読んで休憩しましょ!:shushing_face:' + BR;
  m += '```' + BR;
  m += rowValues[0] + BR;
  m += '```'+ BR;
  m += rowValues[1] + ' - ' + rowValues[2] + BR;
  m += '>>> ';
  m += '執筆:' + rowValues[3] + BR;
  m += BR;
  m += '▼参考URL' + BR;
  m += rowValues[9];

  return m;
};

'```''>>> 'の部分については、詳しくは後述します。

トリガー

今のところは、トリガーの設定画面から時限トリガーで30分ごとにしています。

実行する関数 SendKindWordsBot
デプロイ時に実行 Header
イベントのソース 時間主導型
時間ベースのトリガー 分ベースのタイマー
時間の間隔 30分おき*2
エラー通知設定 1週間おき


余裕ができたら、トリガー用のスクリプト(苦手)を作ってポモドーロ・テクニック的に25分ごとにしたいところ…

送信サンプル

post後のサンプル

Slack記法

一部無いものもありますが、ほぼMarkdownと同じように使うことが出来ます*3

```で文章を挟むことで、歌詞の部分がコードブロック扱いになって若干強調されます。
画像では、「少しだけ 少しだけ~」から「愛してくれよ 許しておくれよ」の部分。

また、文頭に>を付けると1文だけ引用符(グレーの棒の部分)が、>>>と付けると段落まるごと引用符が、それぞれ付きます。
画像では、「作詞」からYoutubeのURLの部分まで、後者を使っています。

個人的には、引用文であってもコードブロックを使ったほうが読みやすくなるので好きです。
等幅フォントになるので、英数字ならさらに桁揃えもしやすくなってレポート等にも良いですしおすし…

【おまけ】Slackの設定変更のすすめ

さて、1つの投稿に複数のURLが含まれる場合は、サムネイルやURLの展開が見た目にややうるさく感じることもあるかと思います。

そんなときは、受信者側の設定(Preferences)で展開をOffにしてみることもオススメです。
以下、PCからの場合を例にして、簡単に手順をご説明します。

画面左上のワークスペース名のあたりをクリック

ワークスペース名をクリック

環境設定を開く

環境設定を開く

「メッセージ&メディア」タブを選択

「メッセージ&メディア」タブを選択

インライン表示をOffにする

下の方に少しスクロールして、「メディア&リンクのインライン表示」の項目で状況に合わせてチェックを外すと、精神衛生上良いと思います。
「インライン表示」のチェックを外す

おすすめ設定
  • 下3つのチェックを外す

    • いろんな投稿にWebサイトやYoutube「リンクが混ざって読みづらい!」という場合

    • Slackではとりあえずザッと目を通すだけにして、「詳細は自分で見に行きたい!」という場合

  • 「2MB以上の~」だけチェックを外す

    • 通信量の削減等で重いデータだけ制限したい場合

※先ほどの送信サンプル画像では、1番下だけ外した状態で撮影しています。

参照

書籍

クラスとインスタンス化が出来るようになる*4とグッと楽しくなりますね。

注釈

*1:もちろん、私の指示が適切であればの話ですが…

*2:ほぼ29分台に届いてるので、時報代わりになりました!

*3:つまり、はてなブログMarkdown記法に統一しちゃえば学習コストが削減できます。笑

*4:本当に出来ているかって?それは、また別のお話…(cv. 森本●オ)