Django、Lineで更新を通知

2019-07-27 / PythonDjangoLine

概要

Djangoで、Webサイトの更新情報を通知するシリーズの1つです。Webサイトの更新情報を通知するシリーズの一つです。Lineで、Webサイトの更新を伝えていきます。注意として、この方法は、ドメインの取得とHTTPSの対応が必要です。

Line Developersコンソール

まず、公式サイトへアクセスします。 「ログイン」を押してください。
公式サイト

初回のログイン時は、幾つかの入力項目があります。入力しておいてください。

ログインすると、次の画面になります。 「新規プロバイダー作成」を押しましょう。
コンソールトップ

適当に入力して、「確認」を押します。確認画面に移るので、そこでもボタンをおしてください。

今回使うのは、「Messaging API」です。「チャネル作成する」を押してください。

Messaging APIの情報を入力する画面に移るので、入力していき、作成しましょう。

次の画面になるので、今作成したチャネルをクリックしましょう。

チャネル基本設定の画面に移りました。

少しスクロールし、「アクセストークン」の「再発行」ボタンを押してください。表示されたトークンを今後使います

また、Webhookを有効にし、URLを次のような感じで設定しておきましょう。URLはSSLのみ対応なので、HTTPSに対応したドメインが必要でした

QR画像があるので、右クリックして画像を保存しておきましょう。

余裕があれば、 自動応答メッセージと、友だち追加時あいさつも設定しておくと良いでしょう。

Webhook URLの設定

Webhookは何かというと、ユーザーがメッセージを送信したり、友達追加をしたり、ブロックしたりそれを解除したり、そういった何らかのイベントの際に、好きな処理をフックする仕組みのことです。具体的に言うと、メッセージの送信や友達追加といった操作をされたときに、私達が作ったDjangoのビューを呼び出してもらえます。

今回はこれを利用して、友達登録してくれたユーザーのLineユーザーIDを取得し、データベースに保存しておきます。LineユーザーIDは、プログラム上からLineメッセージを送信する際の宛先のようなものです。そして、記事の更新をした際に、この宛先を使ってDjango上から更新を通知するのです。

まず、次のようなモデルを定義しておきます。LineユーザーIDを保持するためのモデルです。

class LinePush(models.Model):
    """Lineでのプッシュ先を表す"""
    user_id = models.CharField('ユーザーID', max_length=100, unique=True)

    def __str__(self):
        return self.user_id

次に、WebhookのURLとビューを作ります。urls.pyに次を追加して...

path('callback/', views.callback, name='callback')

そして、Webhookを受け取るビューを次のようにします。

import json
from django.http import HttpResponseBadRequest, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from .models import Post, EmailPush, LinePush
...
...
@csrf_exempt
def callback(request):
    """ラインの友達追加時に呼び出され、ラインのIDを登録する。"""
    if request.method == 'POST':
        request_json = json.loads(request.body.decode('utf-8'))
        events = request_json['events']
        line_user_id = events[0]['source']['userId']

        # チャネル設定のWeb hook接続確認時にはここ。このIDで見に来る。
        if line_user_id == 'Udeadbeefdeadbeefdeadbeefdeadbeef':
            pass

        # 友達追加時・ブロック解除時
        elif events[0]['type'] == 'follow':
            LinePush.objects.create(user_id=line_user_id)

        # アカウントがブロックされたとき
        elif events[0]['type'] == 'unfollow':
            LinePush.objects.filter(user_id=line_user_id).delete()

    return HttpResponse()

この段階で、 チャネル基本設定画面に戻り、Webhookの接続確認をしておくと良いでしょう。

購読ページへQR画像を埋め込む

subscribe.htmlに先ほど保存したQR画像を埋め込みます。これで、このウェブページを訪れた人がLineの友達になれるようになります。友達になると↑のビューが呼ばれ、LineユーザーIDを保存でき、それを使って更新通知を送信できる、というのが流れです。

次のように変更しておきましょう。

{% extends 'blog/base.html' %}
{% load static %}
...
...
    <h2>Lineで新着記事を受け取る</h2>
    <p><img src="{% static 'blog/lineqr.png' %}"></p>

ライン通知の送信処理

PythonからLine Message APIを使うためのライブラリをインストールしておきます。

pip install line-bot-sdk

そして、肝心のPostモデル内のメソッドを変更します。

import linebot
from linebot.models import TextSendMessage
...
...
    def line_push(self, request):
        """記事をラインで通知"""
        context = {
            'post': self,
        }
        message = render_to_string('blog/notify_message.txt', context, request)
        line_bot_api = linebot.LineBotApi('先ほど発行したアクセストークン')
        for push in LinePush.objects.all():
            line_bot_api.push_message(push.user_id, messages=TextSendMessage(text=message))

メール通知で作ったテンプレートファイルを再利用しています。それをメッセージとして、LinePushを全て取り出し、一人ずつ通知を送信しています。

この記事の関連記事

Djangoで、Webサイトの更新情報を通知するシリーズ

2019-07-27 / Djangoシリーズ・まとめ

- Webサイトでは、更新をお知らせする機能がよくあります。例えばメールで最新情報を知らせたり、最近ではLineやブラウザのプッシュ通知で更新情報をお知らせする例もよく使われています。

Django、メールで更新を通知

2019-07-27 / PythonDjango

- Djangoで、Webサイトの更新情報を通知するシリーズの一つです。メールで、Webサイトの更新情報を通知していきます。

Django、OneSignalでブラウザ通知

2019-07-27 / PythonDjango

- Djangoで、Webサイトの更新情報を通知するシリーズの一つです。OneSignalを利用してブラウザのプッシュ通知を行い、Webサイトの更新を伝えます。

Djangoで、Line Botを使いつつ1対1のチャット機能

2019-07-30 / PythonDjangoLine

- Botモードを使いつつ、1対1のチャット機能をDjango側の機能を使って実装していきます。

コメント欄

記事にコメントする

mh

はじめまして!いつも拝見させていただいてます。 日本語でここまで丁寧に解説いただけるサイトはなかなか無いので とても勉強になります。

Lineによる更新通知で一点質問なのですが、管理画面から操作するのではなく、 記事を新規投稿したタイミングで自動的に通知する仕組みは可能でしょうか? 実装したいのですがスキル不足なもので手がかりが掴めません汗

いきなり不躾な質問で申し訳ございません。 ご回答いただけると幸いです。

コメントに返信する

なりと

色々な方法があるのですが、シグナルといった機能を利用してみてください。