SlackユーザとLINEユーザを繋げたい。

# SlackユーザとLINEユーザを繋げたい。
AさんのiPhoneは電話番号がない（格安simでデータ通信しかできない。）そして、Facebookもやっていない。LINEが使えないことに嘆いてたので、電話番号のいらないSlackでLINEの家族や友人とやりとりできるBOTを開発してみた。（需要はないと思う。）

# 今回使うライブラリなど
* Slack
    * Webhook 
    * bots
* LINE
    * LINE Notify
    * LineBotSdk
* Heroku
    * HerokuCLI


# 目標
LINEからSlackへ、SlackからLINEへ双方向でメッセージをやりとりする。

## ディレクトリ

```
├── LINE_to_Slack           #好きな名前で良い。
│   ├── Procfile            #デプロイに必要
│   ├── main.py             #本体
│   ├── requirements.txt　　 #デプロイに必要
│   └── runtime.txt　　　　　 #デプロイに必要
├── README.md
└── Slack_to_LINE            #好きな名前で良い。
    ├── Procfile　　　　　　　 #デプロイに必要
    ├── plugins　　　         # botの機能はこのディレクトリに追加する
    │   ├── __init__.py      # モジュールを示すためのファイル。空で良い
    │   └── line_mention.py  # 機能を書き込むファイル。任意の名前で良い
    ├── requirements.txt　　  #デプロイに必要
    ├── run.py               # このプログラムを実行することで、ボットを起動する
    ├── runtime.txt　　　　　  #デプロイに必要
    └── slackbot_settings.py　# botに関する設定を書くファイル
```

# SlackからLINEへ

まずは、SlackからLINEへということを考えたい。
PythonのslackbotライブラリでSlackボットを作りたい。[^1]

今回はSlackのbotsというappを使いたい。
まず、Slackに検索画面でbotsを検索する。
<img width="1162" alt=" 2.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/f27516b3-af67-c664-6c4e-02ec85c92167.png">
↓
<img width="1057" alt=" 1.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/5209c3fd-4415-9320-95a0-0f14089fb4e8.png">
既にbotsを使ったことがある方は設定を追加で、そうでなければ新規に登録する。

あとは手順に沿って必要項目を埋めていく。
あとで、APIトークンを使うのでコピーしておく。
<img width="1056" alt=" 3.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/e7c2f6da-b460-c0eb-5261-3d4201d74c08.png">
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3131303036302f35363239633932652d643533612d396564622d656439662d3636643166663736323765382e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/110060/91d7720b-3662-95c3-5118-5434a17abd7f.png)


botsの作業は以上。あとはPythonでコードを。

## slackbotのインストール
```$
$ sudo apt install python3-pip
$ sudo pip3 install slackbot
```
ディレクトリ構成は以下である。

```bash:Slack_to_LINE
└── Slack_to_LINE            #好きな名前で良い。
    ├── Procfile　　　　　　　 #デプロイに必要
    ├── plugins　　　         # botの機能はこのディレクトリに追加する
    │   ├── __init__.py      # モジュールを示すためのファイル。空で良い
    │   └── line_mention.py  # 機能を書き込むファイル。任意の名前で良い
    ├── requirements.txt　　  #デプロイに必要
    ├── run.py               # このプログラムを実行することで、ボットを起動する
    ├── runtime.txt　　　　　  #デプロイに必要
    └── slackbot_settings.py　# botに関する設定を書くファイル
```

このrun.pyはボットを起動する部分である。

```python:run.py
# coding: utf-8
from slackbot.bot import Bot
def main():
    bot = Bot()
    bot.run()
if __name__ == "__main__":
    main()
```
次にプラグインを書いていこう。
Slackからメッセージを受け取ったらLINE Notifyを使って送信したい。
##### ・LINE Notifyにアクセス
まずは、LINE Notifyにアクセスしてみた。↓
https://notify-bot.line.me/ja/
<img width="1149" alt=" 3.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/184915f0-64ef-5b92-18d9-e68f47c05da9.png">

ログインする。

<img width="710" alt=" 4.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/b94e86df-a8cf-ebac-4b5c-75edaaec3d6e.png">

ログインできたら、My pageへ移動。

<img width="626" alt=" 5.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/60f351c3-e268-81da-5dc7-7db7fdd8801a.png">

そして、Generate tokenをクリック。

<img width="949" alt=" 2.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/ee024821-06e1-f5bd-3f5d-f3c3eab7b661.png">

