見出し画像

自作自治会HPのLINE連携開発!

はじめに

 今週は会社はお盆休みなのだが、課題がたくさん。。。でも、台風で明後日の京都行をやめたからまだ大丈夫、と思いつつ課題には5日間全く手を付けず、1年前からやりたかった、自作自治会HPの記事投稿時のLINE通知機能を(現実逃避で?夏休みの自由研究的に?)再チャレンジ!そして、数日かけてChatGPT-4oに教えてもらいまくり、自治会HP用のLINEに友達登録した人宛に、HPへ記事投稿時LINE通知される機能を実装できた!(我ながら感動!)
 
そこで、(課題そっちのけで全力投球した)この数日間の悪戦苦闘の内容を夏休みの自由研究として書き留めることにする。


1.前提(自作自治会HPについて)

  • 紙の回覧板の電子化を目的に2023年1月にプロトタイプ自作、2023年4月より、2000人・900世帯が居住する自身の自治会で本番運用開始

  • HPはWIX(ノーコードツール)+Velo(Wixで使えるjavaScript系のプログラミング言語)を使い、自作プログラミングで開発

  • 管理者用の画面で投稿すると、HOME画面の記事一覧が自動更新されるよう、Veloで作りこんでいる。(以下イメージ)

HOME画面
管理者用画面

2.課題意識

1年半運用しているが、以下のような課題意識や要望があった

  • 定期的・能動的にHPをみる人は少ないので、通知がないと投稿してもなかなか気づいてもらえない

  • 災害時などに自治会役員から全員に通知する手段が欲しい(自治会・管理組合委員長からの要望)

そこで、
『記事投稿時に自治会サイトのLINE登録した人にLINE通知が送れるようにしよう』
ということで、開発開始(以下やりたいことのイメージ)

イメージ(投稿時に登録者へ通知)

