サービス終了するLINE Notifyの代わりにDiscordを使ってみた

この記事は<a href="https://qiita.com/advent-calendar/2024/furyu" target="_blank">フリューアドベントカレンダー2024</a>の記事になります。

***


LINEを使って通知を送信できる「LINE Notify」のサービス終了がアナウンスされました。
<a href="https://notify-bot.line.me/closing-announce" target="_blank">サービス終了の詳細はこちら</a>

このサービス終了を受けて、代替手段として Discord を利用することにしました。
本記事では、Pythonを用いた実装方法やLINE Notifyとの機能の違いについて、わかりやすく解説します。


# LINE Notifyとは
LINE NotifyはアプリやWebサービスからの通知をLINEで受け取れるサービスです。
外出中でもスマホで簡単に確認できるので通知手段として非常に使い勝手がよく、しかも無料で利用できるため個人の開発者やサービス運営者にとって重宝されているサービスではないかと思います。

以下は私の活用例の一つです。
* #### インターホンが押されたら通知
自宅のインターホンが押された際に、LINEに通知を送信する仕組みを構築していました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/174f9f70-1374-89a4-8416-acbec53c7a2a.png)

# LINE Notifyに代わるサービス
LINE Notifyのサービス終了に伴い、代替となるサービスをいくつか検討しました。
以下は候補として挙がったサービスです
* LINE Messaging API
* Discord
* Slack
* Teams

他にも選択肢はありますが、できるだけ手間をかけずに実装したいという観点から、既にスマホにアプリがインストールされているサービスを中心に検討しました。

***
#### LINE Messageing API
LINE Notifyと利用感が大きく変わらないのは、**LINE Messaging API**です。

公式サイト

https://developers.line.biz/ja/services/messaging-api/

このAPIは月200通までは無料で利用可能ですが、それ以上になると有料プランが必要です。

https://www.lycbiz.com/jp/service/line-official-account/plan/

無料枠で十分であれば、引き続きLINEプラットフォームを利用するのが良いと思います。
しかし、私は月200通を超えるのでコスト面から見送りました。

***

#### Discord
**Discord** は、無料で利用できるインスタントメッセージングサービスです。

https://discord.com/

普段から利用しており、スマホにもアプリをインストールしていたこともあって、試してみることにしました。
DiscordのAPIは無料で利用可能で、手軽に導入できる点が大きな魅力となります。
今回の記事では、このDiscordを活用した通知の実装方法について解説します。

***

#### Slack,Teams

**Slack** や **Teams** も候補に挙げました。
実現は可能ですが以下の理由から利用を見送りました

* 個人の通知利用では機能が過剰で、やや使いにくそうな印象
* 業務でこれらのツールを利用しており、プライベートとの切り替えが手間そうに感じた

そのため、今回は候補から外しました。

***


# LINE NotifyからDiscordに切り替えてみてどうだったか
詳細を説明する前に、結論を簡単に述べておきます。
**Discordは通知機能として問題なく利用でき、実装も簡単なので、すぐに切り替え可能です。**
私は実際に通知をDiscordで受け取る形に変更しています。
ただし、LINE Notifyと比較するといくつか気になる点があるため、それについても紹介します。


***

### 気になる点
1. **スマホの通知バナーからDiscordを開いた際の遅延**
Discordでは、スマホの通知バナーをクリックしてアプリを開くと、通知内容が表示されるまでに 1秒程度の遅延を感じます。
この遅延により、似たような通知が続く場合には前のメッセージが今回届いたものだと勘違いしてしまうことがあります。

2. **通知メッセージの視認性**
1番と似たような話ですが、LINE Notifyでは通知が1メッセージごとに吹き出し形式で表示されるため、視覚的にわかりやすい構造になっています。
一方、Discordでは投稿が連続すると以下のように1つのメッセージに見える場合があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/0649eb68-7509-7030-a531-443d9c97eda2.png)
この例では、2つの通知メッセージが連続して投稿されていますが、瞬間的に2つの通知であることに気づきにくい点がLINE Notifyとの違いです。
とはいえ、これは通知内容や利用者の好みによる部分も大きいと思います。

***

