Slackに追加されたカスタム絵文字を通知するBOTを作った

今年もAdvent Calendarに参加します！
この記事は[ニフティグループ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/nifty)の4日目です。
社会人3年目。このご時世のせいか、今年が一番早く時間過ぎた気がします。

昨日は @yasu_m_0123 さんの[ITエンジニアがMBAを取るとどうなるのかという話](https://qiita.com/yasu_m_0123/items/1af1903e9d5c9f3b226c)でした。
私は社会人大学院という存在をあまり意識していなかったので、どんなものなのか、どんな雰囲気なのか知ることができました。
# Slackの絵文字は好きですか？

私は好きでよく使っています。:innocent:
手軽にコミュニケーションが取れるのがいいですよね。

特にカスタム絵文字が好きです。汎用性の高いものから、面白いものまでいろいろありますよね。

ちなみに現時点(2021/12/03)での、弊社のカスタム絵文字の数は
**約2500個以上** ありました。
多いのかな、少ないのかな:thinking:

新しい絵文字が追加されるのを楽しみにしていますが、
さすがにこの絵文字数になると、せっかくいい絵文字が追加されても気づけないんですよね。

ということで、新しく追加されたカスタム絵文字を通知するBOTをGASで作りました。

# 追加されたカスタム絵文字を通知するBOT

こんな感じです:innocent:
<font color="Gray">（やばい絵文字映ってないよな:thinking:）</font>

多い日だと、にぎやかになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533977/eec7abe4-1f60-8ee9-f14b-f8f6f7db8364.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533977/ccb6c458-08c3-c95b-e5df-5c7adb597887.png)

当然1個のときも。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533977/61e7e717-a96e-c0be-0362-a960cd9fbf9a.png)

追加されてない日はランダムで1個通知してます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533977/4de12922-5756-03af-2e07-2dbe1e8bd02b.png)


## 構成

GASで実行します。
SlackAPIでカスタム絵文字を全て取得して、Google Driveに保存し、
前日とのファイルの差分をみてSlackに通知します。
GASのトリガーで毎朝実行してます。出社時の楽しみです。

今回使うSlackAPIはカスタム絵文字の一覧を取得するという、マニアックなAPIです。
<font color="Gray">（社内で他に使ってる人いるのかな:thinking:）</font>

申請やスコープの設定などが必要です。
https://api.slack.com/methods/emoji.list 


## ソース
4箇所TODOがあるので、各自の値に書き換えてください。

フォルダーIDは絵文字一覧ファイルを保存するGoogle Drive上のフォルダーで、
```https://drive.google.com/drive/folders/ここの値```
を入れてください。

通知用のWebhookURLとSlackAPIのTokenは各自で用意してください。

```javascript
function myFunction() {
  // ①古い絵文字old_stamp.jsonを削除
  // 保存フォルダID設定
  const folder_id = "";//TODO①絵文字一覧を保存するフォルダーID
  const file_name = 'emoji.json'
  const old_file_name = 'old_emoji.json'
  removeFile_(old_file_name, folder_id)
  // ②emoji.jsonをold_emoji.jsonにファイル名を変更
  const folder   = DriveApp.getFolderById(folder_id);
  const files    = folder.getFiles();
  while (files.hasNext()) {
    const file   = files.next();
    const name   = file.getName().replace('emoji', 'old_emoji');
    file.setName(name);
  }
  // ③新しい絵文字一覧emoji.jsonを取得
  exportJson(file_name, folder_id)
  // ④差分確認
  const emoji_json =getDataFromMyTextFile(file_name, folder_id)
  const emoji_list = Object.keys(emoji_json.emoji)

  const old_emoji_json = getOldDataFromMyTextFile(old_file_name, folder_id)
  const old_emoji_list = Object.keys(old_emoji_json.emoji)

  // 差分を出す
  let result = emoji_list.filter(itemA =>
    // 配列Bに存在しない要素が返る
    old_emoji_list.indexOf(itemA) == -1
  );
  let message = ''
  let username = ''
  let icon = ''

  // 差分を通知、なければランダムに1個通知
  if (result.length) {
    username = '新しい仲間が加わったよ'
    icon = ':hatching_chick:';
    for (const emoji of result) {
      message += ':' + emoji + ':';
    }
  }else {
    username = '今日の絵文字';
    icon = ':smile:';
    const emoji = emoji_list[Math.floor(Math.random() * emoji_list.length)]
    message = ':' + emoji +':';
  }

// ⑤送信
　const postUrl = '';//TODO②Slack通知用URL
  const channel = '';//TODO③通知先チャンネル
  const jsonData =
  {
     "username" : username,
     "icon_emoji": icon,
     "channel": channel,
     "text" : message
  };
  const payload = JSON.stringify(jsonData);

  const options =
  {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : payload
  };
  // 通知
  UrlFetchApp.fetch(postUrl, options);
}

// 新しいjsonファイル
function getDataFromMyTextFile(file_name, folder_id) {
  const contents = DriveApp.getFolderById(folder_id)
  .getFilesByName(file_name)
  .next()
  .getBlob()
  .getDataAsString("utf-8")
  .replace(/\r?\n/g, ''); //改行削除

  return JSON.parse(contents);
}

// 古いjsonファイル
function getOldDataFromMyTextFile(old_file_name,folder_id) {
  const contents = DriveApp.getFolderById(folder_id)
  .getFilesByName(old_file_name)
  .next()
  .getBlob()
  .getDataAsString("utf-8")
  .replace(/\r?\n/g, ''); //改行削除

  return JSON.parse(contents);
}

// 既存ファイルを削除
function removeFile_(file_name, folder_id) {
  const folder = DriveApp.getFolderById(folder_id)
  //DriveAppクラスからファイル名でファイル(ファイル名一致した分)を取得する
  const fileData = folder.getFilesByName(file_name);
  //next()でファイルを取得し、ゴミ箱のフラグをtrueにする
  const getData = fileData.next().setTrashed(true);
}

// emoji.json取得
// JSONファイルをエクスポート
function exportJson(file_name, folder_id) {
  // Slack APIで絵文字取得
  const url = 'https://slack.com/api/emoji.list?token=hogehoge'//TODO④SlackAPIのURL
  const options = {"method" : "GET"}
  const response = UrlFetchApp.fetch(url, options);
  // ファイル作成
  makeFile_(response, file_name, folder_id)
}

// ファイル作成
function makeFile_(jsonData, file_name, folder_id) {
  const contentType = "text/plain";
  const charSet = "UTF-8";
  //blobに変換して、データをsetする。
  const blob = Utilities.newBlob("", contentType, file_name).setDataFromString(jsonData, charSet); 
  DriveApp.getFolderById(folder_id).createFile(blob)
}

```


# まとめ

GASとGoogle Driveでお手軽にBOT作れました。
面白い絵文字があると、話のネタにもなるので気になる方はBOT作ってみてください。
絵文字最高:hugging:

明日は @mh326 さんの記事です。楽しみですね。