【前回記事の補足】いつの間にかフリープランでも使えるようになっていたLINE BotのPUSH APIを使用してみた

# この記事について
前回記事「[Python(Flask)で実装したLINEBotを"Herokuを使わずに"動かす](https://qiita.com/hiro0236/items/84581c5e4481185d4a5c)」の補足。
かつて、LINE Botのフリープランではユーザにメッセージを送るのはユーザからメッセージが送られてきたのに対し応答するのに限られており
ユーザにこちらからメッセージを送るPUSH APIは使用できなかったが、いつの間にかフリープランでもPUSH APIが使用できるようになっていた。
これによりフリープランでも開発の幅が広がったので、その使用方法を調査する。

# なぜ、いつの間にか使えるようになっているのか
調べたところ、LINE公式から[このようなアナウンス](https://engineering.linecorp.com/ja/blog/line-developer-trial-migration/)があった模様。
2019年6月ごろからフリープランでもPUSH APIが使用可能になったらしい。
ただし、**月に1,000通までという制限あり**。
ユーザ数が100人を超えるようなサービスとなると厳しそうだが、数十人程度におさまるのであれば（用途にもよるが）充分そうである。

いずれにせよ、フリープランで開発しているエンジニアにとって開発の幅が大きく広がったことに違いはない。

# プッシュメッセージの種類
[公式のリファレンス]()によると以下の4種類ある模様。

- プッシュメッセージ（ユーザIDをキーとして、1人のユーザにメッセージを送信）
- マルチキャストメッセージ（ユーザIDをキーとして、複数人のユーザにメッセージを送信）
- ナローキャストメッセージ（送信対象となるユーザの属性情報等によりユーザを絞り込んでメッセージを送信）
- ブロードキャストメッセージ（Botアカウントと友だちになっている全ユーザ宛にメッセージを送信）

# メッセージを送信してみる
LINE APIにcurl等で直接たたいてみてもよいが、前回記事でline-bot-sdk-pythonをインストールしたので
Pythonでプッシュメッセージを送信するコードを書いてみようと思う。
[line-bot-sdk-pythonの実装](https://github.com/line/line-bot-sdk-python)を読みながら実装していく。

前回記事の続きということで、line-bot-sdk等はすでに導入されているものとして進める。

## プッシュメッセージの送信
以下のコードで実現可能。
メッセージを送信するだけなら、以下の通り簡単に実装可能。

```python:push.py
from linebot import LineBotApi
from linebot.models import TextSendMessage

CHANNEL_ACCESS_TOKEN = "チャネルアクセストークンを設定"
line_bot_api = LineBotApi(CHANNEL_ACCESS_TOKEN)

def main():
    to = "ユーザIDを指定"
    messages = TextSendMessage(text="プッシュ通知送信テスト")
    line_bot_api.push_message(to, messages=messages)

if __name__ == "__main__":
    main()
```

実行したところ、以下の通りBotからメッセージが送信されてきた。

![linebot3_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476892/f256fd65-417d-8c55-f91d-a2aee6698fba.png)

## マルチキャストメッセージの送信

複数のユーザに対してメッセージを送るのだが、私がLINEのアカウントを一つしか持っていないため
本当に複数人に対して送信されるかどうかは確認できていない。

```python:multicast.py
from linebot import LineBotApi
from linebot.models import TextSendMessage

CHANNEL_ACCESS_TOKEN = "チャネルアクセストークンを設定"
line_bot_api = LineBotApi(CHANNEL_ACCESS_TOKEN)

def main():
    to = ["送信対象のユーザIDをリスト型で指定"]
    messages = TextSendMessage(text="マルチキャストテスト")
    line_bot_api.multicast(to, messages=messages)

if __name__ == "__main__":
    main()
```

![linebot3_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476892/9d72382c-6f16-7571-016b-1ebdd7d8f957.png)

## ナローキャストメッセージの送信
ちょっとよくわからなかった。
ユーザの年齢や性別等で絞り込みをかけるらしいが、ユーザの固有情報として年齢や性別がどうやって設定されるのか不明。
[ユーザのプロフィールを取得するAPI](https://developers.line.biz/ja/reference/messaging-api/#get-profile)で自分のプロフィールを取得してみても、これらの情報は取得できず。
今後の課題として、もう少し調査してみます。

## ブロードキャストメッセージの送信
Botの友だち全員にメッセージを送信するのだが、Botの友だちは自分一人しかいないのでやはり確認はできていない。

```python:broadcast.py
from linebot import LineBotApi
from linebot.models import TextSendMessage

CHANNEL_ACCESS_TOKEN = "チャネルアクセストークンを設定"
line_bot_api = LineBotApi(CHANNEL_ACCESS_TOKEN)

def main():
    messages = TextSendMessage(text="ブロードキャストテスト")
    line_bot_api.broadcast(messages=messages)

if __name__ == "__main__":
    main()
```

![linebot3_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476892/0c93dd99-a9b8-723f-69c4-7c24a0333c64.png)

# テキストメッセージ以外にも対応
line-bot-sdk-pythonはテキストメッセージ以外に、スタンプや画像の送信にも対応している。
今回確認したのはスタンプと画像のみだが、[実装を見る限り](https://github.com/line/line-bot-sdk-python/blob/master/linebot/models/send_messages.py)動画や位置情報等も送信可能な模様

## スタンプを送信

スタンプの指定に必要なpackage_idおよびsticker_idは[こちら](https://developers.line.biz/media/messaging-api/sticker_list.pdf)を参照。
企業の公式アカウント等を見ると、スタンプショップで販売されているスタンプを送信してくるものもあるようだが
これはどうやって実現しているかは不明。もう少し調査する。

```python:push_sticker.py
from linebot import LineBotApi
from linebot.models import StickerSendMessage

CHANNEL_ACCESS_TOKEN = "チャネルアクセストークンを設定"
line_bot_api = LineBotApi(CHANNEL_ACCESS_TOKEN)

def main():
    to = "ユーザIDを指定"
    messages = StickerSendMessage(package_id='11537', sticker_id='52002734')
    line_bot_api.push_message(to, messages=messages)

if __name__ == "__main__":
    main()
```

![linebot3_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476892/7ca28993-84e2-2713-fb54-3a98f8bb0955.png)

## 画像を送信

```python:push_image.py
from linebot import LineBotApi
from linebot.models import ImageSendMessage

CHANNEL_ACCESS_TOKEN = "チャネルアクセストークンを設定"
line_bot_api = LineBotApi(CHANNEL_ACCESS_TOKEN)

def main():
    to = "ユーザIDを指定"
    messages = ImageSendMessage(original_content_url="https://pbs.twimg.com/profile_images/1201406146822557696/ewFFvnAa_400x400.jpg", preview_image_url="https://pbs.twimg.com/profile_images/1201406146822557696/ewFFvnAa_400x400.jpg")
    line_bot_api.push_message(to, messages=messages)

if __name__ == "__main__":
    main()
```

![linebot3_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476892/fe72a95d-d71f-b7e3-86c0-dfabb99bfe26.png)

# おわりに
前回記事で個人的な今後の課題としていた事項について新たに記事を書きましたが、また新たな課題が出てきてしまいました。
また調査が進み次第記事の更新を行うか、新たに記事を作成します。

私の記載した情報に間違い等あれば教えていただけるとありがたいです。