ゆるおたノート

Tomorrow is another day.

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

GASを触り始めると、成果がすぐ出るので楽しい毎日です。

あとは、時限トリガーとSlackなどのチャットツールがあれば、私の代わりに毎日自動で正確に働いてくれます*1。しめしめ。

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

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

本日のテーマ

tonari-it.com

準備

Spreadsheet

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

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

Phraseシートの画像

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

コード

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分ごとにしています。

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


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

送信サンプル

post後のサンプル

Slack記法

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

```で文章を挟むことで、コードブロック化して若干強調されます。
↑では、「少しだけ」から「許しておくれよ」の部分。

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

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

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

さて、1つの投稿に複数のURLが含まれる場合は、サムネイルやURLの展開がややうるさく感じることもあるかと思います。
そんなときは、受信者側の設定(Preferences)で「展開Off」にしてみることもオススメです。

以下、PCからの場合を例にして、簡単に手順をご説明します。

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

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

環境設定を開く

環境設定を開く

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

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

お好みでインライン(本文中の)表示のチェックを外してOffにすると、精神衛生上良いと思います。

  • 「いろんな投稿にWebサイトやYoutubeリンクが混ざって読みづらい!」という場合
  • 「Slackではとりあえずザッと目を通すだけにして、詳細は自分で見に行きたい!」という場合
    下3つをOff

  • 通信量の削減等で重いデータだけ制限したい場合
    「2MB以上の~」だけOff

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

参照

書籍

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

注釈

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

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

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

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