Access tokenを取得できたら、閉じる前にtokenをきちんとコピーしておくこと。
これでLINE Notifyを使う準備はできた。

使うには、curlなどを用いてやれば良い。[^2]


```sh:LineNotify

$ curl -X POST -H "Authorization: Bearer ここにアクセストークン" -F "message=${code}" https://notify-api.line.me/api/notify

```
slackbot_settings.pyの中身を以下のようにする。

```python:slackbot_setting.py
# coding: utf-8
import os
# トークンを指定
API_TOKEN = os.environ["API_TOKEN"]

# このbot宛の標準の応答メッセージ
DEFAULT_REPLY = ""

# プラグインスクリプトのリスト
PLUGINS = ['plugins']
```
ちなみにプラグインは以下のように書けば良い。


```python:plugins/line_mention.py
# coding: utf-8 -*-
from slackbot.bot import respond_to
from slackbot.bot import listen_to
from slackbot.bot import default_reply
import os

LINE_NOTIFY_ACCESS_TOKEN = os.environ["LINE_NOTIFY_ACCESS_TOKEN"]

@respond_to('(.*)')
def mention_func(message,something):
    name = "[" + message.channel._client.users[message._body['user']]['real_name'] + " @ slack]\n"
    p = "curl -X POST https://notify-api.line.me/api/notify -H \'Authorization: Bearer ${LINE_NOTIFY_ACCESS_TOKEN}\' -F \'message={0}{1}\'".format(name,message.body['text'])
    req = os.system(p)

```

```
message.channel._client.users[message._body['user']]['real_name']
```
↑で投稿者のユーザ名を取得することができるので、グループトークのために使う。

```
@respond_to('(.*)')
```
↑はメンションされた全てのメッセージというワイルドカード。

Slackbotを起動するには
以下のコマンドを入力して、プログラムを起動する。

```$
$ python3 run.py
```

これで、SlackからLINEへ送信する機能が完成。

# LINEからSlackへ
次に、LINEからSlackへということを考えたい。
linebotsdkライブラリでLINEボットを作りたい。[^3]
https://developers.line.biz/en/
↑へまずはアクセスしてアカウントを登録しよう。
<img width="1164" alt=" 8.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/e5a88e01-f87f-a114-3521-a3a65130faf0.png">

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3131303036302f63326362663535622d326338302d303566612d623536302d3939346361623430656135342e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/110060/78c17a17-1cb4-b500-356e-8af3dd11f8fd.png)


↑ログインできればこの画面が表示されるはずである。
次にアプリの登録である。
<img width="292" alt=" 11.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/1d823b7b-1f71-f43a-75f3-0d531869dd57.png">
↑をクリック。
<img width="705" alt=" 12.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/9339a799-4122-608e-46f3-a84997d6703f.png">
↑プロバイダーの名前を決める。
<img width="949" alt=" 13.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/e0b774b6-5053-0a29-0d7b-755961ed6e5d.png">
↑次にMessageing APIを今回は使用するので、真ん中をクリック。
<img width="1164" alt=" 14.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/21429b83-dbab-7e4b-eb6a-5b86bcda9337.png">
↑必要事項を入力。
<img width="408" alt=" 15.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/4ffb4781-94dc-722a-a933-0788206127c6.png">
↑まで進めば先ほど作った設定をクリック（ここではtesttestとしている。）
<img width="123" alt=" 16.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/0f27ea92-b41a-21b0-2e68-6383370c685d.png">
<img width="1151" alt=" 17.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/b874648d-b73a-7999-73bc-345fc2f54510.png">
<img width="1162" alt=" 18.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/a3c45852-12d6-71e7-28cf-bc839a9eb8c5.png">
あとは、Channel secretとChannel access token(生成が必要)を使うので設定。
それから、デフォルトで、友達登録した時に初期メッセージが届いたり、標準のリプライを設定できたりするので、切っておけば良いだろう。

* アプリ名は登録後7日間変更できないので気をつけよう。

* プランが２種類あると思いますが、push APIを使いたい場合は上のDeveloper Trialを選べば良いだろう。

次にサーバ側の実装。

ディレクトリは以下。

```
├── LINE_to_Slack           #好きな名前で良い。
│   ├── Procfile            #デプロイに必要
│   ├── main.py             #本体
│   ├── requirements.txt　　 #デプロイに必要
│   └── runtime.txt　　　　　 #デプロイに必要
```

# 環境構築
ライブラリをインストールする。

