10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LINE MessagingAPIをGASとで触ってみた

10
Last updated at Posted at 2021-12-03

ふと何か新しいものを自作したく、気軽に遊べそうだったLINE MessageAPIに触れてみました。その際の手順とかいろいろ書いていきます。
n番煎じのネタなのとコードが汚いのは目を瞑っていただけると幸いです。

1. LINE MessagingAPIの設定をする

LineDevelopersよりMessagingAPIの設定を行います。

1-1. サイト中段にあるプロダクトより、MessagingAPIを選択します。

image.png
バナーの「今すぐ始めよう」から更に遷移。
image.png

1-2. 各必須項目を入力し作成を行う。

チャネルの種類
MessagingAPIを選択選択します。

プロバイダー
実行する管理者を登録します。初回は作成の必要あり。

チャネル名
実際のBotの名前になります。

チャネル説明
なんでも大丈夫です。

大業種
小業種
メールアドレス
ご自身に合わせて選択、入力してください。

上記の必須項目の入力が完了したら、同意項目を確認し作成します。

1-3. Messaging API設定を行う。

タブ内の「Message API設定」を開きます。
image.png

最下部にある「チャネルアクセストークン」を発行します。
こちらのアクセストークンは次で使用しますのでメモ等で取っておいてください。
image.png

応答メッセージの設定も無効にしておきましょう。
image.png

2. Gasでオウム返しのスクリプトをデプロイしてみる

2-1. GoogleDriveから新規スクリプトを作成する。

image.png

2-2. 以下のスクリプトを作成したGasシートに張り付け

貼り付けの前に2行目の ■■■■■■■■■■■■■を 1-3 でメモしておいた自身のアクセストークンに置換してください。

オウム返し
// line token
const channel_token = "■■■■■■■■■■■■■";
// line api url
const url = "https://api.line.me/v2/bot/message/reply";

function doPost(e) {
  let json = e.postData.contents;
  let events = JSON.parse(json).events;
  let requestMessage = events[0].message.text;

  returnMessage(events[0],requestMessage);
}

function returnMessage(event,messageText){
  let message = {
    "replyToken" : event.replyToken,
    "messages" : [{"type": "text","text" : messageText}]
  };
      
  let options = {
    "method" : "post",
    "headers" : {
      "Content-Type" : "application/json",
      "Authorization" : "Bearer " + channel_token
    },
    "payload" : JSON.stringify(message)
   };
  UrlFetchApp.fetch(url, options);
}
2-3. デプロイする

ページ右上の「デプロイ」>「新しいデプロイ」を選択。
image.png

歯車マークから「ウェブアプリ」を選択。
image.png

アクセスできるユーザーを「自分のみ」から「全員」に変更したらデプロイを押下します。
image.png

ウェブアプリのURLは次で使用しますのでメモ等で取っておいてください。
image.png

※アクセス許可の確認が初回のみ出ます。

3. MessagingAPIに戻る

3-1. Webhookを有効にする。

MessagingAPI設定にあるWebhook設定を編集します。
展開されたテキストエリアに先ほどメモに取っていたウェブアプリURLを入力します。
image.png

更新を押したら完了になります。

Webhook利用のチェックを入れるのを忘れずに。
image.png

実際に動かしてみる

MessagingAPI設定に表示されているQRコードからLINE友達追加できます。
メッセージを送信してオウム返しで帰ってくれば成功になります。
image.png

ミニゲーム

折角なのでMessagingAPIとGASを使用して一方通行のヌメロンを作りました。
image.png

main.gs
// line token
const channel_token = "■■■■■■■■■■■■■■";
// line api url
const url = "https://api.line.me/v2/bot/message/reply";
// cache
const cache = CacheService.getScriptCache();

function doPost(e) {
  let json = e.postData.contents;
  let events = JSON.parse(json).events;
  let returnText = "半角0でスタート\nqqで終了"
  let requestMessage = events[0].message.text;
  let status = cache.get("status");
  if(requestMessage == "qq"){
    returnText = endGame();
  }else if(status == 1){
    returnText = inputNumber(requestMessage);
  }else if(requestMessage == "0"){
    returnText = startGame();
  }
  returnMessage(events[0],returnText);
}

function returnMessage(event,messageText){
  let message = {
    "replyToken" : event.replyToken,
    "messages" : [{"type": "text","text" : messageText}]
  };
  let options = {
    "method" : "post",
    "headers" : {
      "Content-Type" : "application/json",
      "Authorization" : "Bearer " + channel_token
    },
    "payload" : JSON.stringify(message)
   };
  UrlFetchApp.fetch(url, options);
}
service.gs
function startGame(){
  let returnText = "";
  let fir = Math.floor(Math.random()*10);
  let sec = Math.floor(Math.random()*10);
  let third = Math.floor(Math.random()*10);
  let num;

  while(sec == fir){
    sec = Math.floor(Math.random()*10);
  }
  while(third == sec || third == fir){
    third = Math.floor(Math.random()*10);
  }

  num = "" + fir + sec + third;
  cache.put("targetNum",num);
  cache.put("status",1);

  returnText = "3桁の数字をセットしました。\n3桁の数字を入力して当ててください。"
  return returnText;
}

function endGame(){
  cache.remove("status");
  return "終了します。";
}

function inputNumber(request){
  let targetNum = cache.get("targetNum");
  let returnText = "";
  let regex = new RegExp(/^[0-9]{3}$/);
 
  // 正規表現マッチ /^[0-9]{3}$/
  if(regex.test(request)){
    let hitCnt = 0;
    let blowCnt = 0;

    // ドンピシャ
    if(request == targetNum){
      returnText = "3Hit 0Blow!\n終了します。";
      cache.remove("status");
    }else{
      let requestArray = request.split('');
      let targetArray = targetNum.split('');

      // 重複チェック
      let duplicateArray = Array.from(new Set(requestArray));
      if(duplicateArray.length == requestArray.length){

        for(let i = 0; i < requestArray.length; i++){

          // hit数チェック -> hit箇所は h に置換
          if(requestArray[i] == targetArray[i]){
            hitCnt++;
            targetArray.splice([i],1,"h");
          }

          // blow数チェック
          if(targetArray.indexOf(requestArray[i]) != -1){
            blowCnt++;
          }
        }
        returnText = hitCnt + "Hit "+ blowCnt + "blow"; 
      }else{
        returnText = "入力に重複している数字があります。";
      }
    }
  }else{
    returnText = "3桁の半角数字を入力してください。";
  }
  return returnText;
}

image.png
BotQR
読み込んでLINEを開くと実際に追加できます。

所感

MessagingAPIは以前から知ってはいましたが、実際触ってみたところ頭の中で考えてることをお手軽に実現できるので面白かったです。
キャッシュとかで対話型のBot、スプシを連携させてDB代わりに使用したりなどもできそうで夢が広がリングです。

今回は一方通行のBotでしたが今度は対話型(対戦型)のBotも作ってみたいと思います。
おわり

追記(2021/12/07)

ミニゲームで遊んでた際に「2hit 1blow」と出るのが発覚。
2つ合ってるけど1つ位置が違うってなんじゃそりゃ。。
原因としてはService.gsのinputNumber中の処理がダメでした。
hitしたナンバーは「h」に置換するようにして解消してます。
targetArray.splice([i],1);
から
targetArray.splice([i],1,"h");

あと重複数字が入力された時のバリデーション追加しました。

10
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?