Skip to content

Instantly share code, notes, and snippets.

@MxShun
Last active December 14, 2020 06:39
Show Gist options
  • Save MxShun/0c87645a868f976c3e620a23d61eb844 to your computer and use it in GitHub Desktop.
Save MxShun/0c87645a868f976c3e620a23d61eb844 to your computer and use it in GitHub Desktop.
8thkun-line-bot
/**
* A Google Apss Script LINE Bot project for activating the group communication.
*
* To improve the group commutication, it has some functions;
* (1)anonymous posts, (2)schedule notifications and
* (3)assign list.
*
* Descripting following page.
*
* Messaging APIとGASを使ったLINE Botでグループチャットの活発化 - Qiita
* https://qiita.com/MxShun/items/7a563a795d41cdc0f1dc
*/
var CHANNEL_ACCESS_TOKEN = "【チャンネルアクセストークン】";
var CALENDER_ID = "【GoogleカレンダーID】";
var SHEET_ID = "【GoogleスプレッドシートID】";
var GROUP_ID = "【LINEグループID】";
var dateExp = /(\d{2})\/(\d{2})\s(\d{2}):(\d{2})/;
var dayExp = /(\d+)[\/月](\d+)/;
var hourMinExp = /(\d+)[:時](\d+)*/;
var assign = "\
🗿配属先一覧🗿\n\
name1 assign1\n\n\
name2 assign2\n\n\
name3 assign3\
";
function doPost(e) {
var replyToken = JSON.parse(e.postData.contents).events[0].replyToken;
var lineType = JSON.parse(e.postData.contents).events[0].type;
if (typeof replyToken === "undefined") {
return;
}
else if (lineType === "follow" || lineType === "unfollow") {
var name = getUserProfile(JSON.parse(e.postData.contents).events[0].source.userId);
logging(name, lineType, null);
return;
}
var userMessage = JSON.parse(e.postData.contents).events[0].message.text;
var cache = CacheService.getScriptCache();
var type = cache.get("type");
if (type === null) {
if (userMessage === "予定の追加") {
cache.put("type", 1);
reply(replyToken, "予定の日付を教えて🗿(1/4)\n---\n形式指定:1/23, 1月23日\nキャンセル:『やめる』と入力");
} else if (userMessage === "匿名で投稿") {
cache.put("type", 10);
reply(replyToken, "グルチャに匿名でラインするよ🗿投稿内容を教えて🗿\n---\nキャンセル:『やめる』と入力");
} else if (userMessage === "配属を表示"){
reply(replyToken, assign);
var name = getUserProfile(JSON.parse(e.postData.contents).events[0].source.userId);
logging(name, lineType, "配属を表示");
}
} else {
if (userMessage === "やめる") {
cache.remove("type");
reply(replyToken, "キャンセルしたよ🗿");
return;
}
switch(type) {
case "1":
// 予定日
var [matched, month, day] = userMessage.match(dayExp);
cache.put("type", 2);
cache.put("month", month);
cache.put("day", day);
reply(replyToken, "予定の開始時刻を教えて🗿(2/4)\n---\n形式指定:1:23, 12時, 12時34分\nキャンセル:『やめる』と入力");
break;
case "2":
// 開始時刻
var [matched, startHour, startMin] = userMessage.match(hourMinExp);
cache.put("type", 3);
cache.put("start_hour", startHour);
if (startMin == null) startMin = "00";
cache.put("start_min", startMin);
reply(replyToken, "予定の終了時刻を教えて🗿(3/4)\n---\n形式指定:1:23, 12時, 12時34分\nキャンセル:『やめる』と入力");
break;
case "3":
// 終了時刻
var [matched, endHour, endMin] = userMessage.match(hourMinExp);
cache.put("type", 4);
cache.put("end_hour", endHour);
if (endMin == null) endMin = "00";
cache.put("end_min", endMin);
reply(replyToken, "予定の名前を教えて🗿(4/4)\n---\nキャンセル:『やめる』と入力");
break;
case "4":
// 予定名
cache.put("type", 5);
cache.put("title", userMessage);
var [title, startDate, endDate] = createEventData(cache);
reply(replyToken, toEventFormat(title, startDate, endDate) + "\n\nで間違いない?🗿\nよければ『はい』、やり直すなら『いいえ』と入力して🗿");
break;
case "5":
// 確認の回答がはい or いいえ
cache.remove("type");
if (userMessage === "はい") {
var [title, startDate, endDate] = createEventData(cache);
CalendarApp.getCalendarById(CALENDER_ID).createEvent(title, startDate, endDate);
reply(replyToken, "予定を追加したよ🗿予定の当日朝に通知するね🗿");
var name = getUserProfile(JSON.parse(e.postData.contents).events[0].source.userId);
logging(name, lineType, "Calender Update at:" + startDate);
} else {
reply(replyToken, "悪いけど最初からやり直して🗿");
}
break;
case "10":
cache.put("type", 11);
cache.put("post", userMessage);
var post = createPost(cache);
reply(replyToken, post + "\n\nで間違いない?🗿\nよければ『はい』、やり直すなら『いいえ』と入力して🗿\nいたずらや誹謗中傷は許さないよ🗿");
break;
case "11":
// 確認の回答がはい or いいえ
cache.remove("type");
if (userMessage === "はい") {
var post = createPost(cache);
// グループにポスト
pushPost("🗿匿名投稿🗿\n" + post);
reply(replyToken, "投稿したから確認してね🗿");
var name = getUserProfile(JSON.parse(e.postData.contents).events[0].source.userId);
logging(name, lineType, post); // 2020/05/27ログ追記
} else {
reply(replyToken, "悪いけど最初からやり直して🗿");
}
cache.remove("post");
break;
default:
reply(replyToken, "申し訳ありません。\n形式に誤りがないか確認してみて、なければ「キャンセル」で予定入力をキャンセルすることができるので、そちらを試していただけますか?");
break;
}
}
}
function createEventData(cache) {
var year = new Date().getFullYear();
var title = cache.get("title");
var startDate = new Date(year, cache.get("month") - 1, cache.get("day"), cache.get("start_hour"), cache.get("start_min"));
var endDate = new Date(year, cache.get("month") - 1, cache.get("day"), cache.get("end_hour"), cache.get("end_min"));
return [title, startDate, endDate];
}
function toEventFormat(title, startDate, endDate) {
var start = Utilities.formatDate(startDate, "JST", "MM/dd HH:mm");
var end = Utilities.formatDate(endDate, "JST", "MM/dd HH:mm");
var str = title + ": " + start + " ~ " + end;
return str;
}
function createPost(cache){
var post = cache.get("post");
return post;
}
function reply(replyToken, message) {
var url = "https://api.line.me/v2/bot/message/reply";
UrlFetchApp.fetch(url, {
"headers": {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": "Bearer " + CHANNEL_ACCESS_TOKEN,
},
"method": "post",
"payload": JSON.stringify({
"replyToken": replyToken,
"messages": [{
"type": "text",
"text": message,
}],
}),
});
return ContentService.createTextOutput(JSON.stringify({"content": "post ok"})).setMimeType(ContentService.MimeType.JSON);
}
function pushPost(body){
var url = 'https://api.line.me/v2/bot/message/push';
UrlFetchApp.fetch(url, {
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
},
'method': 'post',
'payload': JSON.stringify({
'to': GROUP_ID,
'messages':[{
'type': 'text',
'text': body,
}]
})
})
}
function broadcastPost(body){
var url = 'https://api.line.me/v2/bot/message/broadcast';
UrlFetchApp.fetch(url, {
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
},
method: 'post',
payload: JSON.stringify({
'messages':[{
'type': 'text',
'text': body,
}]
})
});
}
function getEvents() {
var date = new Date();
date.setDate(date.getDate());
var events = CalendarApp.getCalendarById(CALENDER_ID).getEventsForDay(date);
if (events.length !== 0) {
var body = "🗿今日の予定🗿";
events.forEach(function(event) {
var title = event.getTitle();
var start = toHHmm(event.getStartTime());
var end = toHHmm(event.getEndTime());
if(end == "00:00"){
body += "\n*" + title;
} else {
body += "\n*" + title + " " + start + " ~ " + end;
}
});
broadcastPost(body);
}
}
function toHHmm(date){
return Utilities.formatDate(date, "JST", "HH:mm");
}
function getUserProfile(userid){
var url = 'https://api.line.me/v2/bot/profile/' + userid;
var userProfile = UrlFetchApp.fetch(url,{
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
},
})
return JSON.parse(userProfile).displayName;
}
function logging(name, action, message){
var sheet = SpreadsheetApp.openById(SHEET_ID).getSheetByName('log');
var data = new Date();
sheet.insertRows(2,1);
sheet.getRange(2, 1, 1, 4).setValues([[data, name, action, message]]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment