LINEグループにBotからメッセージ送信する

LINEグループにプログラムからメッセージを送りたい、と思ったことはありませんか？
SlackやChatworkに比べると手順がやや複雑で手間がかかったので、備忘も兼ねて設定手順を記事に残します。
もし何かの参考になれば幸いです！

# 完成形

```python:example.py
import os
from linebot import LineBotApi
from linebot.models import TextSendMessage

channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN')
group_id = os.getenv('LINE_GROUP_ID')
msg = 'Hello World!'

line_bot_api = LineBotApi(channel_access_token)
line_bot_api.push_message(group_id, TextSendMessage(text=msg))
```

pythonでメッセージ送信する一例です。
`チャネルアクセストークン`と送信先の`グループのID`があればメッセージ送信できます。

**チャネル = メッセージのを送信するアカウント = Bot**と捉えて構いません。
これらを取得しメッセージ送信できることをゴールにします。
# 実装
## Botのチャネルアクセストークンを取得する
チャネルアクセストークンは**LINE Developersコンソール**内で発行できます。
まずはチャネル（Botアカウント）を用意します。

### LINEビジネスIDを取得
チャネルの作成には**LINEビジネスID**が必要です。無い場合は作成します。
https://www.linebiz.com/jp/login/
ここからアカウントを作成しログインします。
個人のLINEアカウントでも登録できますが、私はメールアドレスで登録しました。

### LINE Official Account Managerにログイン
上記の画面にログインすると、その中で**LINE公式アカウント**を作成できます。
![LINEアカウントを作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/4d670665-f05a-0ab0-6d4c-ce251fbeed9e.png)

アカウントを作っていきなり更にアカウントを作る？？とこの時点で少々面食らいましたが、
要するに1つ**LINEビジネスID**があれば複数の**LINE公式アカウント**を持つことができます。

::: note info
**LINE公式アカウント = チャネル = Bot**と考えて良いと思います
（厳密には違いますが今回は触れません）
:::

### メッセージ投稿のための設定
公式アカウントを作ったら、メッセージ投稿のための設定を行います。
画面右端の「設定」メニューを開きます。

#### Messaging API
サイドメニュー「Messaging API」を開き「Messaging APIを利用する」を実行します。
![Messaging APIを利用する](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/837dd56a-ae9b-fc35-a91c-d0d15bb9280b.jpeg)
ここで開発者情報を登録します。改めて開発者のメールアドレスと名前を登録する必要があります。
更に「プロバイダ」の設定も求められます。
![プロバイダーを選択](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/c9e408a5-0990-6384-9e1e-ca50f8203d58.png)
ここには開発元企業や団体名を入れます。
個人利用なら個人名で良いと思います。
![チャネル情報](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/4c2cdf7d-360e-5124-2917-dbe811984704.png)
Channel IDとChannel secretが発行されました（が、今回は使いませんでした）
また、画面の下部のリンクから**LINE Developersコンソール**に入ることができます。

#### Developersコンソールに移動し、アクセストークンを発行
**LINE Developersコンソール**に入ります。
先ほど作った「プロバイダ」と、それに紐づく形で「チャネル」が作成されているのがわかります。
![LINE Developersコンソール](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/205f13b4-347e-1f58-a7fa-eb69258853f2.png)

チャネルを開いたら、
「Messaging API」メニュー下部の「Channel access token」という項目を探します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/e7cdf9d5-db7c-eeba-8750-3da673db9cd7.png" width=50% alt="Channel access token">

「issue」を選択し、アクセストークンを発行します。

これで**チャネルの作成**及び、メッセージの投稿を行うための
**アクセストークン**を取得できました！

## LINEグループのIDを取得する
ここからが**手間がかかる**ところです。
投稿先のLINEグループのIDを知りたいのですが、グループの詳細画面を開いてもIDらしきものが載っていません:frowning2:
SlackのチャンネルIDのようにはいきませんでした…

### LINEグループのIDを確かめる手順
以下の手順を踏む必要がありました。
1. BotにWebhookのURLを登録
1. IDを知りたいLINEグループに参加させる
1. 参加時に発行されるイベントを取得

つまりWebhookの受信サーバを（一時的にでも）用意する必要があります。

::: note info
**Messaging APIのWebhookとは**
友だちのメッセージ投稿やグループへの参加など、Botに対し「イベント」が発生するたび、それを受信することができます。
企業などのLINE公式アカウントのチャットBotはこれを使って実装してるんですね。
:::

