バイセル Tech Blog

バイセル Tech Blogは株式会社BuySell Technologiesのエンジニア達が知見・発見を共有する技術ブログです。

バイセル Tech Blog

SlackボットとGASで癒しを提供する話

こちらは バイセルテクノロジーズ Advent Calendar 2021 の10日目の記事です。
前日の記事は小松山さんの Hasura でプロダクト開発をしてみて感じた良かったところ・辛かったところ でした。

はじめに

こんにちは。21新卒で開発1部に所属しています鈴木です。
普段は弊社の在庫管理システム「AXIS」にプロジェクトリーダー兼プログラマーとして参画しています。
tech.buysell-technologies.com

突然ですが、みなさんラッコはお好きでしょうか?
手を繋いで寝ていたり、冷えた手を温めているラッコはとても可愛いですよね!
弊社ではそんなラッコの画像を定期的に共有し合うSlackチャンネルが存在するのですが、全て手作業で行なっていると流石に面倒になってしまいます。。。😅

というわけで、 今回はGASことGoogle Apps ScriptとSlack Appを使って、定期的に画像を投稿してくれるSlackボットを作ったので紹介していきたいと思います!

事前準備

GASのプロジェクトファイルとSlack Appを事前に用意します。

GASはGoogle Driveの[新規]から作成することができるので、作っておきましょう。

Slack Appに関しては、今回は社内ですでに使用されているものが存在するためそちらを流用します。

もし新規でSlack Appを作成する場合はこちらのページから [Create New App] ボタンより作成することができます。

また、画像などのファルをアップロードするためにはfiles:write権限が必要なので事前に設定しておきましょう。
Your Apps画面から使用するAppを選択し、サイドバーの[OAuth & Permissions]から[Scopes]項目の[Add an OAuth Scope]ボタンを押下することで設定できます。

大まかな流れ

今回想定しているアップロードまでの流れとしては以下の通りです。

  1. Google Drive内にてラッコの画像が保存されているフォルダからランダムに画像を選出する
  2. 選ばれた画像ファイルを指定した時間に特定のSlackチャンネルへアップロードする

それぞれ順を追って説明します。

Google Driveから画像ファイルを取得

フォルダーから画像を取得する

GASでは以下の一行でフォルダーを取得することができます。

var folder = DriveApp.getFolderById("<フォルダーのID>");

ここからフォルダー内のファイルを取得するには以下のように記述します。

var files = folder.getFiles();
while(files.hasNext()) {
  var file = files.next();

  ~ファイルに対して何かしらの操作~

}

これで画像ファイルを取得することができました。

ランダムに画像を選出する

GASでは以下の記述で0~1の疑似乱数を生成することができます。

Math.random()

フォルダ内の総ファイル数をnとして、以下のように記述すれば0~nのランダムな整数が取得できます。

Math.floor( Math.random() * n)

これを利用すればランダムに画像を選出できそうですね。

余談ですが、s~eの疑似乱数が生成したい場合は以下のように記述すれば生成することができます。

Math.floor( Math.random() * (e - s) + s)

先程の式を利用して画像をランダムに選出すると以下のようになります。

function getRandomImage(){
  var folder = DriveApp.getFolderById("<フォルダーのID>");
  var files = folder.getFiles();
  var n = 10; // n はフォルダ内の総ファイル数
  var i = 0;
  var target = Math.floor( Math.random() * n);
  while(files.hasNext()) {
    var file = files.next();
    if(i == target){
      return file
    }
    i++;
  }
  return null;
}

これで画像ファイルの取得に関しては完了です。
この書き方だと、もし目的のファイルが見つからなかった時nullを返すようになっています。
nullでは困るようであれば任意の画像を返すようにしてもいいかもしれません。

Slackへ定期アップロード

Slackチャンネルへ画像をアプロード

Slack APIの公式ドキュメントをもとにリクエスト処理を実装します。
以下で定義されている引数のfileは先程の章で返り値として定義されているfileと同じオブジェクトが定義されているものとします。

fuction uploadFile(file) {
  var options = {
    "payload": {
      token:"<Slack Appのtoken>",
      as_user: true,
      file: file.getBlob(),
      filename: file.getName(),
      channels:"<アップロードしたいSlackチャンネルのID>",
    }
  }
  var result = UrlFetchApp.fetch("https://slack.com/api/files.upload", options);
  Logger.log(result);
}

これにて実装は終了です。

トリガーを設定

最後にGASのトリガーを設定します。 エディタ画面のサイドバーにある[トリガー]からトリガーの設定画面に移動します。

右下に表示される[トリガーを追加]ボタンから任意の設定のトリガーを追加します。
今回は「毎日午後5時~6時の間に実行」という内容で設定しました。

保存したら完了です。

まとめ

今回の内容はラッコの画像に限らず、さまざまなファイルに応用できるかと思います。
ぜひ試してみてください!

最後にバイセルではエンジニアを募集しています。

少しでも興味のある方はぜひご連絡ください!

herp.careers

明日のバイセルテクノロジーズ Advent Calendar 2021 は飯間さんから「Redis Pub/Sub でお手軽にお知らせ配信機能を実装する」です。
そちらもぜひ併せて読んでみてください!