記事内に広告が含まれています。

ノンプログラマーが作る【GASでLINE構築】公式アカウント⑤複合リッチメニューを実装しよう前編

【GAS・LINE】自治会・町内会編

こんにちは!アナログな町内会運営を変えるべく、「GASで機能拡張した町内会公式LINE」を作りました。たくさんの記事を参考にしながら、オープンソースの文化に触れる中で、助け合いの大切さを実感しつつ、ようやく完成させることができました。

Pay forwardの精神で、これから町内会LINEに追加した機能をシリーズで紹介していきます。初心者なので完璧なコードではないかもしれませんが、少しでも役に立てば嬉しいです!

なお、ブログ通りに作業してもうまく動かない方のために、「ココナラ」でサポートを提供しています。良かったらご覧くださいね♪

GASを用いたLINE構築のサポートをします ブログの説明だけではうまくいかない人向け

今回は複合リッチメニューつまり、タブ付きリッチメニューをGASを用いて実装する方法について紹介する前編です。

参考元:【プログラム配布用】リッチメニューの自由分割&タブ切り替えを実装するチュートリアル【LINE公式アカウント / Messaging API】

スポンサーリンク

Google Apps Script にライブラリを追加しよう

LINE Bot SDKをプロジェクトに組み込み、使える状態にします。

SDKとはソフトウェアを開発するために必要な技術文書やツールなど一式のことで、始めから用意された便利なクラスなどを用いて面倒なコードを書くことなく分かりやすく、簡単にLINE Botの持つ機能にコードからアクセスできるようになります。

ライブラリを追加 

→ ライブラリのスクリプトID 参考元より

1KsjhQa6oymhUiACWsAlFTG_XoN8Pnz4px2ekABPjO4tSMX6xRSQMBicy

を入力して検索すると「LineBotSdk」が表示されます。

最新のバージョン(2024/7/14現在はver37)を追加します。

大切なお知らせ:当初、シリーズ「②Google Apps Scriptをさわってみよう」 にてライブラリの紹介をしていましたが、紹介したライブラリのIDが誤っておりました。

もし、2024/7/14以前にLineBotSDK(語尾が大文字)のライブラリを追加された方は、一旦ライブラリを削除し、新たにこちらのLineBotSdk(語尾が小文字)を追加してください。

リッチメニュー用のスクリプトを新規作成

前回使用したスプレッドシートからGoogleAppsを開き、新しいスクリプトを作成します。

以下のコードを入力します。ちょっと行数が多いので、二つに分けて示しますね。

同じスクリプト内に続けて入力してください。

①createRichMenuA,B,C

const bot = new LineBotSdk.client(PropertiesService.getScriptProperties().getProperty('LINEb_TOKEN'));

function createRichMenuA() {
  let richmenu = bot.richmenu({
    "name": "オリジナルリッチメニュー",
    "barText": "メニュー",
    "size": { "width": 2500, "height": 1686 },
    "selected": true, 
    "areas": [
      bot.area({ "x": 0,    "y": 0, "width": 833, "height": 336,
      "action": bot.aSwitch({"aliasId": "switch-to-a", "data": "change to A"}) }),
      bot.area({ "x": 833, "y": 0, "width": 833, "height": 336,
      "action": bot.aSwitch({"aliasId": "switch-to-b", "data": "change to B"}) }),
      bot.area({"x": 1667, "y": 0, "width": 833, "height": 336, 
      "action": bot.aSwitch({"aliasId": "switch-to-c", "data": "change to C"}) }),
      bot.area({ "x": 0,    "y": 337, "width": 833, "height": 674,
      "action": bot.aMessage({"text": 'アンケート' }) }),
      bot.area({ "x": 833, "y": 337, "width": 833, "height": 674,
      "action": bot.aMessage({"text": 'つかいかた' }) }),
      bot.area({"x": 1667, "y": 337, "width": 833, "height": 674, 
      "action": bot.aMessage({"text": "コミュニティバス"}) }),
      bot.area({ "x": 0,    "y": 1011, "width": 833, "height": 674,
      "action": bot.aMessage({"text": "閲覧"}) }),
      bot.area({ "x": 833, "y": 1011, "width": 833, "height": 674,
      "action": bot.aMessage({"text": "ごみ収集日一覧"}) }),
      bot.area({"x": 1667, "y": 1011, "width": 833, "height": 674, 
      "action": bot.aMessage({"text": "イベントカレンダー"}) }),
    ]
  })
  let res = bot.createRichMenu(richmenu);
  console.log(res.toString()); 
}

