成果物
LINE上で「席替え!」とチャットすると、席替え結果を返すBot。
席替えは毎日実施される。
アイコンは拾い物。
Thanks!(https://iconbu.com/illust/4427)
背景
会社の研修中、交流のため「毎回同じところに座らないように。」とのことで作成。
もう少し詳しく
初めは、LINEのあみだくじで行っていたが、あみだくじの作成が面倒に。
LINEBOTのが楽?!と思いつき、作成。
事前に同期に相談していなかったが、スムーズに導入してもらえる。
作成時間
前日の晩に、「(LINEのあみだくじが)面倒くさい」と聞き、翌朝作成。
作業時間。1時間強。(褒めたい)
以前、飲食店向けのLINEBotを作成していたこともあり、早くできた。
GASはお仕事で少しやっていたので問題なし。
シート
シート名 | 内容 |
---|---|
name | 1行目、席替えしたい人の名前。 |
recode | 席替えの履歴。A列、日付。B~列、席替え結果。 |
log | エラーの記録。 |
この3つのシートを作ればOK。
やり方
後日追記
1.スプレッドシートを準備する。
2.名前を記入する。
3.ソースコードをコピペする。
※このままでは動きません。LINE、トークンについてはまた。
ソースコード
全体
関数名 | 説明 |
---|---|
create | スプレッドシートから名前を取得して席替え。プロパティに保存。トリガーで毎朝9時に実施する。 |
getMessages | プロパティの席替えリストをLINEメッセージに変換し返却。 |
doPost | LINEからメッセージを受信すると起動。「席替え!」を受信すると席替え内容を返す。 |
工夫
BOT動作時に、シートから直接取得すると時間がかかるので、propertyServiceを利用して時短。
/**
* @description スプレッドシートから名前を取得して席替え。プロパティに保存。トリガーで毎朝9時に実施する。
*/
function create() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const [names] = ss.getSheetByName('name').getDataRange().getValues();
/**
* @description 席替え参加者リスト
* @param {string[]}
*/
console.log(names)
//配列をランダムに入れ替える
for (let i = names.length - 1; i > 0; i--) {
let r = Math.floor(Math.random() * (i + 1));
let tmp = names[i]
names[i] = names[r]
names[r] = tmp
}
console.log(names)
const d = new Date()
d.setDate(d.getDate() + 1)
console.log(d)
//明日の日付とともにシートに保存する。
const date = Utilities.formatDate(d, Session.getScriptTimeZone(), "yyyy/MM/dd")
const values = [[date, ...names]]
const sh = ss.getSheetByName('recode')
const lr = sh.getLastRow();//スプレッドシートの最終行を取得
sh.getRange(lr + 1, 1, values.length, values[0].length).setValues(values);//貼付
//データをプロパティに保存する
const json = JSON.stringify(values);
PropertiesService.getScriptProperties().setProperty('seki', json);
}
/**
* @description プロパティの席替えリストをLINEメッセージに変換し返却。
*/
function getMessages() {
//プロパティから名前のランダムリスト+日付を取得
const json = PropertiesService.getScriptProperties().getProperty('seki');
const [values] = JSON.parse(json);
const v = values.reduce((a, x, i) => {
if(i ===0) return [...a, x]
const nn = i+". " +x
return[...a, nn]
}, [])
//ラインに投下される形
const text = v.join('\n');
const messages = [
{
type: "text",
text: "せきがえんぬ~"
},
{
type: "text",
text,
}]
console.log(messages)
return messages;
}
/**
* @description LINEからメッセージを受信すると起動。「席替え!」を受信すると席替え内容を返す。
*/
function doPost(e) {
try {
const event = JSON.parse(e.postData.contents).events[0];
console.log(event)
if(event["type"] !== 'message' || event["message"]["type"] !== "text"){
return;
}
const sendedText = event["message"]["text"]; //送信テキスト
console.log(sendedText)
const t = ["席替え!", "せきがえ!"]
if(!t.includes(sendedText)) {
return;
}
const url = 'https://api.line.me/v2/bot/message/reply';
const ACCESS_TOKEN = PropertiesService.getScriptProperties().getProperty('token');
if (!ACCESS_TOKEN) {
console.error('no token')
return;
}
const messages = getMessages();
const replyToken = event["replyToken"];
const options = {
"headers": {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": 'Bearer ' + ACCESS_TOKEN
},
"method": "post",
"payload": JSON.stringify({ replyToken, messages }),
muteHttpExceptions: true
};
var response = UrlFetchApp.fetch(url, options);
if (response.getResponseCode !== 200) {
console.error("error!")
return
}
} catch (e) {
console.log(e)
const s = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('log')
const lr = s.getLastRow()
s.getRange(lr + 1, 1).setValue(JSON.stringify(e))
}
return ContentService
.createTextOutput(JSON.stringify({ 'content': 'post ok' }))
.setMimeType(ContentService.MimeType.JSON);
}
感想
名前順をシャッフルしてくれるので、席替え以外の用途にも使ってもらえました。
嬉しき。
研修中のインフラとして当然のように使われる存在になったので、作ってよかったです。
改善
席を見やすくすることも考えたりしましたが、研修を乗り切ったのでひとまず終了。
参考