GASとSlackではじめるチャットボット〜初心者プログラマ向け〜

## はじめに

[チャットボット Advent Calendar](http://qiita.com/advent-calendar/2016/chatbot)7日目の @yukihirai0505 です!
6日目は同僚の @kashira2339 が実際に僕もお世話になってるbotについて記事にしてます。笑

[[GitHub API & Webhook + hubot]社内で実際にいい反響を得ているチャットボットの機能](http://qiita.com/kashira2339/items/26f97809673acf99e2b4)

ちなみに、自分は何気に初めてのAdvent Calendarです。笑

今回の記事の内容はチャットボットというよりは、チャットボットを通してプログラミングを学んでいけるような内容にします。
また、さらに言えばプログミングを学ぶというよりライブラリの使い方を学ぶ、みたいな内容になってますが悪しからず。笑

今回は手軽に実装できるGoogleAppsScriptでSlack向けのbotを作成していきます。
詳しい手順については下記の記事を参考にしてみてください。

=> [初心者がGASでSlack Botをつくってみた](http://tech.camph.net/slack-bot-with-gas/)

## Google Apps Scriptの起動

まずはSlackの設定とプログラムを記述するための準備をしていくためGoogleAppsScriptを起動します。

Moreの中にGoogle Apps Scriptがない場合は `Connect more apps` で `script` と検索して追加してあげましょう。

![Screen Shot 2016-12-05 at 16.10.28.png](https://qiita-image-store.s3.amazonaws.com/0/45536/d3e27f6e-02db-365d-cb3a-32a0841a8624.png "Screen Shot 2016-12-05 at 16.10.28.png")

`script` で検索すると出てくるので `Connect` ボタンを押して追加できます。

![Screen Shot 2016-12-05 at 16.10.39.png](https://qiita-image-store.s3.amazonaws.com/0/45536/9e7be0e9-3cf0-a91d-011d-b85aacd64037.png "Screen Shot 2016-12-05 at 16.10.39.png")

追加すると、次からはちゃんと選択肢に表示されます。

![Screen Shot 2016-12-05 at 16.10.58.png](https://qiita-image-store.s3.amazonaws.com/0/45536/de66ec80-6fe9-4453-f3b6-0dbed037a7fb.png "Screen Shot 2016-12-05 at 16.10.58.png")

## Salckの設定

次にGASが起動できたらResourcesのlibrariesからSlackを追加してあげましょう。

SlackAppのLibrary Key => `M3W5Ut3Q39AaIwLquryEPMwV62A3znfOO`

![Screen Shot 2016-12-05 at 16.15.30.png](https://qiita-image-store.s3.amazonaws.com/0/45536/144e2b33-c411-6abe-7799-bd2d5ea7d0f1.png "Screen Shot 2016-12-05 at 16.15.30.png")

今回はライブラリのver 22を使用していきます。

Slackのアクセストークンは下記から取得しておきましょう。

https://api.slack.com/web

追記: レガシーなトークンはこちらになった模様 => https://api.slack.com/custom-integrations/legacy-tokens

legacy tokens は今後使われなくなるため
Slack Appを作成して
パーミッションを設定し、アプリをインストールするとトークンが発行されるようになります
こちらを使用するようにしましょう

<img width="662" alt="スクリーンショット 2019-03-08 12.21.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/45536/48c0146b-5aaa-3579-7ac8-ca0a642bdc24.png">

https://get.slack.help/hc/en-us/articles/215770388-Create-and-regenerate-API-tokens

## いざプログラムの実行

やっと目的のプログラミングまでやってきました。

Slackの任意のチャンネルに投稿するプログラムを書いてみます。

```gas:Code.gas
var slackAccessToken = 'ここにアクセストークンを記載';
function test() {
  var slackApp = SlackApp.create(slackAccessToken);
  // 対象チャンネル
  var channelId = "#general";
  // 投稿するメッセージ
  var message = "I'm bot";
  var options = {
    // 投稿するユーザーの名前
    username: "hirai_yuki"
  }
  slackApp.postMessage(channelId, message, options);
}
```

これで作成した `test` を指定して実行ボタンを押せばSlackに投稿されます。

![Screen Shot 2016-12-05 at 17.53.39.png](https://qiita-image-store.s3.amazonaws.com/0/45536/27b24fdf-5588-4206-33b7-9da47bb943e4.png "Screen Shot 2016-12-05 at 17.53.39.png")





## 作成したプログラムの中身の説明

今回はGASからSlackに投稿するというプログラムでしたが、実際にはSlackのOutGoingを使用してSlackでの会話をキーに反応するようなボットも作成できるので
やってみたい方は試してみてください。

=> [初心者がGASでSlack Botをつくってみた](http://tech.camph.net/slack-bot-with-gas/)

では、ここからはプログラミング学習の手順について記載していきます。

## プログラミング学習の手順

今回は `SlackAPP` というライブラリを使用していますが、
こういったライブラリを使用する際はまずドキュメントを見るようにします。

=> [SlackApp (version 22)](https://script.google.com/macros/library/d/M3W5Ut3Q39AaIwLquryEPMwV62A3znfOO/22)

そして今回使用しているプログラムをもう一度みてみます。

```gas:Code.gas
var slackAccessToken = 'ここにアクセストークンを記載';
  var slackApp = SlackApp.create(slackAccessToken);
  // 対象チャンネル
  var channelId = "#general";
  // 投稿するメッセージ
  var message = "I'm bot";
  var options = {
    // 投稿するユーザーの名前
    username: "hirai_yuki"
  }
  slackApp.postMessage(channelId, message, options);
```

みてみると今回は

- `create`
- `postMessage`

というSlackAppのメソッドを使用しているのがわかります。

なのでこのcreateとpostMessageのドキュメントをそれぞれみてみましょう。

### create

中身をみて見ると `token` を渡せば API Clientが返ってくるというのがわかりますね。

![Screen Shot 2016-12-05 at 16.41.55.png](https://qiita-image-store.s3.amazonaws.com/0/45536/8e2c1111-3d71-87a6-0c52-650a7f1a97d1.png "Screen Shot 2016-12-05 at 16.41.55.png")

### postMessage

こちらをみて見ると
チャンネルと投稿内容とオプションを指定すればSlackに投稿してくれるということがわかります。

![Screen Shot 2016-12-05 at 16.42.54.png](https://qiita-image-store.s3.amazonaws.com/0/45536/4aaead9e-ec78-7119-e4b7-5c15a6a33d22.png "Screen Shot 2016-12-05 at 16.42.54.png")

さらにオプションに関しては

https://api.slack.com/methods/chat.postMessage

を参照してねとあります。

リンクをみて見ると
それぞれのArgumentに関してRequiredとOptionalの2種類に分かれています。

*Required*

![Screen Shot 2016-12-05 at 16.45.15.png](https://qiita-image-store.s3.amazonaws.com/0/45536/04296fd4-f2ff-3a46-c2ed-dda37a33cb5d.png "Screen Shot 2016-12-05 at 16.45.15.png")

*Optional*

![Screen Shot 2016-12-05 at 16.45.06.png](https://qiita-image-store.s3.amazonaws.com/0/45536/0c332c4e-02bb-b3bf-fe87-2638b6c2fc47.png "Screen Shot 2016-12-05 at 16.45.06.png")


postMessageの第三引数はここでいうOptionalの部分を渡してあげることができるということがわかりますね。

では実際に第三引数のオブジェクトに `as_user` というプロパティがあるので `true` で設定してみましょう。

![Screen Shot 2016-12-05 at 16.53.48.png](https://qiita-image-store.s3.amazonaws.com/0/45536/6fb3eb7b-19ec-3135-fe47-38d272cb52ba.png "Screen Shot 2016-12-05 at 16.53.48.png")


```gas:Code.gas
var slackAccessToken = 'ここにアクセストークンを記載';
function test() {
  var slackApp = SlackApp.create(slackAccessToken);
  // 対象チャンネル
  var channelId = "#dev_company_system";
  // 投稿するメッセージ
  var message = "I'm bot";
  var options = {
    as_user: true
  };
  slackApp.postMessage(channelId, message, options);
}
```

そうすると今度はbotとしてではなくSlackのAPIトークンを作成したユーザーとして投稿されます。

![Screen Shot 2016-12-05 at 16.49.55.png](https://qiita-image-store.s3.amazonaws.com/0/45536/351e855a-ddfe-b8fa-f92d-32d826dea48d.png "Screen Shot 2016-12-05 at 16.49.55.png")

このようにライブラリを見ればその中身が理解できてさらに応用もできるようになります。

もう少し深くみていくとこちらのコードも勉強になります。

https://github.com/soundTricker/SlackApp/blob/master/src/Code.coffee

このライブラリで使用されているコードの中身ですね。
こちらはCoffeeScriptで記述されてます。

Jsのコードはこちらですね。

https://github.com/soundTricker/SlackApp/blob/master/bin/Code.gs

今回はCoffeeの方を見てみましょう。

```Code.coffee
/**
 * Create an Slack API Client 
 * @param {String} token API Token via https://api.slack.com/tokens
 * @return {SlackApp} return an Slack API Client 
 */
function create(token){
  return new SlackApp(null, null, null, null, {token : token});
}
```

となってます。
`SlackApp` というインスタンスを返してますね。

さらに `postMessage` をみてみます。

https://github.com/soundTricker/SlackApp/blob/master/src/Code.coffee

```Code.coffee
        chatPostMessage : (channelId, text , option={})=>
            @fetch_("chat.postMessage", _.extend({channel : channelId, text : text}, option))

        postMessage : (channelId, text , option={})=>
            @chatPostMessage(channelId, text , option)
```

これをみて見ると `postMessage` ではなく `chatPostMessage` メソッドでも投稿できることがわかります。
というか本来は `chatPostMessage` があってエイリアスで `postMessage` が設定されてるのがわかります。

実際に試してみましょう。

```gas:Code.gas
var slackAccessToken = 'hogehoge';
function test() {
  var slackApp = SlackApp.create(slackAccessToken);
  // 対象チャンネル
  var channelId = "#dev_company_system";
  // 投稿するメッセージ
  var message = "I'm bot";
  var options = {
    icon_url: "https://avatars0.githubusercontent.com/u/7392701?v=3&s=400",
    username: 'sasaki_taka'
  };
  slackApp.chatPostMessage(channelId, message, options);
}
```



## 最後に

まずはドキュメントを読む、
そして余裕があればコードも読んで見るとプログラミングの理解にもつながっていきます。
こうしてドキュメントを読み進めてコードを理解することで、
例えば、Slackに参加している他のユーザーになりすますなんていうこともできます。
`BOT` という表示がつくので完全になりすますことはできませんが。笑

```gas:Code.gas
var slackAccessToken = 'hogehoge';
function test() {
  var slackApp = SlackApp.create(slackAccessToken);
  // 対象チャンネル
  var channelId = "#dev_company_system";
  // 投稿するメッセージ
  var message = "@sasaki_taka え。。。";
  var options = {
    // botのアイコン画像リンク
    icon_url: "https://avatars0.githubusercontent.com/u/7392701?v=3&s=400",
    // メンションしたとき @sasaki_taka が文字列ではなくリンクになるように設定
    link_names: 1,
    // botのユーザー名
    username: 'sasaki_taka'
  };
  slackApp.chatPostMessage(channelId, message, options);
}
```

![Screen Shot 2016-12-05 at 17.25.32.png](https://qiita-image-store.s3.amazonaws.com/0/45536/919f381d-804e-d580-893d-eef8b066b7aa.png "Screen Shot 2016-12-05 at 17.25.32.png")


こういう遊び心もボットの醍醐味ですよね。
プログラミングを通じて楽しい体験をつむことは、
プログラミングの上達にもつながっていくと思います。
ぜひ初心者の方もチャットボットを通じてプログラミングに触れてみてください^^