function createRichMenuB() {
  let richmenu = bot.richmenu({
    "name": "オリジナルリッチメニュー",
    "barText": "メニュー",
    "size": { "width": 2500, "height": 1686 },
    "selected": true, 
    "areas": [
      bot.area({ "x": 0,    "y": 0, "width": 833, "height": 336,
      "action": bot.aSwitch({"aliasId": "switch-to-a", "data": "change to A"}) }),
      bot.area({ "x": 833, "y": 0, "width": 833, "height": 336,
      "action": bot.aSwitch({"aliasId": "switch-to-b", "data": "change to B"}) }),
      bot.area({"x": 1667, "y": 0, "width": 833, "height": 336, 
      "action": bot.aSwitch({"aliasId": "switch-to-c", "data": "change to C"}) }),

      bot.area({ "x": 0,    "y": 337, "width": 833, "height": 450,
      "action": bot.aMessage({"text": "ボタンB-1"}) }),
      bot.area({ "x": 833, "y": 337, "width": 833, "height": 450,
      "action": bot.aMessage({"text": "ボタンB-2"}) }),
      bot.area({"x": 1667, "y": 337, "width": 833, "height": 450, 
      "action": bot.aMessage({"text": "ボタンB-3"}) }),

      bot.area({ "x": 0,    "y": 786, "width": 833, "height": 450,
      "action": bot.aMessage({"text": "ボタンB-4"}) }),
      bot.area({ "x": 833, "y": 786, "width": 833, "height": 450,
      "action": bot.aMessage({"text": "ボタンB-5"}) }),
      bot.area({"x": 1667, "y": 786, "width": 833, "height": 450, 
      "action": bot.aMessage({"text": "ボタンB-6"}) }),

      bot.area({ "x": 0,    "y": 1122, "width": 833, "height": 450,
      "action": bot.aMessage({"text": "ボタンB-7"}) }),
      bot.area({ "x": 833, "y": 1122, "width": 833, "height": 450,
      "action": bot.aMessage({"text": "ボタンB-8"}) }),
      bot.area({"x": 1667, "y": 1122, "width": 833, "height": 450, 
      "action": bot.aMessage({"text": "ボタンB-9"}) }),
    ]
  })
  let res = bot.createRichMenu(richmenu);
  console.log(res.toString());
}
function createRichMenuC() {
  let richmenu = bot.richmenu({
    "name": "オリジナルリッチメニュー",
    "barText": "メニュー",
    "size": { "width": 2500, "height": 1686 },
    "selected": true, 
    "areas": [
      bot.area({ "x": 0,    "y": 0, "width": 833, "height": 336,
      "action": bot.aSwitch({"aliasId": "switch-to-a", "data": "change to A"}) }),
      bot.area({ "x": 833, "y": 0, "width": 833, "height": 336,
      "action": bot.aSwitch({"aliasId": "switch-to-b", "data": "change to B"}) }),
      bot.area({"x": 1667, "y": 0, "width": 833, "height": 336, 
      "action": bot.aSwitch({"aliasId": "switch-to-c", "data": "change to C"}) }),

      bot.area({ "x": 0,    "y": 337, "width": 833, "height": 1349,
      "action": bot.aMessage({"text": "ボタンC-1"}) }),
      bot.area({ "x": 833, "y": 337, "width": 833, "height": 1349,
      "action": bot.aMessage({"text": "ボタンC-2"}) }),
      bot.area({"x": 1667, "y": 337, "width": 833, "height": 1349, 
      "action": bot.aMessage({"text": "ボタンC-3"}) }),
    ]
  })
  let res = bot.createRichMenu(richmenu);
  console.log(res.toString());
}

②createRichMenuArias、updateRichMenuArias、uploadRichmenuImageA、B、C、setDefaultRichMenu

