どうも。つじけ(tsujikenzo)です。このシリーズでは、「スプレッドシートとGASでリッチメニューを管理しよう」をお送りします。今回は3回目で、最終回です。
前回のおさらい
前回は、「リッチメニューオブジェクトのアップロード」をお届けしました。
今回は、「リッチメニュー画像とIDの紐づけ」をお届けします。
今日のアジェンダ
- スプレッドシートのリッチメニュー一覧を更新する
- リッチメニュー画像とリッチメニューIDを紐づける
- リッチメニューをユーザーに送信する
スプレッドシートのリッチメニュー一覧を更新する
復習です。getRichMenuIds()メソッドを実行すると、現在、LINEサーバー上にアップロードされている、全リッチメニューを取得できました。
//アップロードされている全リッチメニューIDの配列を取得する
console.log(r.getRichMenuIds());
// [ { richMenuId: 'richmenu-xxx',
// name: '99_richMenu_test',
// size: { width: 2500, height: 1686 },
// chatBarText: '▲タップしてメニューを表示▲',
// selected: false,
// areas: [ [Object], [Object], [Object] ] } ]
これを、スプレッドシートに出力します。
テスト関数に、リッチメニュー一覧をスプレッドシートに出力するメソッドの呼び出しを記述します。
//リッチメニュー一覧をスプレッドシートに出力する
console.log(r.setValuesRichMenuIds());
クラスにメソッドを実装します。
getRichMenuIds()メソッドで取得した配列の中身はオブジェクトなので、map()メソッドと、Object.values()メソッドの組み合わせで、オブジェクトを配列に展開しています。
また、オブジェクトは、取り出し順が保証されていませんので、リッチメニュー名で降順されるように、ソート処理を行っています。(したがって、リッチメニュー名を付けるときは、「99_richMenu_test」など、先頭に数字を付けて管理することをオススメします。)
/** リッチメニューidsをスプレッドシートに出力するメソッド */
setValuesRichMenuIds() {
const ids = this.getRichMenuIds(); //[]
const values = ids.map(element => { returnObject.values(element) });
//nameで降順ソートする
values.sort((a, b) => { return a[1] < b[1] ? -1 : 1; });
const sheet = SpreadsheetApp.openById("スプレッドシートID").getSheetByName("シート1");
sheet.getRange(2, 5, values.length, values[0].length).setValues(values);
return"スプレッドシートに貼り付けしました";
}
テスト関数を実行しましょう。
スプレッドシートに、リッチメニュー情報が反映されたら成功です。
リッチメニュー画像とリッチメニューIDを紐づける
そして、最後に、リッチメニュー画像と、リッチメニューIDを紐づけます。
テスト関数に、リッチメニュー画像アップロードとリッチメニューIDへの紐づけを行うメソッドを記述します。
リッチメニュー画像は、まだLINEサーバーにアップロードされていませんので、「uploadRichMenuImage()」というメソッド名にしました。
引数に、リッチメニューidと、画像のファイルIDを指定します。
//リッチメニュー画像アップロードとリッチメニューIDへの紐づけを行う
const id = "richmenu-xxx";
const imageId = "ファイルID";
console.log(r.uploadRichMenuImage(id,imageId));
クラスにメソッドを実装します。
画像は、DriveApp.getFileById(ファイルID)メソッドで、blobとして取得します。
/** リッチメニュー画像アップロードとリッチメニューIDへの紐づけを行うメソッド
* @param{string} リッチメニューid
* @param{string} 画像のファイルID
*/
uploadRichMenuImage(richMenuId,imageId) {
const imageBlob = DriveApp.getFileById(imageId);
const url = `https://api-data.line.me/v2/bot/richmenu/${richMenuId}/content`;
const headers = {
'Content-Type': 'image/jpeg',
'Authorization': 'Bearer ' + this.ACCESS_TOKEN,
};
const options = {
'headers': headers,
'method': 'post',
'payload': imageBlob
};
const response = UrlFetchApp.fetch(url, options);
const statusCode = response.getResponseCode();
return`[${statusCode}]リッチメニュー画像をアップロードしました`
}
テストメソッドを実行しましょう。
ステータスコードを含む、メッセージが取得できていれば、成功です。
// [200]リッチメニュー画像をアップロードしました
リッチメニューをユーザーに送信する
ユーザーにリッチメニューを送信することを、公式では「リンクする」と呼んでいます。
サーバー側からすると、ユーザーIDと、リッチメニューIDを紐づけるという行為になるからです。
テスト関数に、ユーザーにリッチメニューをリンクするメソッドの呼び出しを記述します。
引数に、リッチメニューIDと、ユーザーIDを指定します。
//ユーザーにリッチメニューをリンクする
const richMenuId = "richmenu-xxx";
const userId = "ユーザーID";
console.log(r.sendRichMenuToUser(richMenuId, userId));
もし、ユーザーIDを取得できていないばあいは、このようなウェブアプリをデプロイして、ユーザーIDを取得しましょう。
/** メッセージが送付された際に、実行される関数 */
function doPost(e) {
const event = JSON.parse(e.postData.contents).events[0];
const userMessage = event.message.text;
const timestamp = Utilities.formatDate(newDate(event.timestamp), "JST", "yyyyMMdd_hh:mm:ss");
const userId = event.source.userId;
GmailApp.sendEmail("メールアドレス", "メッセージが送信されました", [userId,timestamp,userMessage]);
}
クラスにメソッドを実装します。
/** ユーザーにリッチメニューをリンクする
* @param{string} リッチメニューID
* @param{string} ユーザーID
* ※ただし、RichMenuImageが紐づいてないと送信不可
*/sendRichMenuToUser(richMenuId, userId) {
const url = `https://api.line.me/v2/bot/user/${userId}/richmenu/${richMenuId}`;
const headers = {
'Authorization': 'Bearer ' + this.ACCESS_TOKEN,
};
const options = {
'headers': headers,
'method': "post",
};
const response = UrlFetchApp.fetch(url, options);
const statusCode = response.getResponseCode();
return`[${statusCode}]ユーザーにリッチメニューを送信しました`
}
スマホのLINEに、リッチメニューが送信されたら成功です。(PC版のLINEには対応しておりません。※2023年1月)
それぞれの領域をタップして、動作を確認しましょう。
まとめ
以上で、「リッチメニュー画像とIDの紐づけ」をお届けしました。
このように、GASでリッチメニューを操作できるようになると、時限トリガーを組んだ関数を作成し、月曜日と金曜日はクーポン付きリッチメニューを配信する、といったことを自動化できます。
また、今回はユーザーIDやリッチメニューIDなどをリテラル(ソースコードに直接記述すること)に記述しましたが、ユーザーIDテーブルや、属性別リッチメニューテーブルなどをスプレッドシートで作成し、動的に更新される特定のユーザーにのみリッチメニューを配信することが可能です。
みなさんのリッチメニュー活用アイディアを、ぜひお待ちしております!