こんにちわ。西田@リテールアプリ共創部マッハチームです
今回はLINEのサービスメッセージをTypeScriptで作成されたLINEミニアプリから送信してみます
参考: サービスメッセージを送信する
LINEサービスメッセージの概要
LINEミニアプリ上のユーザーの操作に対する確認、応答としてLINEミニアプリから送信できるメッセージです。無料(メッセージ通数カウントされない)で送信でき、1つのメッセージで最大5つまでの吹き出しを送信することが可能です。
具体的なユースケースとしては、LINEミニアプリからホテルの宿泊予約をした場合に、予約の完了時に予約完了をお知らせするメッセージを送信し、後日予約している日の前日にリマインドするメッセージを送信するなどがあります
禁止事項
ユーザーの操作に対する応答の用途以外のメッセージを送信することは禁止されています。例えばプロモーションやイベントの告知などをサービスメッセージで送信することはできません。もし送信してしまうと、一定期間サービスメッセージを送信できなくなったり、使用できなくなったりします
テンプレート
サービスメッセージを送信する際は必ずテンプレートを使用する必要があります。テンプレートはあらかじめ用意されたテンプレートがあり、その中から選んでLINEミニアプリチャネルに追加する必要があります。 テンプレートをLINEミニアプリチャネルに追加するには審査が必要で、審査が通るまでは、そのテンプレートを使ってサービスメッセージを送信することはできません
ただし、審査中のテンプレートでもテストユーザー(LINE Developersコンソールで、LINEミニアプリのチャネルに招待されてるユーザー)には、 LINE Developersコンソール上から、もしくは、LINEの サービスメッセージを送る APIから送信できます
送信トークルーム
送信されたサービスメッセージは、「LINEミニアプリ お知らせ」に送信されます
メッセージを送信する
大まかな流れ
- チャネルアクセストークン を発行する
- ユーザーのアクセストークンを受け取る
- サービス通知トークンを発行する
- サービスメッセージを送る
LINEミニアプリチャネルアクセストークンを発行
サービス通知トークンを発行するのに必要なLINEミニアプリのチャネルアクセストークンを発行します
LINEミニアプリのチャネルアクセストークンの発行には、チャネルIDとチャネルシークレットがそれぞれ必要で、LINE DeveloopersコンソールのLINEミニアプリ画面の「チャネル基本情報」タブから確認することができます
チャネルIDを取得します。
今回はテストユーザーにのみ送信するので開発用のIDを使います
チャネルシークレットを取得します
TypeScriptでLINEミニアプリチャネルアクセストークンを発行
取得したチャネルID、チャネルシークレットを環境変数から取得できるようにして、それらを使ってチャネルアクセストークン発行エンドポイントを呼び出します
export async function issueChannelAccessToken() {
const response = await fetch("https://api.line.me/oauth2/v3/token", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: process.env.LINE_MINIAPP_CHANNEL_ID!,
client_secret: process.env.LINE_MINIAPP_CHANNEL_SECRET!,
}),
});
if (!response.ok) {
const text = await response.text();
throw new Error(
`Failed to issue access token: ${response.statusText} ${text}`
);
}
const body = (await response.json()) as {
access_token: string;
expires_in: number;
};
return body;
}
ユーザーのアクセストークンを受け取る
LINEサービスメッセージは、LINEミニアプリ上の操作に対する応答メッセージなので、送信するにはLINEミニアプリ上で発行できるユーザーのアクセストークンが必要です。以下はReactでLIFFを使ってアクセストークンを送信する例です。liffAccessTokenというパラメーターでアクセストークンをAPIに渡しています
import liff from "@line/liff";
import { config } from "./config";
function App() {
const sendServiceMessage = async () => {
fetch(config.apiUrl + "service-message", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
liffAccessToken: await liff.getAccessToken()!,
}),
});
};
return (
<>
<button onClick={sendServiceMessage}>
サービスメッセージ
</button>
</>
);
}
export default App;
サービス通知トークンを発行する
LINEミニアプリチャネルのアクセストークンと、ユーザーから取得したLIFFアクセストークンを使って、サービスメッセージ送信用のトークンを発行します
export async function issueServiceMessageNotificationToken(
liffAccessToken: string
) {
const channelAccessToken = (await issueChannelAccessToken()).access_token;
const response = await fetch(
"https://api.line.me/message/v3/notifier/token",
{
method: "POST",
headers: {
Authorization: `Bearer ${channelAccessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
liffAccessToken: liffAccessToken,
}),
}
);
if (!response.ok) {
const text = await response.text();
throw new Error(
`Failed to get service message notification token: ${response.statusText} ${text}`
);
}
const body = (await response.json()) as {
notificationToken: string;
};
return body;
}
サービスメッセージを送信
LINEミニアプリのチャネルアクセストークンと、サービス通知トークンを使ってサービスメッセージを送信します
export async function sendServiceMessage({
templateName,
params,
notificationToken,
}: {
templateName: string;
params: { [key: string]: string };
notificationToken: string;
}) {
const channelAccessToken = (await issueChannelAccessToken()).access_token;
const response = await fetch(
"https://api.line.me/message/v3/notifier/send?target=service",
{
method: "POST",
headers: {
Authorization: `Bearer ${channelAccessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
templateName,
params,
notificationToken,
}),
}
);
if (!response.ok) {
const text = await response.text();
throw new Error(
`Failed to send service message: ${response.statusText} ${text}`
);
}
}
画面からの呼び出し部分を作成
下記は express を使った例です、画面(React)からアクセストークンを呼び出し、これまでに作成したLINEサービスメッセージ送信APIを呼び出しています。パラメーターはサンプルの値です
app.use(express.json());
app.post("/service-message", async (req, res) => {
const { liffAccessToken } = req.body;
const { notificationToken } = await issueServiceMessageNotificationToken(
liffAccessToken
);
await sendServiceMessage({
templateName: "restock_d_ja",
params: {
price: "400円",
number: "1357",
address: "東京都新宿区新宿4-1-6",
btn1_url: "https://line.me",
btn2_url: "https://line.me",
btn3_url: "https://line.me",
btn4_url: "https://line.me",
reg_date: "2033/8/22 0:00",
shop_name: "ブラウン新宿店",
instock_date: "2033/8/22 0:00",
product_name: "Tシャツ",
},
notificationToken,
});
res.send("OK");
});
最後に
この記事が誰かの役に立てば幸いです