### 総評
**無料で利用でき、最低限やりたいことを実現できる点から、DiscordはLINE Notifyの代替サービスとして十分と判断しました。**
また、Discordではチャンネルを分けることで、通常の通知、エラー系の通知などシーンに応じた通知をまとめられる点が強みかなと感じました。
先ほど述べた気になる点もありますが、実装元の通知の仕組みを大きく変更することなく切り替えが可能なため、コストを抑えつつスムーズに移行したい方にはおすすめです。

***


# Discordで通知を実現する
実現方法にはWebhookを利用する方法と、Botを作成する方法があります。
手軽に実現するのであればWebhookを利用するのが良さそうです。

https://discord.com/developers/docs/resources/webhook

今回は将来的に対話も実装できるよう一歩踏み込んで、Botを利用した実現方法を紹介します。

では、内容に入ります。
**Discordで通知を実現するには、LINE Notifyに比べて少し手間が掛かりますが、難しい内容ではありません。**
具体的には、以下の手順で通知を行います。
1. DiscordのBOT（アプリ）を作成する
1. Discordの通知用サーバーを作成する
1. 作成したサーバーのテキストチャンネルにBOT（アプリ）を参加させる
1. BOTを介して通知を送信する

 「BOTを使うなら、応答アプリをサーバーにホストする必要があるのでは？」と思うかもしれません。
 しかし、通知を送るだけであれば **APIを呼び出すだけで実現可能**です。
 この点において、実装レベルでの使用感はLINE Notifyとほとんど変わりません。

順を追って説明します。

# 実装手順

### 1.Botアプリケーションの設定

**Discord Developer Portalにアクセス**
まず、以下のURLからDiscord Developer Portalにログインします
<a href="https://discord.com/developers/applications" target="_blank">Discord Developer Portal</a>

ログイン後、```New Application```を選択します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/e8667890-a05a-d301-ba3e-9edc3de43f5f.png)

**アプリケーションの作成**
1. アプリケーション名を入力します（例：NOTIFICATION-TEST)
1. 利用規約とポリシーに同意するチェックをして```Create```します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/4b23aabe-ba55-5c6c-19a9-b8afa0bda4ff.png)


**Botの作成と設定**
1. サイドメニューから```Bot```を選択します
1. ```USERNAME```欄でBotの名前を設定します、これがDiscord上で表示される名前です（例：通知くん）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/cdfdf14b-f80c-a557-1a85-ab2f1e572304.png)

1. サイドメニューから```Installation```を選択し、以下の設定を行います
* ```User Install```のチェックを外します
* ```Guild Install```に```Scope```として「bot」を追加します
* ```Permissions```に「Administrator」と[Send Messages]を追加します

:::note warn

今回はテストとして権限をAdministratorにしています、個人チャンネル以外への通知やBotとして受け答えさせる場合には然るべき権限にしてください
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/3bef0f6d-ff0b-331c-209b-a9cad0ca8c00.png)

*** 

### 2.通知を行うチャンネルを作成
次に、通知を送信するDiscordのテキストチャンネルを作成します。

**サーバーの作成**
1. Discordにログインして、```サーバーを追加```を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/ce3019b5-704f-2a56-5afc-1f28b3dea2de.png)

2. ```オリジナルの作成```を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/6a87f98a-7f05-7323-ff60-f802880fdbc3.png)
3. サーバーの規模を選択します、今回は```自分と友達のため```を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/9e0d127a-94e3-eabe-b959-1007b78e14e0.png)
4. サーバー名を入力し、```新規作成```をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/2868d0f3-0b3d-df2f-297d-7b35b5712d37.png)
5.サーバーが作成されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/d85c366b-5c5b-aea1-085d-fcdd31f5bc37.png)

*** 

### 3.Botアプリを通知用のチャンネルへ追加する
**Botアプリインストールリンクを取得**
1. Discord Developer Portalの**アプリケーション設定ページ**に戻ります
1. ```Installation```を選択し、```Install Link```に表示されているURLをコピーします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/4f024bda-4b80-8d11-4888-4cd481f1c827.png)
1. コピーしたリンクをブラウザに貼り付けて開きます
1. 以下のようなインストール画面が表示されるので、先程追加したサーバー名を選択して ```はい``` をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/9f9d0a41-229d-b4af-e570-e9b4200d4382.png)