3.全体像

 開発の全体像は以下の通り

  • LINE(デベロッパー)・WIX(バックエンド・フロントエンド)・Glitchを利用

  • 最初(A)の投稿時に(固定の)ユーザーに通知する機能を開発(以下(1)(2)(3))

  • 次に(B)の友達追加されたユーザーIDを自動保存する機能を開発(以下(4)~(7)

開発全体像

4.開発ステップ

(1)LINE Developerの設定

以下を参考にしながら、プロバイダーとチャネルを作成

■「チャネル基本設定」
チャネルアイコンとチャネル名は更にリンク先(LINE Official Account Manager)に飛び設定を実施

■「Messaging API 設定」
以下を利用する

Messaging API 設定の利用

(2)Wix(velo)のバックエンド

WixとveroでHPを作成しています。投稿したらLINE通知がされるようなプログラムを書きたいです。 投稿の処理は現在veroで以下のようなコード(略)を書いています。以下サイトを参考にして、やりたいことを実現するプログラムを書いてください。

  • 上記のような感じの質問をChatGPT-4oにして、そこで生成されたプログラムで実行、エラーをさらに質問、そして以下サイトを見ながら作成(以下サイトを見つける前は、ChatGPTに質問しても、「.jsw」か「.js」の拡張子のやり方しか回答がこず、フロントエンドからの呼び出しがどうしてもうまくいかずここで数時間かかってしまったが、以下サイトを見て「.web.js」でwebMethodでのやり方が説明されていたので、自分でも確認しながらプログラム作成し、うまくいった!)

export const sendLineNotification = webMethod(
  Permissions.Anyone,
  async (message) => {
    const url = "https://api.line.me/v2/bot/message/push";
    const channelAccessToken = "MY_ACCESS_TOKEN";//個別に設定
    const headers = {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${channelAccessToken}`,
    };
    try {
        // データベースからユーザーIDを取得
        const userIds = await getUserIds();

        for (let userId of userIds) {
            console.log(userId);
            const body = {
                "to": userId,
                "messages": [
                    {
                        "type": "text",
                        "text": message,
                    },
                ],
            };

            try {
                const response = await fetch(url, {
                    method: "POST",
                    headers: headers,
                    body: JSON.stringify(body),
                });

                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }

                const data = await response.json();
                console.log(`Message sent successfully to ${userId}:`, data);
            } catch (error) {
                console.error(`Error sending message to ${userId}:`, error);
            }
        }
    } catch (error) {
        console.error("Error retrieving user IDs:", error);
    }
}
);

// データベースからユーザーIDを取得する関数
async function getUserIds() {
    try {
        const result = await wixData.query("UserIds").find();
        return result.items.map(item => item.userId);
    } catch (error) {
        console.error("Error querying UserIds collection:", error);
        throw new Error("Failed to retrieve user IDs");
    }
}
  • 4行目:https://api.line.me/v2/bot/message/pushは以下を参照

  • 5行目:channelAccessToken は、(1)で取得したチャネルアクセストークンを設定

  • 最初は自分のUserIDでテスト(以下「開発者が自分自身のユーザーIDを取得する」を参照し、getUserIds()や for (let userId of userIds) は使わず、"to": に直接自分自身のユーザーIDを設定して実施)

  • その後、Wixのテーブル(UserIds)を作成し

  • 上記テーブルのUserIdから順に取得し(getUserIds関数)、ループで送信できるよう変更

(3)Wix(velo)のフロントエンド

既に実装済(運用済)のregisterbotton_clickから先ほどのバックエンド関数のsendLineNotificationを呼び出すように追加

let message = `自治会HPへの新しい投稿:  ${toInsert.title};
                    sendLineNotification(message)
                    .then(response => console.log("通知が成功しました:",response))
                    .catch(error => console.error("通知に失敗しました:", error));

ここまでで、(A)の投稿時に(固定の)ユーザーに通知する機能は、完成!

(自分の理解のための確認)
何故バックエンドに分けて記載するのか?
⇒AccessTokenやUserIDなどフロント側のソースコードに書くと外から見えてしまうから。

(4)ユーザーIDを取得方法検討

さて次は、(B)の友達追加されたユーザーIDを自動保存する機能を開発だが、どうやってすればよいのだろうか。

  • 以下記載の通り、LINE登録されたユーザーIDの取得方法は4つある

LINEのUserIDの取得方法
  • 自分自身だけでは意味がないので、2,3,4を検討。有償プランも年間1,200円と低額だが自治会の了解得ていない、認証済アカウントにするにはLINEに色々申請が必要、Webhook機能というのを一度試してみようということで、2のWebhookにチャレンジしてみることに。

  • ただ、どうやっていいか全然わからないので、ChatGPTにそのまま質問。「LINEのwebhookURLには何を記載すればよいですか? https://developers.line.biz/ja/docs/messaging-api/getting-user-ids/#get-user-ids-in-webhook に従って、 WebhookからユーザーIDを取得する が出来るようにしたいと思っています」。すると、「あなたが運営するサーバーやクラウドサービス(AWS Lambda、Google Cloud Functions、Herokuなど)に配置するか、Glitch( シンプルにNode.jsコードをオンラインでホスティングし、Webhookをテスト)と回答(他詳しく教えてくれる)

  • クラウドは個人で管理が難しいので、初めてのGlitchに挑戦

(自分の理解のための確認)
Webhookとは・・・

Webアプリケーションでイベントが実行された際、外部サービスにHTTP で通知する仕組み。但し、ユーザーからのリクエストが暗号化や認証の手段で保護されていない場合、個人情報が漏洩するリスクもある
⇒本番化には色々考慮必要そうだがとりあえず試行まで(多分本番化は、3の方が安全)

(5)Glitch&LineDeveloper

ここでも、ChatGPT-4oに「Glitchを使うやり方を教えてください」として教えられたとおりに実施。

  • Glitchのウェブサイトにアクセスし、アカウントを作成

  • 「New Project」ボタンをクリックし、「Create a Node App」を選択し、Glitchプロジェクトのファイルビューで、server.jsファイルを開きChatGPTに教えてもらった通りのコードをそのまま貼り付け(ソースコードは割愛)

  • Glitchの右上の「Share」をクリックしLive SiteのURLをコピー

  • LINE Developer でWebhookの有効化を実施、WebhookURLには、https://<your-project-name>.glitch.me/webhookとコピーしたURLの最後に/webhookとつける。

  • これで、LINEの友達登録時に、userIDが取れるようになった。

(6)Wixのエンドポイント作成

(5)でGlitchでuserIDは取れるようになったものの、これを自動でWixのテーブルに書き込みに行きたい。ChatGPTに聞きながら色々試してみるも、そもそも、GlitchからWixで作ったエンドポイントをなかなか呼び出せない。そんな中以下サイトを発見。

そもそも、「.web.js」で書くのが間違い(「.js」で書くのが正しいようでファイル名や関数名の付け方も定められている)、かつ呼び出し方の間違いもあり、これでまた数時間費やしたが、何とか自力で成功。(ソースコードは割愛)ポイントは以下

  • バックエンドの中にhttp-functions.jsというファイル作り post_××という関数を書くこと(Glitchから呼び出すときには、サイト名の後は、/_functions/××と書く!(post_××ではない!)https://{user\_name}.wixsite.com/{site\_name}/\_functions/<functionName>

更に、既にテーブルにあるIDは挿入せず、なければテーブルに挿入する処理を追加したり、少し権限を変更したりする。

(7)GlitchからWixへの送信

ステップ(5)で書いた処理に、Wixに送信する関数(Wix側で作成したエンドポイント(http-functions.jsに書いた関数を実行)、エンドポイント自体はGlitchの環境変数に設定)を追加したもの)を追加して完成!(ソースコードは割愛)

これで、友達登録されたなどLINEのイベント発生時に、LINEのWebhookでGlitchからWixに送信され保存される仕組みも完成

最後に

 このお盆休み、Wix(Velo)で作成したHPの投稿時のLINE通知機能(友達登録時の自動連係含む)を試行的に作り、動くものが完成できてとても嬉しい。あわせて、異なるアプリケーション間でのやりとり、バックエンド・フロントエンドでのやりとり、fetchでの呼出、エンドポイントの作り方、Webhook、など大分実践的に理解できた。
 ニーズが高いのでどこかで本番化していきたいとは考えているが、セキュリティ面などについて有識者に確認した上で、安全な状態にしてから本番化していきたい。

この記事が気に入ったらサポートをしてみませんか?