```$:$
$ sudo pip3 install flask 
$ sudo pip3 install line-bot-sdk
```

```python:main.py
from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)
import os
import slackweb
app = Flask(__name__)

YOUR_CHANNEL_ACCESS_TOKEN = os.environ["YOUR_CHANNEL_ACCESS_TOKEN"]
YOUR_CHANNEL_SECRET = os.environ["YOUR_CHANNEL_SECRET"]

line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)

@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    webhooklink = ""
    slackinfo = slackweb.Slack(webhooklink)
    profile = line_bot_api.get_profile(event.source.user_id)
    MESSAGE = "[ " + profile.display_name + "からのメッセージ ]\n" + event.message.text
    slackinfo.notify(text=MESSAGE)

if __name__ == "__main__":
    port = int(os.getenv("PORT", 5000))
    app.run(host="0.0.0.0", port=port)

```

ちなみに、送信元のLINEのユーザ名は以下のように取ることができる。↓

```
 profile = line_bot_api.get_profile(event.source.user_id)
 MESSAGE = "[ " + profile.display_name + "からのメッセージ ]\n" + event.message.text
```
これでmain.pyを実行すればlinebotが起動する。

```$:$
python3 main.py
```
これでLINEからSlackへの送信部は完成。
ここまでできたら双方でメッセージのやりとりができるようになっている。


# Herokuにデプロイ[^3]
最後にデプロイをしてサービスを運用したい。
今回はLINEBOTがssl通信必須ということもあって、Herokuを用いることにした。

herokuに登録
まだherokuに登録してない人は以下から登録する。
https://dashboard.heroku.com/

登録後、ターミナルからHerokuを扱うためheroku-cliをインストールし、ログインする。

```$:$
$ brew install heroku/brew/heroku
$ heroku login
```

あとは設定ファイルを記入してデプロイ。
設定ファイル等はGithubにあげているので、参考に。
https://github.com/Iovesophy/LINE-Slack-Connector

Gitを使ってHerokuにデプロイ。

```$:$
$ cd path/to/your/linebot/directory
$ git init
$ git add . 
$ git commit -m "init"
$ heroku create [Your bot name] % http://[your bot name].herokuapp.com/
```

あとはLINEBOTの方はcallback URLを設定しなければならないので、デプロイ後に表示されるURLをコピペすれば良い。↓

<img width="1131" alt=" 1.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/84c6e569-0e4c-10de-818d-9de092b5f364.png">


pushすれば完了、必要なインストール作業を設定ファイルを元に全てやってくれる。

```$:$
$ git push heroku master
```

LINE messaging APIのChannel secret
Slackのbots API token等はHerokuの環境変数へ。
例↓

```$:$
$ heroku config:set YOUR_SECRET=hoge
$ heroku config:set YOUR_ACCESS_TOKEN=fuga
```

以上でデプロイ完了、時間に余裕ができればもう少し詳しく加筆したいと思う。
ソースをGithubにもあげているので参考にしていただければと思う。↓
https://github.com/Iovesophy/LINE-Slack-Connector

![test2.jpg](https://qiita-image-store.s3.amazonaws.com/0/110060/6e1521bd-2d94-f256-ff12-4afe5de7fdcc.jpeg)

今回LINEとSlackをつなぐこと自体は特に需要がないが、双方を連携させることで、アイデア次第で素晴らしいものができそうな気がしている。
例えば、Raspberry Piから、Slackへセンサー情報を飛ばして、そこから、LINEとSlackを相互通信させておけばHerokuを用いてセンサー情報を取得できるため、sslのサーバを立てたり、ngrockを使ってプライベートネットワークを危険に晒す必要がなくなる。
引き続き研究を続けていきたい。

@kuri_meganeさんにご指摘いただきました、to_lineデプロイ時には以下が必要です。[^4]

```
heroku ps:scale pbot=1
```
またto-line と to-slackはそれぞれ別々にデプロイする必要があります。

[^1]: 「PythonのslackbotライブラリでSlackボットを作る」 https://qiita.com/sukesuke/items/1ac92251def87357fdf6
[^2]: 「LINE Notify API Document」 https://notify-bot.line.me/doc/en/

[^3]: 「FlaskでLINE botを実装し，herokuにdeployするまで」 https://qiita.com/suigin/items/0deb9451f45e351acf92

[^4]: 「pythonで作ったSlackBotを常駐化するまでの備忘録」https://qiita.com/usomaru/items/6eed064690cdb7988e54