[公式ドキュメントのWebhook仕様はこちら](https://developers.line.biz/ja/docs/messaging-api/receiving-messages/)

### Webhook受信先を用意する
イベント受信のための一時的なサーバを作ります。
今回はAWS lambdaを使用しました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/828f7950-2e6f-9292-f12f-4bc3ae328c95.png" width=75% alt="lambda">
ランタイムはpythonを選択しました。
他は全て初期設定で構いません。

#### イベントをログに出力するように修正
```diff_python:lambda_function.py
import json

def lambda_handler(event, context):
+   print(event['body'])
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```
初期コードに1行追加し、Deployします。
受信したパラメータをログに出すようにしました。

#### URL発行
「設定」→「関数 URL」より関数URLを作成します。
認証タイプはNONEで作成しました。
![関数 URL](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/4dd8fc7f-4b72-c6dd-7c97-db3605ca9e8d.png)
※どこからでもアクセスできてしまいますが、今回の用途のように一時的にであれば大丈夫でしょう。
**終わったらURLの削除を忘れないように**します。

#### Webhook受信のための設定
先ほど作成したURLを**LINE Official Account Manager**内
「Messaging API」の「Webhook URL」に保存します。
![Webhook URL](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/6320bdc0-f064-5095-c123-9630a4b666ee.png)


更に、「応答設定」メニューの詳細設定からWebhookをオンにします。
![応答設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/f404258d-66e0-4973-2c82-c596f66c2854.png)
これでWebhook受信の準備が整いました。

### LINEグループにBotを招待する
Botをグループに招待するために、もう一つ設定を変更しておきます。
サイドメニュー「アカウント設定」の中から「トークへの参加」項目を探し、
「グループ・複数人トークへの参加を許可する」に切り替えます。
![アカウント設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/5fbe837b-a1f2-af62-7fc9-06d1c5f66702.png)
これを行わないとBotをグループに招待してもすぐに退出してしまいます。

#### Botを友だち追加
ここからは個人のLINEアカウントを使います。
まずはBot（LINEアカウント）と友だちになります。
「ホーム」メニューの「友だち追加ガイド」を参考に、URLやQRコードで友だち追加してください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/3ed80374-f128-4140-d7a8-520fb06e24b2.jpeg" width=50% alt="友だち追加">
（設定したプロバイダ名はここで公開されることになります）

::: note info
友だち追加後にサーバーのログを見ると、何かが実行されていることがわかります。
これは「友だち追加」のイベントを受信したためです。
:::

![CloudWatch](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/7a66bd99-2d9e-ee61-af6b-7082ee0548c9.png)
（lambdaのメニュー「モニタリング」→CloudWatchのログより確認）

#### LINEグループにBotを招待し、イベントの中身を確認
あと少しです！
LINEグループにBotを招待するとイベントが発行されるので、ログを確認します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/8b9ace6f-0f59-7f6c-39df-c7bd999c19e7.png" width=75% alt="イベント">
`type`が`join`なのはグループへの参加イベントであることを表します。
`source`内の`groupId`がお目当ての**LINEグループID**です:laughing:
これを控えておきます。

終わったら忘れないようにlambda関数のURLを削除します。
Webhookの設定も無効化しておきます。

## （余談）グループID確認手段について
サーバはイベントの中身が確認できればなんでも良いです（ただしhttpsである必要はあります）
本格的なアプリを組む場合は別ですが、今回のような用途であればGASやLambdaで良いでしょう。

::: note info
調べるとGASで同じことをやる記事がいくつか出てきました。そちらの方が手軽で良さそうです。
:::

もし、もっと手っ取り早くIDを確認する手段をご存知の方がいれば、
ぜひ教えてください:pray:

## いよいよメッセージ送信
[冒頭のソース](#完成形)に`チャネルアクセストークン`と`グループのID`を入れてやれば完成です。
実行するとグループにメッセージが送信されます！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385718/ca806a1f-7096-22ba-7722-6cd4b6d94baa.jpeg" width=50% alt="メッセージ送信">
あとはリマインダーにするなりなんなりご自由に:v:

### 公式SDKについて
実装には[公式のSDK](https://developers.line.biz/ja/docs/messaging-api/line-bot-sdk/)を使いました。
```bash:pipでSDKをインストール
$ pip install line-bot-sdk
```
GoやRubyなど他言語にも提供されているので、チェックしてみてください。

# まとめ
- アクセストークンはDeveloperコンソール内で発行できる
- LINEグループIDの取得はWebhookイベントを参照するしかなく、サーバが必要

SlackやChatworkは便利ですが、家族や友人に入れてもらうのはちょっと無理があります。
LINEで自由にメッセージ投稿できるのであれば、有力なツールになるのではないでしょうか。私はサークルのイベントのリマインドに使っています。

ぜひぜひお試しください！