// エイリアス作成
function createRichMenuArias() {
    deleteRichMenuArias();  // 既存のエイリアスを削除
  bot.createRichMenuArias("switch-to-a", "リッチメニューAのID");
  bot.createRichMenuArias("switch-to-b", "リッチメニューBのID");
  bot.createRichMenuArias("switch-to-c", "リッチメニューCのID");
}
// エイリアス削除
function deleteRichMenuArias() {
  bot.deleteRichMenuArias("switch-to-a");
  bot.deleteRichMenuArias("switch-to-b");
  bot.deleteRichMenuArias("switch-to-c");
}
// エイリアス変更
// function updateRichMenuArias() {
//   bot.updateRichMenuArias("switch-to-a", "リッチメニューAのID");
//   bot.updateRichMenuArias("switch-to-b", "リッチメニューBのID");
//   bot.updateRichMenuArias("switch-to-c", "リッチメニューCのID");
// }

function uploadRichmenuImageA() {
  const file = DriveApp.getFileById("リッチメニューAの画像ID");
  const blob = Utilities.newBlob(
    file.getBlob().getBytes(),
    file.getMimeType(),
    file.getName()
  );
  bot.setRichMenuImage("リッチメニューAのID", blob);
}
function uploadRichmenuImageB() {
  const file = DriveApp.getFileById("リッチメニューBの画像ID");
  const blob = Utilities.newBlob(
    file.getBlob().getBytes(),
    file.getMimeType(),
    file.getName()
  );
  bot.setRichMenuImage("リッチメニューBのID", blob);
}
function uploadRichmenuImageC() {
  const file = DriveApp.getFileById("リッチメニューCの画像ID");
  const blob = Utilities.newBlob(
    file.getBlob().getBytes(),
    file.getMimeType(),
    file.getName()
  );
  bot.setRichMenuImage("リッチメニューCのID", blob);
}

// デフォルト表示
function setDefaultRichMenu() {
  bot.setDefaultRichMenu("リッチメニューAのID");
}
// // デフォルト取り下げ
// function deleteDefaultRichMenu() {
//   bot.deleteDefaultRichMenu();
// }


今回、リッチメニューB、Cは各自お好みの項目を設定してください。

現在は、該当のボタンを押すと「ボタン〇-〇」と発言する設定にしてなってます。

この「ボタン〇-〇」に対応するアクションをそれぞれ設定すると、いわゆる「自動応答」ができます。

各リッチメニューのIDを取得しよう

デプロイができたので、リッチメニューのスクリプトに戻ります。

createRichMenuAを実行します。

すると、コンソールに情報:richMenuId:”richmenu- ~ ”が表示されます。

この「richmenu-~」の部分をコピーし、コード内の「リッチメニューAのID」4カ所に貼り付けます。

同様に、createRichMenuB、createRichMenuCを実行し、それぞれ3カ所に貼り付けます。

「デプロイ」しよう

「デプロイ(Deploy)」には「配備する、展開する」という意味があり、IT業界で「デプロイ」というと、「実行ファイルをサーバ上に配置し、システムをユーザが利用できる状態にすること」を指します。

デプロイとは【3分でわかる】ビルドやリリースとの違い|IT用語

作成したリッチメニューをLINEのデフォルト画面に反映させるということは、ザックリ言うと「LINEの画面(=webページ)に反映させる」ということです。

Webページとして閲覧できるようにするためには、「デプロイ」という作成したスクリプトに対してWebアプリURLを発行する作業が必要です。

WebアプリURLを発行することでこのWebページにアクセスできるようになります。

新しいデプロイ

右上の「デプロイ」→「新しいデプロイ」を開きます。

種類の選択右の歯車アイコンからウェブアプリを選択

アクセスできるユーザー:全員 を選択し、デプロイ。

ウェブアプリのURLをコピー

→ LINE Developersの自身のチャネル

→ Webhook設定でWebhook URLにペースト

→ 更新

→ Webhookの利用 ON

これでOK!

まとめ

今回は新たなスクリプトの作成に伴い、ライブラリの追加とWebhookの設定を行いました。

今後、ウェブページに関するスクリプトの変更を反映しようとするたびに「デプロイ」の更新が必要になりますので、頭の片隅に覚えておいてくださいね!

次回は後編として前回作成したリッチメニュー画像を紐づけ、LINEの画面に反映させる作業を行います。

どうぞお楽しみに!