Messaging APIをご利用の皆様こんにちは。
今回はMessaging APIでURLをユーザーに送信した場合の、
URLプレビューについて調べてみました。
表示内容の制御方法
以下のFAQにもあるとおり、LINEのURLプレビューはOGPの規格に準拠するようです。
https://developers.line.biz/ja/faq/#how-are-the-url-previews-generated
対応しているパラメータは
og:title
og:description
og:image
のみようです。
こんな感じでOGPの制御ができるようです。
<!DOCTYPE html>
<html lang="ja">
<meta property="og:title" content="title:URLプレビューテスト">
<meta property="og:description" content="description:URLプレビューテスト">
<meta property="og:image" content="https://placehold.jp/d92733/ffffff/150x150.png?text=LINE%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B9%E3%83%88">
<head>
<meta charset="utf-8">
</head>
<body>
</body>
</html>
OGPのキャッシュ
LINEアプリで表示したURLプレビューについては、キャッシュが作成されるようです。
一度キャッシュが作成された場合、しばらく経過しないと新しいOGPタグが反映されないようです。
キャッシュにはLINEアプリ側と、LINEサーバー側の2種類があるようで、
片方でもキャッシュが残ってる場合、一定期間OGPタグ情報の再取得を行わないようです。
ただし、以下の方法でキャッシュを削除することで、新しいOGPタグを即時に反映させることができる
場合があるようです。(双方実施する必要があります。)
LINEアプリ本体のキャッシュを削除する
iOSの場合:
LINEアプリの設定 > トーク > データの削除 > キャッシュデータ
Androidの場合:
OSのアプリ > LINE >ストレージとキャッシュ > キャッシュを削除
LINEサーバー側のキャッシュを削除する
これは不可能かと思いきや、いつの間にか以下のような公式ツールが公開されていました。
https://poker.line.naver.jp/
このサイトはプレビューも確認できるので便利だとおもいます。
上記FAQページにリンクがありました。
利用方法は見たまんま、URLを指定してClear Cacheするだけです。
Clear Cacheした後、LINEのクローラーがOGPの再取得にアクセスしてきました。
[27/May/2021:14:44:20 +0000] "GET /login-url-preview-test2 HTTP/1.1" 302 801 "-" "facebookexternalhit/1.1;line-poker/1.0"
応用編
LINEのOGPを取得するクローラーのユーザーエージェントは
"facebookexternalhit/1.1;line-poker/1.0" です。
このUAからのアクセスの場合にユーザーがアクセスするページのHTMLとは別の
HTMLをレスポンスすることで、プレビュー内容をカスタマイズできます。
例えば、以下のURLではLINEログインの認可リクエストへのリダイレクトを行っています。
https://myucy.herokuapp.com/login-url-preview-test2
この場合のURLプレビューは、以下のようにLINEのログインページのものが表示されるので
UX的にはあまり良くないです。
以下のURLでは上記と同じくLINEログインの認可リクエストへのリダイレクトを行っていますが、
LINEクローラーからのアクセス時のみ、処理を変更しています。
すると、以下のように表示をカスタマイズできます。
こうすることでユーザーに不信感を与えにくいUXを実現できます。
https://myucy.herokuapp.com/login-url-preview-test
Flaskを使った処理の例です。
from argparse import ArgumentParser
from flask import Flask, request, abort, render_template, jsonify, redirect, session, make_response
import secrets
import base64
import hashlib
import urllib.request
app = Flask(__name__,static_folder='static')
@app.route('/login-url-preview-test', methods=['GET'])
def LoginUrlPreview():
#LINEクローラーのみ処理を変更
if request.headers.get('User-Agent') == "facebookexternalhit/1.1;line-poker/1.0":
return render_template('login-url-preview-test.html')
code_verifier = secrets.token_urlsafe(48)
code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode('utf-8')).digest()).decode('utf-8').strip('=')
queries = {}
queries['response_type'] = "code"
queries['client_id'] = "1654102793"
queries['redirect_uri'] = "https://example.com"
queries['scope'] = "profile"
queries['state'] = secrets.token_urlsafe(32)
queries['code_challenge_method'] = "S256"
queries['code_challenge'] = code_challenge
authorize_url = 'https://access.line.me/oauth2/v2.1/authorize?' + \
urllib.parse.urlencode(queries)
return redirect(authorize_url)
login-url-preview-test.html
<!DOCTYPE html>
<html lang="ja">
<meta property="og:title" content="title:URLプレビューテスト">
<meta property="og:description" content="description:URLプレビューテスト">
<meta property="og:image" content="https://placehold.jp/d92733/ffffff/150x150.png?text=LINE%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B9%E3%83%88">
<head>
<meta charset="utf-8">
</head>
<body>
</body>
</html>