**Bot権限の確認と認証**
1. Botアプリケーションで設定した権限が正しく表示されていることを確認します
1. ```認証```をクリックして、インストールを完了します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/8ffe3da1-e47b-a4bc-6450-e21986f9fb17.png)

1. インストール完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/6f403562-c211-c2c9-e8e0-155b949a73b9.png)

**Botの追加確認**

インストールが完了すると、Botが通知用のテキストチャンネルに追加されているはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/1f8a6e3f-3374-c602-3d14-845c6efdc19a.png)

これでサーバー側の設定が完了しました。

*** 

### 4.BOTを介して通知を送信する

#### 通知元の実装
ここでは、DiscordのBotに通知を送信するためのPythonコードを実装します。
動作確認は以下の環境で行っています。
|環境 |バージョン
|---|---|
|OS |Windows 11  |
|Python|3.11.9  |


**必要なライブラリのインストール**
コードの実行には```requests```ライブラリが必要です。
以下のコマンドでインストールしてください
```
pip install requests
```

**送信クラスの作成**
以下は、通知を送信するためのシンプルなクラスです。
また必要最低限のエラー処理しか実装していないので、必要に応じて作成してください。

``` discode_send_message.py
import requests

class DiscordSendMessage:

    __default_token : str = 'your_default_token' # アプリケーションのトークンを設定する
    __default_channel_id : str = '1234567890'    # テキストチャンネルのIDを設定する

    def __init__(self, token: str = __default_token, channel_id: str = __default_channel_id):
        self.__token = token
        self.__channel_id = channel_id
        
    def send_message(self, message: str):
        url = f"https://discord.com/api/v10/channels/{self.__channel_id}/messages"
        headers = {
            "Authorization": f"Bot {self.__token}",
            "Content-Type": "application/json"
        }
        data = {
            "content": message
        }

        response = requests.post(url, headers=headers, json=data)
        
        if response.status_code == 200:
            print(f"送信完了: {self.__channel_id}")
        else:
            print(f"送信失敗: {response.status_code}, {response.text}")
```

**トークンの取得と設定**
1. Discord Developer Portalのアプリケーション設定ページにアクセスします
1. ```Bot```メニューの```Reset Token```をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/cbca0050-8b3c-d924-c2e1-98757980e980.png)
1. 自身のDiscordのログインパスワードを入力します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/b91d3612-5e08-9ae9-fe91-e81b318ace8a.png)
1. トークンが発行されるので、そのトークンを**コード内の```__default_token``` に設定**してください

:::note alert
**トークンのセキュリティに注意**
この取得したトークンは外部に漏らさないよう注意してください。
サンプルコードでは直接コードに記載していますが、実際の運用では環境変数などから取得するようにしましょう。
:::

**4. チャンネルIDの取得と設定**
1. Discordのサーバーにあるテキストチャンネルを右クリックし、```IDをコピー``` を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/f11c2bd5-0078-50fa-81b5-b618174c526d.png)
1. 取得したチャンネルIDを**コード内の ```__default_channel_id``` に設定**してください


**5. メインコードの作成**
以下のコードで送信クラスを呼び出し、Botに通知を送信します。
``` main.py
from discord_send_message import DiscordSendMessage

if __name__ == "__main__":
    discord_utility = DiscordSendMessage()

    # 完了通知をDiscordへ送信
    discord_utility.send_message("通知のテストです。")

```
このコードを実行すると、メッセージが指定したテキストチャンネルに送信されるはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743276/60cbdd7f-4da3-1416-bbfd-b54272d3b18a.png)


### 5.参考リンク
DiscordのAPIリファレンスについては、以下のリンクを参考にしてください

https://discord.com/developers/docs/reference

# さいごに
いかがでしたでしょうか？
Discordでの通知システムは、サーバーにBotアプリケーションを設置する手間があるだけで、基本的な使い勝手はLINE Notifyとほとんど変わらないと感じていただけたのではないでしょうか。

また、Discordの「Message Components」を活用すれば、通知だけでなくUIを設置してインタラクティブな操作を行うことも可能です。
将来的には、Discordからの入力を受けて遠隔実行など、より高度な機能に挑戦してみようと考えています。
この記事が、LINE Notifyの代替を探している方の参考になれば幸いです。