AWS LambdaとPythonでスラッシュコマンドで入力した文字をそのまま返すSlackBotを作成する

# はじめに
SlackBotを作る記事はいくつかあったのですが、記事が少し古かったり、複雑な記事が多かったため、シンプルに`/hoge`で入力した内容をそのまま返すSlackBotを作成します。Slackで匿名質問などをしたいときにも使えます。

# Slackの設定
## Botの設定
[SlackAPIのサイト](https://api.slack.com/apps/)から`Create New App`で新しいBotを作ります。
その後、OAuth&PermissionsのScopesでBot Token Scopesというところがあるので、`chat:write`と`chat:write.public`と`commands`をscopeに追加します。

次にBotの設定をします。
`Basic Information > Bots`をクリックして`App DisplayName`の設定とShow tabsの`Messages Tab`をONにするのと`Allow users to send Slash commands and messages from the messages tab`にチェックをしてください。

その後`install to Workspace`を選んでWorkspaceにBotをインストールしてください。
インストールした後に出てくるTokenが大事なので保管しておきましょう。見つからない場合は、`OAuth & Permissions`のタブをクリックして確認しましょう。
![スクリーンショット 2021-05-11 23.09.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514848/18239e70-e403-5008-410c-ef482bc02607.png)


## Botの設定の確認
Botの設定がうまく行っているかテストするには[こちらのサイト](https://api.slack.com/methods/chat.postMessage/test)の`token`と`channel`と`text`を埋めてSendしてみてください。うまくいけば指定したチャンネルに入力したテキストが出力されるはずです。

channelはchannel IDを入れる必要があるのですが、こちらはWeb版のSlackチャンネルで出てくるURLに書いてあるので確認してみてください。

# AWS側の設定
## AWS Lambdaの設定
AWSを開いて`Author from scratch`のBasic infomationを埋めてください。
今回はPython3.6を使いました。
![スクリーンショット 2021-05-11 22.54.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514848/b15f6d6b-2c0d-4dde-e336-8be5ac98da98.png)

## API Gatewayの設定
Lambdaの画面が出てきたら、`+Add trigger`を選択します。
![スクリーンショット 2021-05-11 22.57.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514848/106bfcdf-6d70-64e0-c90d-0078410e076f.png)

Trigger configurationの画面のトリガー選択から`API Gateway`を選択してください。
その後次のように埋めます。
![スクリーンショット 2021-05-11 21.33.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514848/06d7a347-20fa-140d-2943-4c9759893dcb.png)

できたあとは、こちらの画面のAPIエンドポイントにクリックしてアクセスしてみてください。`"Hello from Lambda!"`と出てきたら、API Gatewayの設定はうまくいってます。
![スクリーンショット 2021-05-11 22.59.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514848/51e955ff-d46e-9104-f538-d06984d06d69.png)



## AWS Lambdaのコード
次にAWS Lambdaのコードを修正しましょう。

```python:lambda_function.py
import urllib
import urllib.request
import base64

def send_text_response(event, response_text):
    SLACK_URL = "https://slack.com/api/chat.postMessage"
    channel_id = "<チャンネルIDを入力>"
    data = urllib.parse.urlencode(
        (
            ("token", "xoxb-...<Bot User OAuth Tokenを入力>"),
            ("channel", channel_id),
            ("text", response_text)
        )
    )
    data = data.encode("ascii")
    
    request = urllib.request.Request(SLACK_URL, data=data, method="POST")
    request.add_header( "Content-Type", "application/x-www-form-urlencoded" )
    
    urllib.request.urlopen(request).read()
    
def lambda_handler(event, context):
    print(f"Received event:\n{event}\nWith context:\n{context}")
    # Bodyのbase64をデコードしてstr型にする
    body = base64.b64decode(event.get("body").encode()).decode()
    # BodyをDict型にparseする 
    qs_d = urllib.parse.parse_qs(body)

    # parse_qsのdict型のvalueは配列で持っているため0番目を選択する
    response_text = qs_d["text"][0]
    send_text_response(event, response_text)
    
    # レスポンスをSlackbotが返す(なんでも良い)
    return "200 OK"
```
多分Pythonの書き方はもっといい書き方があると思うのですが、こちらでとりあえず動きます。


リクエストのログや出力などは[CloudWatchコンソール]
(https://console.aws.amazon.com/cloudwatch/)の`Logs > log groups`で見ることができます。
デバッグするときに使ってみてください。


## スラッシュコマンドの設定とAWSとの接続
スラッシュコマンドでBotが動くようにするためには、slack apiの左タブの`Slash Commands`を選択します。
Commandには実行時に使いたいコマンド、RequestURLにはAPI Gatewayで設定したAPI endpointのURLを入力してください。
![スクリーンショット 2021-05-11 23.13.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514848/f47326df-434f-33e7-d891-ab713b49ca24.png)

以上で完成です。
Slackで`/hoge "Botに話させたい文字列"`を入力してあげればBotが返してくれます。

# 参考
こちらをかなり参考にしました。(英語)
https://medium.com/glasswall-engineering/how-to-create-a-slack-bot-using-aws-lambda-in-1-hour-1dbc1b6f021c
Node.jsで同様のものを作成しています。Requireの設定がうまく行かなかったため断念しました。
https://www.cview.co.jp/osakatech/2020.02.06.eSBhZVxH