はじめに
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);
// });
おわりに
かなり限定的だと思うので、都度追加していきます。
コメントもお待ちしてます🙇♂️