LINEプラットフォームの導入と運用
この記事は MICIN Advent Calendar 2023 の 8 日目の記事です。
前回は高橋さんの、「脆弱性の早期検知と管理を内製化してみた」 でした。
MICIN では LINE プラットフォーム(以下,LINE PF)を様々な場面で導入・活用しています。
- curon,curon お薬サポート,クロンスマートパスの患者向けアプリケーションへの LINE ログイン導入
- curon お薬サポートで LINE へのメッセージ配信
- 自費オンライン診療ピルマルの患者向けインターフェースとしての活用
- 企業が運用する LINE 公式アカウントとのサービス連携
LINE は月間ユーザー数 9,500 万人[1]で,スマホユーザーの大半がインストールしているアプリです。IT 慣れしていないユーザーでも,LINE の画面は抵抗なく触れられるという方は少なくありません。高水準のアクセシビリティが求められる医療領域の Web アプリケーション開発において,LINE の活用は非常に魅力的なソリューションです。
LINE PF の詳細な仕様は公式ドキュメントに詳しく記載があります。本記事では機能の詳細な説明はできるだけ省き,LINE PF の活用を考えている方々に向けて,その概観を要所に絞って紹介します。
LINE PF を使う理由は?
MICIN での LINE PF の活用メリットは以下の 2 つです。
ユーザー体験の向上
- ログイン時にメアド・パスワードの入力が不要
- Web アプリケーションでも LINE にプッシュ通知を送れる
サービスのリピート率向上
- LINE 上に自社サービスへの導線を設けられる(ユーザーのブックマークや再検索が不要になる)
- プッシュ通知やメッセージ配信を通じてサービスの再利用を促進
MICIN は上記のメリットを得るために,LINE ログイン・メッセージ配信・LINE のトーク画面を活用しています。以下では各機能の導入と運用について説明します。
LINE ログイン
LINE ログインは文字通り,LINE のユーザー情報で自社の Web アプリケーション認証を行う機能です。OIDCプロトコルとOAuth 2.0 の認可コード付与のフローに基づいて処理が行われます。
処理の流れ
大まかな処理としては以下の 6 ステップに分類されます。
- Web アプリケーションからパラメータを付与の上,LINE ログインの承認画面に遷移
- 認証成功後にコールバック URL に遷移
- コールバック URL に含まれる
code
を用いて JWT 形式のtoken
取得を LINE にリクエスト -
token
をデコードしてユーザー関連情報を取得 - ユーザーの作成 or 取得
find_or_create
- セッションの保存
手順 3 で取得できるtoken
には LINE からプロバイダー単位で発行される,ユーザー ID が含まれます。また手順 6 において,サーバー上でセッションを保存することで,再認証することなくサービスを利用できます。
設定が必要な項目
コールバック URL
LINE 認証完了後の遷移・リクエスト先です。Web アプリケーションから公開用 URL を作成の上,前述の手順 1 でリクエストパラメーターに設定します。
コールバック URL は手順 3 でも利用します。この際に URL が手順 1 のリクエスト時に設定したコールバック URL と完全一致している必要があり,手順 1 と 3 で異なるパラメーター設定はできません。
Scope
手順 1 で LINE から取得したい情報をリクエストパラメーターで指定します。以下の情報を選択・取得可能です。
- プロフィール
- ユーザー ID
- プロフィール画像
- LINE の表示名
- メールアドレス(※取得に申請が必要)
公式アカウントの追加
LINE ログインの際に,公式アカウントの友達追加を同時に行うことができます。curon でも LINE ログイン導入以降,LINE 公式アカウントのユーザー数が大幅に増加しました。リクエストパラメーターbot_prompt
の設定によって,LINE ログイン時の画面表示が異なります。
運用上の注意点
メッセージ機能
LINE PF ではメッセージの配信方法が大きく 3 つの形式に分かれます。
LINE 公式アカウントの 管理画面 |
Messaging API | サービスメッセージ ※LINE ミニアプリお知らせ |
|
---|---|---|---|
利用条件 | 管理画面へのアクセス権 | ユーザー ID とチャネルアクセストークンの取得 | LINE ミニアプリの開設 |
送信トリガー | チャット画面から任意のタイミングで送信 自動応答メッセージ AI 応答メッセージ |
自由に設定可能 | LINE ミニアプリ上でユーザー操作に対する応答としてのみ送信 |
メッセージの配信先 | 公式アカウント | 公式アカウント | 「LINE ミニアプリ お知らせ」のアカウント ※全ての LINE ミニアプリで共通利用 |
配信対象 | ① 公式アカウントを友達追加した全員 ② 特定のユーザー群(年齢,性別等のカスタムセグメント) |
① 公式アカウントを友達追加した全員 ② 特定のユーザー群(年齢,性別等のカスタムセグメント) ③ 任意のユーザー |
任意のユーザー |
メッセージの受信 | 可能 ※チャット機能 on の場合のみ |
可能 ※webhook の設定必須 |
N/A |
Messaging API
自社のサーバーから任意のタイミングでメッセージを送りたい場合,Messaging API を利用することになります。ユーザー ID を指定して特定のユーザーへのメッセージ送信や,複数人への一斉送信も可能です。
Messaging API を利用する注意点としては大きく以下の 4 つです。
- メッセージの送信先は公式アカウントとユーザーのトーク画面
- メッセージ配信数に応じた従量課金(※1 ヶ月に 200 通まで無料)
- ユーザー ID とチャネルアクセストークンの取得が必要(後述)
- webhook で受け取ったメッセージに対する返信の場合は従量課金対象外(無料)
メッセージ送信のインターフェース自体は非常にシンプルで,以下のステップですぐに機能を試すことができます。
- LINE Developer コンソールから Messaging API のチャネルを開設
- 開設したチャネルから
チャネルシークレット
を取得して環境変数に設定 -
https://api.line.me/v2/bot/message/push
に必須となるヘッダーやボディ情報を付与してリクエスト
以下は Ruby on Rails での実装例です。
※ログ保存の処理等を入れており,冗長な書き方になっています。
# 呼び出し元
# ※Userテーブル内にline_user_idを保持しており,このidで送信先を指定します
messenger = Line::Messenger.new(user:)
message = { type: 'text', text: 'test message' }
messenger.send_message(message, SecureRandom.uuid)
# app/models/line/messenger.rb
class Line::Messenger
include ActiveModel::Model
validates :user, presence: true
def initialize(user: nil)
@user = user
end
def send_message(message, retry_key)
requester = Util::LineMessaging::Request.new
response = requester.send_message(
retry_key:,
to: user.line_user_id,
messages: [message],
)
raise Exceptions::LineMessagingFailure, response.error_message if response.status != 200
# メッセージログをDBに保存
LineMessagingLog.create!(
user:,
retry_key:,
text: log_text(message),
line_request_id: response.line_request_id,
)
true
end
private
def log_text(message)
return message[:altText] if message[:type] == 'flex'
return message[:text] if message[:type] == 'text'
''
end
attr_reader :user
end
# lib/util/line_messaging.rb
module Util::LineMessaging
BASE_URL = 'https://api.line.me'.freeze
Response = Struct.new(
:status,
:error_message,
:line_request_id,
keyword_init: true,
)
class Request
def send_message(retry_key:, to:, messages:, notification_disabled: false)
requester = Faraday.new(url: BASE_URL) do |builder|
builder.request :json
builder.response :json
builder.adapter Faraday.default_adapter
end
headers = {
'Content-Type' => 'application/json',
'Authorization' => "Bearer #{ENV.fetch('LINE_MESSAGING_CHANNEL_ACCESS_TOKEN')}",
'X-Line-Retry-Key' => retry_key, # 任意の方法で生成した16進表記のUUID eg.) 123e4567-e89b-12d3-a456-426614174000
}
params = {
to: to, # LINEログイン等を用いて取得したuser_idを指定
messages: messages,
notificationDisabled: notification_disabled,
}
resp = requester.post 'v2/bot/message/push', params do |request|
request.headers = headers
end
Response.new(
status: resp.status,
error_message: resp.body['message'],
line_request_id: resp.headers['x-line-request-id'],
)
end
end
end
メッセージタイプ
Messaging API ではメッセージのカスタマイズも可能です。テキストだけでなく,画像や音声メッセージの送信はもちろんのこと,複数のメッセージタイプを組み合わせた「Flex Message」も作成可能です。
Flex Message を作成する際には,ブラウザ上で動作するシミュレーターを利用して,UI を確認しながらメッセージのカスタマイズが行えます。
シミュレーターの UI
Webhook
公式アカウントのトーク画面でユーザーが何かしらのアクション(テキストやスタンプの送信等)を行うと,LINE PF から登録済みの Webhook URL に HTTPS POST リクエストが行われます。
自社の API サーバーを用いてインタラクティブなコミュニケーションを行いたい場合,Webhook 用の公開 URL を用意して,LINE Developers の管理画面から URL 登録を行います。
以下は Ruby on Rails で作成する場合の実装例です。
# config/routes.rb
Rails.application.routes.draw do
namespace :users do
namespace :webhooks do
namespace :line do
post 'receive'
end
end
end
end
# app/controllers/users/webhooks/line_controller.rb
class Users::Webhooks::LineController < ApplicationController
def receive
return head :bad_request unless check_signature
return head :ok if params[:events].blank?
user = User.find_by(line_user_id:) # ユーザーが登録済みかを検証
return head :ok unless user
return text_action(user) if message_params[:type] == 'message'
return postback_action(user) if message_params[:type] == 'postback'
head :ok
end
private
# 署名の検証
def check_signature
CHANNEL_SECRET = '...' # Channel secret string
http_request_body = request.raw_post # Request body string
hash = OpenSSL::HMAC::digest(OpenSSL::Digest::SHA256.new, CHANNEL_SECRET, http_request_body)
request.headers['X-Line-Signature'] == Base64.strict_encode64(hash)
end
def text_action(user)
case receive_message
when '登録情報'
# 任意の処理
when '予約状況'
# 任意の処理
else
# 任意の処理
end
end
def postback_action(user)
# 任意のアクション
end
def message_params
params.require(:events)[0].permit(:type, :replyToken, message: [:type, :text], source: [:userId], postback: [:data])
end
def receive_message
message_params[:message][:text]
end
def line_user_id
message_params[:source][:userId]
end
def action_params
query_string = message_params[:postback][:data]
URI.decode_www_form(query_string).to_h
end
end
Messaging API では Flex Message 等を用いて作成したボタンや画像に対してアクションオブジェクトの指定ができます。その中でポストバックアクションを利用すると,上記のように任意のパラメーターを Webhook のエンドポイントに送信できます。
ピルマルでもこの仕組みを用いて予約の取得 → 確認 → 確定の一連のフローを LINE のトーク画面でインタラクティブに行っています。
予約の取得 Web アプリケーション |
確認 → 確定 LINE トーク画面 |
---|---|
上記左の画像で日時を選択すると,LINE トーク画面に選択した日時の情報が Flex Message の形式で送られます。右の画像の「予約を確定する」ボタンには,ポストバックアクションで予約日時が変数として保持されており,ボタンを押すことで Webhook 内で予約の確定処理と後続のメッセージ送信が行われる仕組みです。
サービスメッセージ
サービスメッセージは LINE ミニアプリでのみ利用可能なメッセージ機能です。メッセージ配信自体は無料となりますが,配信先が全ての公式アカウント共通で「LINE ミニアプリ お知らせ」というトーク画面になります。
メッセージ管理・運用
ピルマルのように Messaging API を多用しているサービスでは,トーク内容の確認がカスタマーサポートやデバッグなどの観点で欠かせません。Messaging API で送信したメッセージは LINE 公式アカウントのチャット機能からも確認可能です。一方でトークの中身には住所氏名などの個人情報も含まれるため,アクセス権を必要最低限にを絞る必要があります。
そこで,ピルマルでは以下の方針でメッセージ管理・運用を行っています。
- ユーザーの問い合わせ窓口は原則メールと電話を利用
- 管理画面上でのチャット返信は原則行わない
- 管理画面上へのアクセス権は運用担当者など必要最小限に絞る
- DB には API サーバー経由で送信したメッセージを暗号化して保存
- 医師 → 患者への予約キャンセル通知等,必要な機能に限ってメッセージ送信用の UI を実装
企業対ユーザーの関係において,1 人の担当者が対応できるユーザー数には限界があります。Messaging API は従量課金という特性も踏まえて,できる限り効率的かつ,ユーザー体験を損ねない設計を意識した管理・運用を実施しています。
フロントエンドの比較
自社でサーバーサイドの API を開発・運用している前提で,LINE PF を活用した Web アプリケーションのフロントエンドの特徴をまとめました。
一般的な Web アプリケーション | LINE 公式アカウント |
LINE ミニアプリ |
LIFF アプリ |
|
---|---|---|---|---|
UI/UX | 自由に設計 | トーク画面 リッチメニュー |
自由だが一部制限有 | 自由だが一部制限有 |
ホスティング | 必須 | 不要 | 不要 | 不要 |
審査 | 不要 | 不要 | 必須 | 不要 |
ブラウザ | Chrome, Safari など | 不要 | LIFF ブラウザ | LIFF ブラウザ |
利用導線 | ブックマーク,検索 | LINE の友達一覧 | LINE トーク画面 | LINE トーク画面 |
外部サイトへの遷移 | 可能 | 可能 | 制限有り | 制限有り |
ユースケース | 小〜大規模の開発 | 予約,チャットなど限定された機能開発 | 小〜中規模の開発 | 小〜中規模の開発 |
LINE PF を用いたフロントエンド開発
機能要求の側面だけ考えると,LINE PF を用いたフロントエンド開発は UI/UX,ホスティング,ブラウザなどの制限事項が少なくありません。特にLIFF ブラウザではデバイスのハードウェアに関する機能(カメラや Bluetooth へのアクセス)に制限事項が多いです。
開発・運用工数の観点では,フロントエンドをホスティングするサーバーを LINE が用意してくれている点で,運用が楽という考え方もできます。しかし一般的な Web アプリケーションに比べて LINE PF を用いた開発工数に大きな違いはありません。むしろ LINE PF 独自の API や仕様の理解が必要という点では,工数が多少増える印象です。
一方でサービスを一度利用すれば LINE 上から再アクセスしやすいという点は,URL ベースの Web アプリケーションには無いメリットです。
MICIN での LINE PF の活用
MICIN のサービスでもこれらの特性を考慮して,自前での Web アプリケーション+公式アカウント+Messaging API の構成でプロダクトの開発・運用を行っています。
サービス名 | サービスの基本機能 ※LINE 外で実装 |
サービスの 認証方式 |
LINE PF の利用目的 |
---|---|---|---|
クロンお薬サポート | 予約,ビデオ通話,決済,配送 | メアド・LINE・Apple | LINE ログインした場合,メールの代わりとして LINE に通知 |
ピルマル | 予約,決済 | LINE のみ | LINE ログインでの認証 チャットでの機能利用誘導 個人情報・配送情報の表示 UI |
LIFF アプリと LINE ミニアプリの違い
LINE ミニアプリと LIFF アプリは,LIFF(LINE Front-end Framework)上で実行される、ウェブアプリケーションです。その違いは大きく以下の 3 点です。
LIFF アプリ | LINE ミニアプリ | |
---|---|---|
公開審査 | 不要 | 必須 |
サービスメッセージの利用 | 不可 | 可能 |
LINE アプリ上からの検索 | 不可 | 可能 |
LINE PF の活用を進める上で
LINE PF は多岐にわたるソリューションを提供していることもあり,ソリューションの取捨選択や理解に時間がかかります。特に仕様の理解・共有という面ではエンジニアが詳細を確認し,メリット・デメリット,できること・できないことをプロダクトマネージャーやデザイナー,場合によってはビジネスサイドのメンバーにもインプットしなければなりません。
弊社でも公式ドキュメントの度重なる確認,社内向けの機能比較ドキュメントの作成を行い,MTG を重ねる中でメンバー内での LINE PF に関する理解度を深めています。本記事はその中で整理された知見をまとめて執筆しました。本記事を通じて,皆様の LINE PF を用いたプロダクト開発や事業開発が促進されると幸いです。
MICIN ではメンバーを大募集しています。
「とりあえず話を聞いてみたい」でも大歓迎ですので、お気軽にご応募ください!
MICIN 採用ページ:https://recruit.micin.jp/
Discussion