8
5

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 1 year has passed since last update.

【初心者向け】GAS+Googleスプレッドシート+LINEBotでやりたいこと逆引き

Posted at

はじめに

GAS+GoogleスプレッドシートでLINEBotを作る際に、よくやる処理を逆引きでまとめました

前提

CHANNEL_ACCESS_TOKENが定義されている
line_endpointが定義されている
doPostの引数はe
jsonは以下のようにパースされている

const CHANNEL_ACCESS_TOKEN = 'チャネルアクセストークンを貼り付け'; 
const line_endpoint = 'https://api.line.me/v2/bot/message/reply';
function doPost(e) {
  //JSONをパースする
  var json = JSON.parse(e.postData.contents);
}

LINEBot編

詳細を確認したい場合は公式ドキュメントを読んでください

LINEbotから送信されるjsonの中身のサンプルです

{
  "destination": "xxxxxxxxxx",
  "events": [
    {
      "replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
      "type": "message",
      "mode": "active",
      "timestamp": 1462629479859,
      "source": {
        "type": "user",
        "userId": "U4af4980629..."
      },
      "message": {
        "id": "325708",
        "type": "text",
        "text": "@example Hello, world! (love)",
        "emojis": [
          {
            "index": 14,
            "length": 6,
            "productId": "5ac1bfd5040ab15980c9b435",
            "emojiId": "001"
          }
        ],
        "mention": {
          "mentionees": [
            {
              "index": 0,
              "length": 8,
              "userId": "U850014438e..."
            }
          ]
        }
      }
    }
  ]
}

こういう構造になっているので以下のように情報を取得できます

リプライトークン

json.events[0].replyToken;

イベントのタイプ

json.events[0].type

ユーザーID

json.events[0].source.userId

メッセージ

イベントのタイプがmessageだった場合

json.events[0].message.text

postback

イベントのタイプがpostbackだった場合

json.events[0].postback.data

リプライトークンを用いて返信する

var messages = [{'type': 'text', 'text': "テスト返信"}]
UrlFetchApp.fetch(line_endpoint, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': reply_token,
      'messages': messages,
    }),
});
return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);

スプレッドシート編

まずこちらで基本的な使い方を覚えましょう
【GAS初心者】getDataRange関数でのシートの値の取り方6step+1try(GAS)

使うシートを指定する

const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートの名前');

データ全体を取得

sheet.getDataRange().getValues();

注意点

セルのデータを取得

sheet.getRange(行番号,列番号).getValue()
// または英字+数字の文字列
sheet.getRange("A1").getValue()

セルにデータを設定

sheet.getRange(行番号,列番号).setValue("文字列")
// または英字+数字の文字列
sheet.getRange("A1").setValue("文字列")

列を検索して条件に該当する行番号をすべて取得

function doPost(e) {
  // いろんな処理
  var target_rows = searchData(sheet, 検索する条件, 検索したい行番号)
}

function searchData(sheet, condition, col){
  var allData = sheet.getDataRange().getValues(); // データを全件取得
  var target_rows = []; 
  // ヘッダーを含める場合はi=0で初期値を与える
  for(var i = 1; i < allData.length; i++) { // データを順に調べていく
    // ↓ この部分を変更していろんなパターンが作れる
    // 調べたい列が4列目だとすると、配列は0からはじまるので4-1で3が指定される
    if(allData[i][col-1].indexOf(condition) != -1){ 
      target_rows.push(i+1); // 検索に引っかかる箇所の行番号を配列に集める
    }
    // ↑ この部分を変更していろんなパターンが作れる
  }
  return target_rows;
}

列に指定の文字が一部分でも入っている場合(部分一致)

if(allData[i][col-1].indexOf(condition) != -1){
  target_rows.push(i+1);
}

indexOfを利用
indexOfのドキュメント

列に指定の文字が一部分でも入っている場合(完全一致)

if(allData[i][col-1] == condition){
  target_rows.push(i+1);
}

列に指定の数以上のものがある場合

if(allData[i][col-1] >= condition){
  target_rows.push(i+1);
}

列に指定の数以下のものがある場合

if(allData[i][col-1] <= condition){
  target_rows.push(i+1);
}

配列からランダムにn個取り出したい

function doPost(e){
  // いろんな処理
  var target_rows = searchData(sheet, 検索する条件, 検索したい行番号)
  // target_rowsからランダムにn個取り出したい
  var selected_target_rows = randomSelect(target_rows, 2) // 引数に2を指定したら2つ取得できる
}

function randomSelect(array, n){
  var randomSelect = [];
  while(randomSelect.length < n && array.length > 0){
    const rand = Math.floor(Math.random() * array.length);
    var selected_val = array[rand]
    randomSelect.push(selected_val);
    // ↓ この部分を変更したらいろんなパターンに対応できる 
    array = array.filter(function(v, i) {
      return (v !== selected_val);
    }); // 結果が重複しないように、元の配列からは削除
    // ↑ この部分を変更したらいろんなパターンに対応できる 
  }
  return randomSelect;
}

該当の要素全部削除

// 以下の配列から3つ取り出すときに[1,1,x]はナシにしたい
[1,2,3,4,5,1]

array = array.filter(function(v, i) {
      return (v !== selected_val);
    });

該当の要素だけ削除

// 以下の配列から3つ取り出すときに[1,1,x]はアリだけど、[2,2,x]はナシ
[1,2,3,4,5,1]

array[rand] = "" //取り出しところを特定の文字で埋める
array = array.filter(function(v, i) {
      return (v !== ""); // その文字を除外
    });

重複を許す

// 以下の配列から3つ取り出すときに[1,1,x]でも、[2,2,2]でもあり
[1,2,3,4,5,1]

// 何も書かない
//array = array.filter(function(v, i) {
//      return (v !== selected_val);
//    });

おわりに

かなり限定的だと思うので、都度追加していきます。
コメントもお待ちしてます🙇‍♂️

8
5
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
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?