Django ✕ LINE Messaging APIで簡易的なユーザー登録を作成する②
LINE Bot開発では、LINEユーザーの管理が必要となってくる場面があります。今回、LINEでできるスタンプラリーの開発に携わった関係でそのあたりの内容をまとめたいと思います。
前回はモデル作成とViewでのプログラム記述についてお伝えしました。
今回は具体的な例を用いてユーザーの登録フローを作成します。

目次
前提
この記事では以下の技術を使います:
- Django
- LINE Messaging API
設定の仕方
リプライメッセージを送信する部分を作成
まずは、リプライメッセージを送る部分を定義します。
以下は1つのリプライメッセージを送る関数です。
# リプライメッセージを送信する関数
def reply_message(reply_token, message):
url = "https://api.line.me/v2/bot/message/reply"
headers = {"Content-Type": "application/json", "Authorization": f"Bearer {LINE_CHANNEL_ACCESS_TOKEN}"}
data = {
"replyToken": reply_token,
"messages": [{"type": "text", "text": message}]
}
response = requests.post(url, headers=headers, json=data)
if response.status_code != 200:
print(response.status_code, response.text)
return response以下は1つのメッセージと1つのFlex Messageを送るための関数です。
# メッセージとFlex Messageを送信する関数
def reply_two_message(reply_token, first_message, alt_text, flex_message):
url = "https://api.line.me/v2/bot/message/reply"
headers = {"Content-Type": "application/json", "Authorization": f"Bearer {LINE_CHANNEL_ACCESS_TOKEN}"}
data = {
"replyToken": reply_token,
"messages": [
{
"type": "text",
"text": first_message
},
{
"type": "flex",
"altText": alt_text,
"contents": flex_message
}
]
}
response = requests.post(url, headers=headers, json=data)
if response.status_code != 200:
print(response.status_code, response.text)
return responseWebhookを受け取り、条件分岐させる部分の作成
Webhookを受け取り、条件分岐をする部分を記述します。
ユーザーのリクエストに応じて処理を分岐させます。友だち登録の処理はevent[“type”] == “follow”です。
# LINEのWebhookを受け取る
@csrf_exempt
def line_webhook(request):
body = json.loads(request.body.decode("utf-8"))
for event in body.get("events", []):
reply_token = event["replyToken"]
line_id = event["source"]["userId"]
# ユーザーが初めて登録した場合
if event["type"] == "follow":
# ユーザーが登録した際の処理
user, created = User.objects.get_or_create(line_id=line_id)
# Postback イベントの処理
elif event["type"] == "postback":
postback_data = event["postback"]["data"]
# ユーザーがDBに登録されていればuserに変数を定義、
try:
user = User.objects.get(line_id=line_id)
except User.DoesNotExist:
user, created = User.objects.get_or_create(line_id=line_id)
continue
# ユーザーがメッセージを送信した場合
elif event["type"] == "message" and event["message"]["type"] == "text":
message = event["message"]["text"]
try:
user = User.objects.get(line_id=line_id)
except User.DoesNotExist:
user, created = User.objects.get_or_create(line_id=line_id)
continue会員登録の部分のフローを作成
ニックネーム登録 → 利用規約の同意 → 登録完了 のフローを作成したプログラムです。
ニックネームを登録はキーボードから行うため処理はevent[“type”] == “message”の中で行います。
それ以外はPostbackイベントを活用します。
ユーザーの登録状態はuser.statusで処理分岐します。
# LINEのWebhookを受け取る
@csrf_exempt
def line_webhook(request):
body = json.loads(request.body.decode("utf-8"))
for event in body.get("events", []):
reply_token = event["replyToken"]
line_id = event["source"]["userId"]
# ユーザーが初めて登録した場合
if event["type"] == "follow":
user, created = User.objects.get_or_create(line_id=line_id)
user.status = "awaiting_name"
user.save()
first_message = "はじめまして!〇〇スタンプラリーです👀🥳"
reply_two_message(reply_token, first_message, "ニックネームを教えて下さい", name_message)
# Postback イベントの処理
elif event["type"] == "postback":
postback_data = event["postback"]["data"]
try:
user = User.objects.get(line_id=line_id)
except User.DoesNotExist:
user, created = User.objects.get_or_create(line_id=line_id)
reply_flex_message(reply_token, "ニックネームを教えて下さい", name_message)
continue
if user.status == "awaiting_name":
reply_flex_message(reply_token, "ニックネームを教えて下さい", name_message)
elif user.status == "awaiting_agreement":
reply_flex_message(reply_token, "利用規約の確認", privacy_policy_message)
elif user.status == "complete":
# 会員登録が終わったあとの処理を行う
# ユーザーがメッセージを送信した場合
elif event["type"] == "message" and event["message"]["type"] == "text":
message = event["message"]["text"]
try:
user = User.objects.get(line_id=line_id)
except User.DoesNotExist:
user, created = User.objects.get_or_create(line_id=line_id)
reply_flex_message(reply_token, "ニックネームを教えて下さい", name_message)
continue
if user.status == "awaiting_name":
if message == "この名前で登録する":
if not user.temp_name:
reply_flex_message(reply_token, "ニックネームを教えて下さい", name_message)
continue
else:
user.name = user.temp_name
user.status = "awaiting_agreement"
user.temp_name = ""
user.save()
reply_flex_message(reply_token, "利用規約の確認", privacy_policy_message)
elif message == "別の名前にする":
user.temp_name = ""
user.save()
reply_message(reply_token, "もう一度トークにお名前を入力して送信してください(左下のキーボードマーク)")
else:
user.temp_name = message # 一時保存
user.save()
flex_message = {
"type": "bubble",
"body": {
"type": "box",
"layout": "vertical",
"contents": [
{
"type": "text",
"text": f"「{message}」で登録しますか?",
"weight": "bold",
"size": "lg",
"wrap": True
},
{
"type": "text",
"text": "※変更できません",
"size": "sm",
"color": "#999999",
"margin": "md"
},
{
"type": "box",
"layout": "vertical",
"spacing": "md",
"margin": "lg",
"contents": [
{
"type": "button",
"style": "primary",
"color": "#4CAF50",
"action": {
"type": "message",
"label": "この名前で登録する",
"text": "この名前で登録する"
}
},
{
"type": "button",
"style": "secondary",
"action": {
"type": "message",
"label": "別の名前にする",
"text": "別の名前にする"
}
}
]
}
]
}
}
reply_flex_message(reply_token, "ニックネーム確認", flex_message)
elif user.status == "awaiting_agreement":
if message == "利用規約に同意して進む":
user.agreed = True
user.status = "complete"
user.save()
first_message = f"{user.name}さん、登録が完了しました!メニューを開いて、スタンプラリーをお楽しみください🎉\n参加方法はメニューから👇"
messages = [
first_message,
"ぜひHPもご覧ください!",
]
reply_multi_message(reply_token, messages)
else:
reply_flex_message(reply_token, "利用規約の確認", privacy_policy_message)
elif user.status == "complete":
# 会員登録が終わったあとの処理を行う
return JsonResponse({"status": "ok"})サンプル例通りにプログラムすると以下のようになります

あわせて読みたい


第1話:WordPressじゃ物足りない!?LINE✕鬼太鼓スタンプラリー開発のはじまり
私は、友達の紹介でさどんでこプロジェクトのIT担当として様々システム構築などを行っています。今回、スタンプラリー作成でかなり大変だったということから、開発秘話…

コメント