문장에서도 알 수 있는, GAS에 의한 수업 통지의 LINE bot 작성
14438 단어 LINEmessagingAPIlinebotgas
이번에 마지막이 됩니다.
setTrigger라고 하는 것을 사용해, 수업 개시 10분전에 통지가 오도록(듯이) 합니다.
이 기사에서 이해
이번에 할 일
요구사항 정의
푸시 알림을 보내는 기능 만들기
Code.gsfunction push(text, zoom) {
//メッセージを送信(push)する時に必要なurlでこれは、皆同じなので、修正する必要ありません。
//この関数は全て基本コピペで大丈夫です。
var url = "https://api.line.me/v2/bot/message/push";
var headers = {
"Content-Type" : "application/json; charset=UTF-8",
'Authorization': 'Bearer ' + access_token,
};
//toのところにメッセージを送信したいユーザーのIDを指定します。(toは最初の方で自分のIDを指定したので、linebotから自分に送信されることになります。)
//textの部分は、送信されるメッセージが入ります。createMessageという関数で定義したメッセージがここに入ります。
var postData = {
"to" : user_id,
"messages" : [
{
'type':'text',
'text':text,
},
{
'type':'text',
'text':zoom,
}
]
};
var options = {
"method" : "post",
"headers" : headers,
"payload" : JSON.stringify(postData)
};
return UrlFetchApp.fetch(url, options);
}
"messages" : [{}{}]
의 형태로 하는 것으로, 패스워드가 다른 메세지로서 보내 오는 것을 하고 있습니다 (위의 화상 참조). 이렇게 하면 암호를 쉽게 복사할 수 있습니다.
푸시 알림으로 보낼 수업 정보를 얻는 기능 만들기
Code.gsfunction pushClassInfo() {
//function findNextClassを実行
var classInfos = findNextClass();
var today = new Date();
//あとで、現在より15分後の日時を取得します。
var quarterAfter = new Date();
var day = today.getDay();
var array = ["日", "月", "火", "水", "木", "金", "土"];
//quarterAfterに入っている日時が、現在より15分後になりました。
quarterAfter.setMinutes(quarterAfter.getMinutes() + 15);
var hhmmToday = Utilities.formatDate( today, 'Asia/Tokyo', 'HH:mm');
var hhmmQuarter = Utilities.formatDate( quarterAfter, 'Asia/Tokyo', 'HH:mm');
console.log(classInfos);
console.log(classInfos.startTime <= hhmmQuarter); //授業が始まるのは、今から15分後より前、つまりもうすぐ授業が始まる。
//findNextClassで取得した授業が現在の曜日のものか
if(classInfos.classDay == array[day] && classInfos.startTime <= hhmmQuarter ){
var message = "もうすぐ次の授業です。\n" + classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime +
")\n授業名:" + classInfos.className +
"\nZoomID:" + classInfos.zoomID +
"\nPass:" + classInfos.zoomPass;
console.log(message);
//function pushを実行
push(message, classInfos.zoomPass);
} else {console.log("not upcoming one ");}
}
흐름으로서는 fuction findNextClass
로 1번 가까운 수업을 취득해, 그것이 시작되는 것이 지금으로부터 15분 이내인지 판별해, true라면 클래스의 정보를 push한다고 하는 느낌입니다.
지정된 시간에 알림이 전송되도록합니다.
코드(코피페로 움직입니다)
Code.gs//授業時間が設定されている時、その授業時間の10分前にpushClassInfoを実行するタイマーをセットする
function setTrigger(){
var today = new Date();
var year = today.getFullYear();
var month = today.getMonth();
var date = today.getDate();
for(let i=3; i <= 27; i+=4) {
if(sheet.getRange(i, 1).getValue()){
var classStart = sheet.getRange(i, 1).getValue();
var startMinutes = classStart.getMinutes();
classStart.setFullYear(year);
classStart.setMonth(month);
classStart.setDate(date);
classStart.setMinutes(startMinutes - 10);
console.log(classStart);
ScriptApp.newTrigger('pushClassInfo').timeBased().at(classStart).create();
}
}
}
function delTrigger() {
var triggers = ScriptApp.getProjectTriggers();
for(let i=0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() == "pushClassInfo") {
ScriptApp.deleteTrigger(triggers[i]);
}
}
}
트리거 사용법
ScriptApp.newTrigger('function名').timeBased().at(時間).create()
에서 트리거라는 것을 설정하는 것이 가능합니다. 이 트리거를 사용하면 지정된 날짜와 시간에 함수를 실행할 수 있습니다.
단, 세트한 트리거는 계속 남아 버리므로 deleleTrigger
로 삭제합니다.
그리고는, function setTrigger를 이른 아침에, delTrigger를 자정에 실행하는 설정을 하면 완료입니다.
setTrigger와 delTrigger를 매일 호출
h tps://이웃이 다른 t. 작은 m/가 s-t 리깅 r- 등 t/#와 C4
이 기사의 「5. 매일 지정 시간의 Date 객체를 작성한다」를 참고로, setTrigger를 이른 아침(1한 이전의 시간)에, delTrigger를 자정(7한 이후의 시간)에 세트 해 제발. 즉, 기사의 작업을 2회 행합니다.
덧붙여서 1~4도 ScriptApp.newTrigger
에 대해 자세하게 해설해 주고 있으므로, 읽으면 공부가 됩니다.
이것으로 완성입니다!
마지막으로 업데이트를 잊지 마세요.
최종 코드의 전체 이미지
모두 작성한 후의 코드는 다음과 같습니다.
Code.gsvar access_token = "アクセストークン"
// 自分のユーザーIDを指定します。LINE Developersの「Your user ID」の部分です。
var user_id = "ユーザーID"
//★★スプレッドシートID★★
var ss = SpreadsheetApp.openById("スプレッドシートID");
//★★シート名★★
var sheet = ss.getSheetByName("シート名");
function doPost(e) {
var event = JSON.parse(e.postData.contents).events[0];
var returnMessage = "曜日と時限(半角:1〜7)を指定してね!\n次の授業が知りたいときは、「次」と入力してね!";
if(event.source.userId == user_id){
//返信するためのトークン取得
var reply_token= event.replyToken;
if (typeof reply_token === 'undefined') {
return;
}
var message = event.message.text;
for(let i=3; i<=7; i ++) {
var dateColumn = i;
var day = sheet.getRange(1, i).getValue();
if(message.includes(day)){
for(let j=2; j<=26; j += 4) {
var classNumRow = j;
var classNum = sheet.getRange(j, 1).getValue();
if(message.includes(classNum) && sheet.getRange(classNumRow, dateColumn).getValue()){
var classInfos = getClassInfo(classNumRow, dateColumn);
var returnMessage = classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime +
")\n授業名:" + classInfos.className +
"\nZoomID: " + classInfos.zoomID +
"\nPass: " + classInfos.zoomPass;
reply(reply_token, returnMessage);
} else if(message.includes(classNum) && !sheet.getRange(classNumRow, dateColumn).getValue()) {
var returnMessage = "授業はありません。"
reply(reply_token, returnMessage);
}
}
}
}
if(message.includes("次")){
var classInfos = findNextClass();
var returnMessage = classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime +
")\n授業名:" + classInfos.className +
"\nZoomID: " + classInfos.zoomID +
"\nPass: " + classInfos.zoomPass;
reply(reply_token, returnMessage);
} else {reply(reply_token, returnMessage);}
}
}
function reply(reply_token, returnMessage) {
var reply_url = 'https://api.line.me/v2/bot/message/reply';
// メッセージを返信
UrlFetchApp.fetch(reply_url, {
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + access_token,
},
'method': 'post',
'payload': JSON.stringify({
'replyToken': reply_token,
'messages': [{
'type': 'text',
'text': returnMessage,
}],
}),
});
return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
function push(text, zoom) {
//メッセージを送信(push)する時に必要なurlでこれは、皆同じなので、修正する必要ありません。
//この関数は全て基本コピペで大丈夫です。
var url = "https://api.line.me/v2/bot/message/push";
var headers = {
"Content-Type" : "application/json; charset=UTF-8",
'Authorization': 'Bearer ' + access_token,
};
//toのところにメッセージを送信したいユーザーのIDを指定します。(toは最初の方で自分のIDを指定したので、linebotから自分に送信されることになります。)
//textの部分は、送信されるメッセージが入ります。createMessageという関数で定義したメッセージがここに入ります。
var postData = {
"to" : user_id,
"messages" : [
{
'type':'text',
'text':text,
},
{
'type':'text',
'text':zoom,
}
]
};
var options = {
"method" : "post",
"headers" : headers,
"payload" : JSON.stringify(postData)
};
return UrlFetchApp.fetch(url, options);
}
function pushClassInfo() {
var classInfos = findNextClass();
var today = new Date();
var quarterAfter = new Date();
var day = today.getDay();
var array = ["日", "月", "火", "水", "木", "金", "土"];
quarterAfter.setMinutes(quarterAfter.getMinutes() + 15);
var hhmmToday = Utilities.formatDate( today, 'Asia/Tokyo', 'HH:mm');
var hhmmQuarter = Utilities.formatDate( quarterAfter, 'Asia/Tokyo', 'HH:mm');
console.log(classInfos);
console.log(classInfos.startTime <= hhmmQuarter); //授業が始まるのは、今から15分後より前、つまりもうすぐ授業が始まる。
if(classInfos.classDay == array[day] && classInfos.startTime <= hhmmQuarter ){
var message = "もうすぐ次の授業です。\n" + classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime +
")\n授業名:" + classInfos.className +
"\nZoomID:" + classInfos.zoomID +
"\nPass:" + classInfos.zoomPass;
console.log(message);
push(message, classInfos.zoomPass);
} else {console.log("not upcoming one ");}
}
function findNextClass() {
var today = new Date();
var hour = today.getHours();
var minutes = today.getMinutes();
console.log(today);
for(let i=0; i <= 6; i++) {
var day = (today.getDay() + i) % 7;
var dateColumn = day + 3;
var array = ['日','月','火','水','木', '金', '土'];
console.log("曜日:" + array[day]);
var searchHour = 0;
if(day == today.getDay()){searchHour = hour;} else { searchHour = 6;}
for(var j=0; j < 24-searchHour; j++) {
console.log(searchHour + "時");
for(let k=2; k <= 26; k+=4){
var classNumRow = k;
var startTimeRow = k + 1;
//始業時間が設定されている場合、始業時間を取得
if(sheet.getRange(startTimeRow, 1).getValue()) {
var startTime = sheet.getRange(startTimeRow, 1).getValue();
var startHour = startTime.getHours();
var startMinutes = startTime.getMinutes();
console.log("start hour: " + startHour);
//検索した時、今と検索時間の日付と時間が一致していても、今の分が始業の分を超えている場合は情報を取得しない
if(searchHour === startHour && today.getDay() === day && hour === searchHour && minutes > startMinutes){
console.log("\nalready orver\n");
//時間が一致し、授業が存在する場合、情報を取得
} else if(searchHour === startHour && sheet.getRange(classNumRow, dateColumn).getValue()){
var classInfos = getClassInfo(classNumRow, dateColumn);
return classInfos;
}
}
}
searchHour += 1;
}
}
}
function getClassInfo(rowNum, dateColumn){
var className = sheet.getRange(rowNum, dateColumn).getValue();
var classDay = sheet.getRange(1, dateColumn).getValue();
var classNum = sheet.getRange(rowNum, 1).getValue();
var startTime = Utilities.formatDate( sheet.getRange(rowNum + 1, 1).getValue(), 'Asia/Tokyo', 'HH:mm');
var endTime = Utilities.formatDate( sheet.getRange(rowNum + 3, 1).getValue(), 'Asia/Tokyo', 'HH:mm');
var zoomID = sheet.getRange(rowNum + 1, dateColumn).getValue();
var zoomPass = sheet.getRange(rowNum + 2, dateColumn).getValue();
var classInfos = {className: className, classDay: classDay, classNum: classNum, startTime: startTime, endTime: endTime, zoomID: zoomID, zoomPass: zoomPass};
return classInfos;
}
function setTrigger(){
var today = new Date();
var year = today.getFullYear();
var month = today.getMonth();
var date = today.getDate();
for(let i=3; i <= 27; i+=4) {
if(sheet.getRange(i, 1).getValue()){
var classStart = sheet.getRange(i, 1).getValue();
var startMinutes = classStart.getMinutes();
classStart.setFullYear(year);
classStart.setMonth(month);
classStart.setDate(date);
classStart.setMinutes(startMinutes - 10);
console.log(classStart);
ScriptApp.newTrigger('pushClassInfo').timeBased().at(classStart).create();
}
}
}
function delTrigger() {
var triggers = ScriptApp.getProjectTriggers();
for(let i=0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() == "pushClassInfo") {
ScriptApp.deleteTrigger(triggers[i]);
}
}
}
마지막으로
어땠습니까?
나는 이것을 만들었을 때, 문계에서도 이런 것을 만들 수 있다고 감동했습니다.
문계 시선으로 가능한 한 알기 쉽게 해설을 넣을 생각이므로, 조금이라도 도움이 되면 기쁩니다.
덧붙여 미경험문계 대학생이 쓰고 있으므로, 잘못등 있을지도 모릅니다만 양해 바랍니다.
끝까지 일해 주셔서 감사합니다!
Reference
이 문제에 관하여(문장에서도 알 수 있는, GAS에 의한 수업 통지의 LINE bot 작성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Ko001/items/d35a74e3be452198b8f2
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
function push(text, zoom) {
//メッセージを送信(push)する時に必要なurlでこれは、皆同じなので、修正する必要ありません。
//この関数は全て基本コピペで大丈夫です。
var url = "https://api.line.me/v2/bot/message/push";
var headers = {
"Content-Type" : "application/json; charset=UTF-8",
'Authorization': 'Bearer ' + access_token,
};
//toのところにメッセージを送信したいユーザーのIDを指定します。(toは最初の方で自分のIDを指定したので、linebotから自分に送信されることになります。)
//textの部分は、送信されるメッセージが入ります。createMessageという関数で定義したメッセージがここに入ります。
var postData = {
"to" : user_id,
"messages" : [
{
'type':'text',
'text':text,
},
{
'type':'text',
'text':zoom,
}
]
};
var options = {
"method" : "post",
"headers" : headers,
"payload" : JSON.stringify(postData)
};
return UrlFetchApp.fetch(url, options);
}
Code.gs
function pushClassInfo() {
//function findNextClassを実行
var classInfos = findNextClass();
var today = new Date();
//あとで、現在より15分後の日時を取得します。
var quarterAfter = new Date();
var day = today.getDay();
var array = ["日", "月", "火", "水", "木", "金", "土"];
//quarterAfterに入っている日時が、現在より15分後になりました。
quarterAfter.setMinutes(quarterAfter.getMinutes() + 15);
var hhmmToday = Utilities.formatDate( today, 'Asia/Tokyo', 'HH:mm');
var hhmmQuarter = Utilities.formatDate( quarterAfter, 'Asia/Tokyo', 'HH:mm');
console.log(classInfos);
console.log(classInfos.startTime <= hhmmQuarter); //授業が始まるのは、今から15分後より前、つまりもうすぐ授業が始まる。
//findNextClassで取得した授業が現在の曜日のものか
if(classInfos.classDay == array[day] && classInfos.startTime <= hhmmQuarter ){
var message = "もうすぐ次の授業です。\n" + classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime +
")\n授業名:" + classInfos.className +
"\nZoomID:" + classInfos.zoomID +
"\nPass:" + classInfos.zoomPass;
console.log(message);
//function pushを実行
push(message, classInfos.zoomPass);
} else {console.log("not upcoming one ");}
}
흐름으로서는
fuction findNextClass
로 1번 가까운 수업을 취득해, 그것이 시작되는 것이 지금으로부터 15분 이내인지 판별해, true라면 클래스의 정보를 push한다고 하는 느낌입니다.지정된 시간에 알림이 전송되도록합니다.
코드(코피페로 움직입니다)
Code.gs//授業時間が設定されている時、その授業時間の10分前にpushClassInfoを実行するタイマーをセットする
function setTrigger(){
var today = new Date();
var year = today.getFullYear();
var month = today.getMonth();
var date = today.getDate();
for(let i=3; i <= 27; i+=4) {
if(sheet.getRange(i, 1).getValue()){
var classStart = sheet.getRange(i, 1).getValue();
var startMinutes = classStart.getMinutes();
classStart.setFullYear(year);
classStart.setMonth(month);
classStart.setDate(date);
classStart.setMinutes(startMinutes - 10);
console.log(classStart);
ScriptApp.newTrigger('pushClassInfo').timeBased().at(classStart).create();
}
}
}
function delTrigger() {
var triggers = ScriptApp.getProjectTriggers();
for(let i=0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() == "pushClassInfo") {
ScriptApp.deleteTrigger(triggers[i]);
}
}
}
트리거 사용법
ScriptApp.newTrigger('function名').timeBased().at(時間).create()
에서 트리거라는 것을 설정하는 것이 가능합니다. 이 트리거를 사용하면 지정된 날짜와 시간에 함수를 실행할 수 있습니다.
단, 세트한 트리거는 계속 남아 버리므로 deleleTrigger
로 삭제합니다.
그리고는, function setTrigger를 이른 아침에, delTrigger를 자정에 실행하는 설정을 하면 완료입니다.
setTrigger와 delTrigger를 매일 호출
h tps://이웃이 다른 t. 작은 m/가 s-t 리깅 r- 등 t/#와 C4
이 기사의 「5. 매일 지정 시간의 Date 객체를 작성한다」를 참고로, setTrigger를 이른 아침(1한 이전의 시간)에, delTrigger를 자정(7한 이후의 시간)에 세트 해 제발. 즉, 기사의 작업을 2회 행합니다.
덧붙여서 1~4도 ScriptApp.newTrigger
에 대해 자세하게 해설해 주고 있으므로, 읽으면 공부가 됩니다.
이것으로 완성입니다!
마지막으로 업데이트를 잊지 마세요.
최종 코드의 전체 이미지
모두 작성한 후의 코드는 다음과 같습니다.
Code.gsvar access_token = "アクセストークン"
// 自分のユーザーIDを指定します。LINE Developersの「Your user ID」の部分です。
var user_id = "ユーザーID"
//★★スプレッドシートID★★
var ss = SpreadsheetApp.openById("スプレッドシートID");
//★★シート名★★
var sheet = ss.getSheetByName("シート名");
function doPost(e) {
var event = JSON.parse(e.postData.contents).events[0];
var returnMessage = "曜日と時限(半角:1〜7)を指定してね!\n次の授業が知りたいときは、「次」と入力してね!";
if(event.source.userId == user_id){
//返信するためのトークン取得
var reply_token= event.replyToken;
if (typeof reply_token === 'undefined') {
return;
}
var message = event.message.text;
for(let i=3; i<=7; i ++) {
var dateColumn = i;
var day = sheet.getRange(1, i).getValue();
if(message.includes(day)){
for(let j=2; j<=26; j += 4) {
var classNumRow = j;
var classNum = sheet.getRange(j, 1).getValue();
if(message.includes(classNum) && sheet.getRange(classNumRow, dateColumn).getValue()){
var classInfos = getClassInfo(classNumRow, dateColumn);
var returnMessage = classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime +
")\n授業名:" + classInfos.className +
"\nZoomID: " + classInfos.zoomID +
"\nPass: " + classInfos.zoomPass;
reply(reply_token, returnMessage);
} else if(message.includes(classNum) && !sheet.getRange(classNumRow, dateColumn).getValue()) {
var returnMessage = "授業はありません。"
reply(reply_token, returnMessage);
}
}
}
}
if(message.includes("次")){
var classInfos = findNextClass();
var returnMessage = classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime +
")\n授業名:" + classInfos.className +
"\nZoomID: " + classInfos.zoomID +
"\nPass: " + classInfos.zoomPass;
reply(reply_token, returnMessage);
} else {reply(reply_token, returnMessage);}
}
}
function reply(reply_token, returnMessage) {
var reply_url = 'https://api.line.me/v2/bot/message/reply';
// メッセージを返信
UrlFetchApp.fetch(reply_url, {
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + access_token,
},
'method': 'post',
'payload': JSON.stringify({
'replyToken': reply_token,
'messages': [{
'type': 'text',
'text': returnMessage,
}],
}),
});
return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
function push(text, zoom) {
//メッセージを送信(push)する時に必要なurlでこれは、皆同じなので、修正する必要ありません。
//この関数は全て基本コピペで大丈夫です。
var url = "https://api.line.me/v2/bot/message/push";
var headers = {
"Content-Type" : "application/json; charset=UTF-8",
'Authorization': 'Bearer ' + access_token,
};
//toのところにメッセージを送信したいユーザーのIDを指定します。(toは最初の方で自分のIDを指定したので、linebotから自分に送信されることになります。)
//textの部分は、送信されるメッセージが入ります。createMessageという関数で定義したメッセージがここに入ります。
var postData = {
"to" : user_id,
"messages" : [
{
'type':'text',
'text':text,
},
{
'type':'text',
'text':zoom,
}
]
};
var options = {
"method" : "post",
"headers" : headers,
"payload" : JSON.stringify(postData)
};
return UrlFetchApp.fetch(url, options);
}
function pushClassInfo() {
var classInfos = findNextClass();
var today = new Date();
var quarterAfter = new Date();
var day = today.getDay();
var array = ["日", "月", "火", "水", "木", "金", "土"];
quarterAfter.setMinutes(quarterAfter.getMinutes() + 15);
var hhmmToday = Utilities.formatDate( today, 'Asia/Tokyo', 'HH:mm');
var hhmmQuarter = Utilities.formatDate( quarterAfter, 'Asia/Tokyo', 'HH:mm');
console.log(classInfos);
console.log(classInfos.startTime <= hhmmQuarter); //授業が始まるのは、今から15分後より前、つまりもうすぐ授業が始まる。
if(classInfos.classDay == array[day] && classInfos.startTime <= hhmmQuarter ){
var message = "もうすぐ次の授業です。\n" + classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime +
")\n授業名:" + classInfos.className +
"\nZoomID:" + classInfos.zoomID +
"\nPass:" + classInfos.zoomPass;
console.log(message);
push(message, classInfos.zoomPass);
} else {console.log("not upcoming one ");}
}
function findNextClass() {
var today = new Date();
var hour = today.getHours();
var minutes = today.getMinutes();
console.log(today);
for(let i=0; i <= 6; i++) {
var day = (today.getDay() + i) % 7;
var dateColumn = day + 3;
var array = ['日','月','火','水','木', '金', '土'];
console.log("曜日:" + array[day]);
var searchHour = 0;
if(day == today.getDay()){searchHour = hour;} else { searchHour = 6;}
for(var j=0; j < 24-searchHour; j++) {
console.log(searchHour + "時");
for(let k=2; k <= 26; k+=4){
var classNumRow = k;
var startTimeRow = k + 1;
//始業時間が設定されている場合、始業時間を取得
if(sheet.getRange(startTimeRow, 1).getValue()) {
var startTime = sheet.getRange(startTimeRow, 1).getValue();
var startHour = startTime.getHours();
var startMinutes = startTime.getMinutes();
console.log("start hour: " + startHour);
//検索した時、今と検索時間の日付と時間が一致していても、今の分が始業の分を超えている場合は情報を取得しない
if(searchHour === startHour && today.getDay() === day && hour === searchHour && minutes > startMinutes){
console.log("\nalready orver\n");
//時間が一致し、授業が存在する場合、情報を取得
} else if(searchHour === startHour && sheet.getRange(classNumRow, dateColumn).getValue()){
var classInfos = getClassInfo(classNumRow, dateColumn);
return classInfos;
}
}
}
searchHour += 1;
}
}
}
function getClassInfo(rowNum, dateColumn){
var className = sheet.getRange(rowNum, dateColumn).getValue();
var classDay = sheet.getRange(1, dateColumn).getValue();
var classNum = sheet.getRange(rowNum, 1).getValue();
var startTime = Utilities.formatDate( sheet.getRange(rowNum + 1, 1).getValue(), 'Asia/Tokyo', 'HH:mm');
var endTime = Utilities.formatDate( sheet.getRange(rowNum + 3, 1).getValue(), 'Asia/Tokyo', 'HH:mm');
var zoomID = sheet.getRange(rowNum + 1, dateColumn).getValue();
var zoomPass = sheet.getRange(rowNum + 2, dateColumn).getValue();
var classInfos = {className: className, classDay: classDay, classNum: classNum, startTime: startTime, endTime: endTime, zoomID: zoomID, zoomPass: zoomPass};
return classInfos;
}
function setTrigger(){
var today = new Date();
var year = today.getFullYear();
var month = today.getMonth();
var date = today.getDate();
for(let i=3; i <= 27; i+=4) {
if(sheet.getRange(i, 1).getValue()){
var classStart = sheet.getRange(i, 1).getValue();
var startMinutes = classStart.getMinutes();
classStart.setFullYear(year);
classStart.setMonth(month);
classStart.setDate(date);
classStart.setMinutes(startMinutes - 10);
console.log(classStart);
ScriptApp.newTrigger('pushClassInfo').timeBased().at(classStart).create();
}
}
}
function delTrigger() {
var triggers = ScriptApp.getProjectTriggers();
for(let i=0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() == "pushClassInfo") {
ScriptApp.deleteTrigger(triggers[i]);
}
}
}
마지막으로
어땠습니까?
나는 이것을 만들었을 때, 문계에서도 이런 것을 만들 수 있다고 감동했습니다.
문계 시선으로 가능한 한 알기 쉽게 해설을 넣을 생각이므로, 조금이라도 도움이 되면 기쁩니다.
덧붙여 미경험문계 대학생이 쓰고 있으므로, 잘못등 있을지도 모릅니다만 양해 바랍니다.
끝까지 일해 주셔서 감사합니다!
Reference
이 문제에 관하여(문장에서도 알 수 있는, GAS에 의한 수업 통지의 LINE bot 작성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Ko001/items/d35a74e3be452198b8f2
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
//授業時間が設定されている時、その授業時間の10分前にpushClassInfoを実行するタイマーをセットする
function setTrigger(){
var today = new Date();
var year = today.getFullYear();
var month = today.getMonth();
var date = today.getDate();
for(let i=3; i <= 27; i+=4) {
if(sheet.getRange(i, 1).getValue()){
var classStart = sheet.getRange(i, 1).getValue();
var startMinutes = classStart.getMinutes();
classStart.setFullYear(year);
classStart.setMonth(month);
classStart.setDate(date);
classStart.setMinutes(startMinutes - 10);
console.log(classStart);
ScriptApp.newTrigger('pushClassInfo').timeBased().at(classStart).create();
}
}
}
function delTrigger() {
var triggers = ScriptApp.getProjectTriggers();
for(let i=0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() == "pushClassInfo") {
ScriptApp.deleteTrigger(triggers[i]);
}
}
}
h tps://이웃이 다른 t. 작은 m/가 s-t 리깅 r- 등 t/#와 C4
이 기사의 「5. 매일 지정 시간의 Date 객체를 작성한다」를 참고로, setTrigger를 이른 아침(1한 이전의 시간)에, delTrigger를 자정(7한 이후의 시간)에 세트 해 제발. 즉, 기사의 작업을 2회 행합니다.
덧붙여서 1~4도
ScriptApp.newTrigger
에 대해 자세하게 해설해 주고 있으므로, 읽으면 공부가 됩니다.이것으로 완성입니다!
마지막으로 업데이트를 잊지 마세요.
최종 코드의 전체 이미지
모두 작성한 후의 코드는 다음과 같습니다.
Code.gsvar access_token = "アクセストークン"
// 自分のユーザーIDを指定します。LINE Developersの「Your user ID」の部分です。
var user_id = "ユーザーID"
//★★スプレッドシートID★★
var ss = SpreadsheetApp.openById("スプレッドシートID");
//★★シート名★★
var sheet = ss.getSheetByName("シート名");
function doPost(e) {
var event = JSON.parse(e.postData.contents).events[0];
var returnMessage = "曜日と時限(半角:1〜7)を指定してね!\n次の授業が知りたいときは、「次」と入力してね!";
if(event.source.userId == user_id){
//返信するためのトークン取得
var reply_token= event.replyToken;
if (typeof reply_token === 'undefined') {
return;
}
var message = event.message.text;
for(let i=3; i<=7; i ++) {
var dateColumn = i;
var day = sheet.getRange(1, i).getValue();
if(message.includes(day)){
for(let j=2; j<=26; j += 4) {
var classNumRow = j;
var classNum = sheet.getRange(j, 1).getValue();
if(message.includes(classNum) && sheet.getRange(classNumRow, dateColumn).getValue()){
var classInfos = getClassInfo(classNumRow, dateColumn);
var returnMessage = classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime +
")\n授業名:" + classInfos.className +
"\nZoomID: " + classInfos.zoomID +
"\nPass: " + classInfos.zoomPass;
reply(reply_token, returnMessage);
} else if(message.includes(classNum) && !sheet.getRange(classNumRow, dateColumn).getValue()) {
var returnMessage = "授業はありません。"
reply(reply_token, returnMessage);
}
}
}
}
if(message.includes("次")){
var classInfos = findNextClass();
var returnMessage = classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime +
")\n授業名:" + classInfos.className +
"\nZoomID: " + classInfos.zoomID +
"\nPass: " + classInfos.zoomPass;
reply(reply_token, returnMessage);
} else {reply(reply_token, returnMessage);}
}
}
function reply(reply_token, returnMessage) {
var reply_url = 'https://api.line.me/v2/bot/message/reply';
// メッセージを返信
UrlFetchApp.fetch(reply_url, {
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + access_token,
},
'method': 'post',
'payload': JSON.stringify({
'replyToken': reply_token,
'messages': [{
'type': 'text',
'text': returnMessage,
}],
}),
});
return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
function push(text, zoom) {
//メッセージを送信(push)する時に必要なurlでこれは、皆同じなので、修正する必要ありません。
//この関数は全て基本コピペで大丈夫です。
var url = "https://api.line.me/v2/bot/message/push";
var headers = {
"Content-Type" : "application/json; charset=UTF-8",
'Authorization': 'Bearer ' + access_token,
};
//toのところにメッセージを送信したいユーザーのIDを指定します。(toは最初の方で自分のIDを指定したので、linebotから自分に送信されることになります。)
//textの部分は、送信されるメッセージが入ります。createMessageという関数で定義したメッセージがここに入ります。
var postData = {
"to" : user_id,
"messages" : [
{
'type':'text',
'text':text,
},
{
'type':'text',
'text':zoom,
}
]
};
var options = {
"method" : "post",
"headers" : headers,
"payload" : JSON.stringify(postData)
};
return UrlFetchApp.fetch(url, options);
}
function pushClassInfo() {
var classInfos = findNextClass();
var today = new Date();
var quarterAfter = new Date();
var day = today.getDay();
var array = ["日", "月", "火", "水", "木", "金", "土"];
quarterAfter.setMinutes(quarterAfter.getMinutes() + 15);
var hhmmToday = Utilities.formatDate( today, 'Asia/Tokyo', 'HH:mm');
var hhmmQuarter = Utilities.formatDate( quarterAfter, 'Asia/Tokyo', 'HH:mm');
console.log(classInfos);
console.log(classInfos.startTime <= hhmmQuarter); //授業が始まるのは、今から15分後より前、つまりもうすぐ授業が始まる。
if(classInfos.classDay == array[day] && classInfos.startTime <= hhmmQuarter ){
var message = "もうすぐ次の授業です。\n" + classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime +
")\n授業名:" + classInfos.className +
"\nZoomID:" + classInfos.zoomID +
"\nPass:" + classInfos.zoomPass;
console.log(message);
push(message, classInfos.zoomPass);
} else {console.log("not upcoming one ");}
}
function findNextClass() {
var today = new Date();
var hour = today.getHours();
var minutes = today.getMinutes();
console.log(today);
for(let i=0; i <= 6; i++) {
var day = (today.getDay() + i) % 7;
var dateColumn = day + 3;
var array = ['日','月','火','水','木', '金', '土'];
console.log("曜日:" + array[day]);
var searchHour = 0;
if(day == today.getDay()){searchHour = hour;} else { searchHour = 6;}
for(var j=0; j < 24-searchHour; j++) {
console.log(searchHour + "時");
for(let k=2; k <= 26; k+=4){
var classNumRow = k;
var startTimeRow = k + 1;
//始業時間が設定されている場合、始業時間を取得
if(sheet.getRange(startTimeRow, 1).getValue()) {
var startTime = sheet.getRange(startTimeRow, 1).getValue();
var startHour = startTime.getHours();
var startMinutes = startTime.getMinutes();
console.log("start hour: " + startHour);
//検索した時、今と検索時間の日付と時間が一致していても、今の分が始業の分を超えている場合は情報を取得しない
if(searchHour === startHour && today.getDay() === day && hour === searchHour && minutes > startMinutes){
console.log("\nalready orver\n");
//時間が一致し、授業が存在する場合、情報を取得
} else if(searchHour === startHour && sheet.getRange(classNumRow, dateColumn).getValue()){
var classInfos = getClassInfo(classNumRow, dateColumn);
return classInfos;
}
}
}
searchHour += 1;
}
}
}
function getClassInfo(rowNum, dateColumn){
var className = sheet.getRange(rowNum, dateColumn).getValue();
var classDay = sheet.getRange(1, dateColumn).getValue();
var classNum = sheet.getRange(rowNum, 1).getValue();
var startTime = Utilities.formatDate( sheet.getRange(rowNum + 1, 1).getValue(), 'Asia/Tokyo', 'HH:mm');
var endTime = Utilities.formatDate( sheet.getRange(rowNum + 3, 1).getValue(), 'Asia/Tokyo', 'HH:mm');
var zoomID = sheet.getRange(rowNum + 1, dateColumn).getValue();
var zoomPass = sheet.getRange(rowNum + 2, dateColumn).getValue();
var classInfos = {className: className, classDay: classDay, classNum: classNum, startTime: startTime, endTime: endTime, zoomID: zoomID, zoomPass: zoomPass};
return classInfos;
}
function setTrigger(){
var today = new Date();
var year = today.getFullYear();
var month = today.getMonth();
var date = today.getDate();
for(let i=3; i <= 27; i+=4) {
if(sheet.getRange(i, 1).getValue()){
var classStart = sheet.getRange(i, 1).getValue();
var startMinutes = classStart.getMinutes();
classStart.setFullYear(year);
classStart.setMonth(month);
classStart.setDate(date);
classStart.setMinutes(startMinutes - 10);
console.log(classStart);
ScriptApp.newTrigger('pushClassInfo').timeBased().at(classStart).create();
}
}
}
function delTrigger() {
var triggers = ScriptApp.getProjectTriggers();
for(let i=0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() == "pushClassInfo") {
ScriptApp.deleteTrigger(triggers[i]);
}
}
}
마지막으로
어땠습니까?
나는 이것을 만들었을 때, 문계에서도 이런 것을 만들 수 있다고 감동했습니다.
문계 시선으로 가능한 한 알기 쉽게 해설을 넣을 생각이므로, 조금이라도 도움이 되면 기쁩니다.
덧붙여 미경험문계 대학생이 쓰고 있으므로, 잘못등 있을지도 모릅니다만 양해 바랍니다.
끝까지 일해 주셔서 감사합니다!
Reference
이 문제에 관하여(문장에서도 알 수 있는, GAS에 의한 수업 통지의 LINE bot 작성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Ko001/items/d35a74e3be452198b8f2
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
var access_token = "アクセストークン"
// 自分のユーザーIDを指定します。LINE Developersの「Your user ID」の部分です。
var user_id = "ユーザーID"
//★★スプレッドシートID★★
var ss = SpreadsheetApp.openById("スプレッドシートID");
//★★シート名★★
var sheet = ss.getSheetByName("シート名");
function doPost(e) {
var event = JSON.parse(e.postData.contents).events[0];
var returnMessage = "曜日と時限(半角:1〜7)を指定してね!\n次の授業が知りたいときは、「次」と入力してね!";
if(event.source.userId == user_id){
//返信するためのトークン取得
var reply_token= event.replyToken;
if (typeof reply_token === 'undefined') {
return;
}
var message = event.message.text;
for(let i=3; i<=7; i ++) {
var dateColumn = i;
var day = sheet.getRange(1, i).getValue();
if(message.includes(day)){
for(let j=2; j<=26; j += 4) {
var classNumRow = j;
var classNum = sheet.getRange(j, 1).getValue();
if(message.includes(classNum) && sheet.getRange(classNumRow, dateColumn).getValue()){
var classInfos = getClassInfo(classNumRow, dateColumn);
var returnMessage = classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime +
")\n授業名:" + classInfos.className +
"\nZoomID: " + classInfos.zoomID +
"\nPass: " + classInfos.zoomPass;
reply(reply_token, returnMessage);
} else if(message.includes(classNum) && !sheet.getRange(classNumRow, dateColumn).getValue()) {
var returnMessage = "授業はありません。"
reply(reply_token, returnMessage);
}
}
}
}
if(message.includes("次")){
var classInfos = findNextClass();
var returnMessage = classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime +
")\n授業名:" + classInfos.className +
"\nZoomID: " + classInfos.zoomID +
"\nPass: " + classInfos.zoomPass;
reply(reply_token, returnMessage);
} else {reply(reply_token, returnMessage);}
}
}
function reply(reply_token, returnMessage) {
var reply_url = 'https://api.line.me/v2/bot/message/reply';
// メッセージを返信
UrlFetchApp.fetch(reply_url, {
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + access_token,
},
'method': 'post',
'payload': JSON.stringify({
'replyToken': reply_token,
'messages': [{
'type': 'text',
'text': returnMessage,
}],
}),
});
return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
function push(text, zoom) {
//メッセージを送信(push)する時に必要なurlでこれは、皆同じなので、修正する必要ありません。
//この関数は全て基本コピペで大丈夫です。
var url = "https://api.line.me/v2/bot/message/push";
var headers = {
"Content-Type" : "application/json; charset=UTF-8",
'Authorization': 'Bearer ' + access_token,
};
//toのところにメッセージを送信したいユーザーのIDを指定します。(toは最初の方で自分のIDを指定したので、linebotから自分に送信されることになります。)
//textの部分は、送信されるメッセージが入ります。createMessageという関数で定義したメッセージがここに入ります。
var postData = {
"to" : user_id,
"messages" : [
{
'type':'text',
'text':text,
},
{
'type':'text',
'text':zoom,
}
]
};
var options = {
"method" : "post",
"headers" : headers,
"payload" : JSON.stringify(postData)
};
return UrlFetchApp.fetch(url, options);
}
function pushClassInfo() {
var classInfos = findNextClass();
var today = new Date();
var quarterAfter = new Date();
var day = today.getDay();
var array = ["日", "月", "火", "水", "木", "金", "土"];
quarterAfter.setMinutes(quarterAfter.getMinutes() + 15);
var hhmmToday = Utilities.formatDate( today, 'Asia/Tokyo', 'HH:mm');
var hhmmQuarter = Utilities.formatDate( quarterAfter, 'Asia/Tokyo', 'HH:mm');
console.log(classInfos);
console.log(classInfos.startTime <= hhmmQuarter); //授業が始まるのは、今から15分後より前、つまりもうすぐ授業が始まる。
if(classInfos.classDay == array[day] && classInfos.startTime <= hhmmQuarter ){
var message = "もうすぐ次の授業です。\n" + classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime +
")\n授業名:" + classInfos.className +
"\nZoomID:" + classInfos.zoomID +
"\nPass:" + classInfos.zoomPass;
console.log(message);
push(message, classInfos.zoomPass);
} else {console.log("not upcoming one ");}
}
function findNextClass() {
var today = new Date();
var hour = today.getHours();
var minutes = today.getMinutes();
console.log(today);
for(let i=0; i <= 6; i++) {
var day = (today.getDay() + i) % 7;
var dateColumn = day + 3;
var array = ['日','月','火','水','木', '金', '土'];
console.log("曜日:" + array[day]);
var searchHour = 0;
if(day == today.getDay()){searchHour = hour;} else { searchHour = 6;}
for(var j=0; j < 24-searchHour; j++) {
console.log(searchHour + "時");
for(let k=2; k <= 26; k+=4){
var classNumRow = k;
var startTimeRow = k + 1;
//始業時間が設定されている場合、始業時間を取得
if(sheet.getRange(startTimeRow, 1).getValue()) {
var startTime = sheet.getRange(startTimeRow, 1).getValue();
var startHour = startTime.getHours();
var startMinutes = startTime.getMinutes();
console.log("start hour: " + startHour);
//検索した時、今と検索時間の日付と時間が一致していても、今の分が始業の分を超えている場合は情報を取得しない
if(searchHour === startHour && today.getDay() === day && hour === searchHour && minutes > startMinutes){
console.log("\nalready orver\n");
//時間が一致し、授業が存在する場合、情報を取得
} else if(searchHour === startHour && sheet.getRange(classNumRow, dateColumn).getValue()){
var classInfos = getClassInfo(classNumRow, dateColumn);
return classInfos;
}
}
}
searchHour += 1;
}
}
}
function getClassInfo(rowNum, dateColumn){
var className = sheet.getRange(rowNum, dateColumn).getValue();
var classDay = sheet.getRange(1, dateColumn).getValue();
var classNum = sheet.getRange(rowNum, 1).getValue();
var startTime = Utilities.formatDate( sheet.getRange(rowNum + 1, 1).getValue(), 'Asia/Tokyo', 'HH:mm');
var endTime = Utilities.formatDate( sheet.getRange(rowNum + 3, 1).getValue(), 'Asia/Tokyo', 'HH:mm');
var zoomID = sheet.getRange(rowNum + 1, dateColumn).getValue();
var zoomPass = sheet.getRange(rowNum + 2, dateColumn).getValue();
var classInfos = {className: className, classDay: classDay, classNum: classNum, startTime: startTime, endTime: endTime, zoomID: zoomID, zoomPass: zoomPass};
return classInfos;
}
function setTrigger(){
var today = new Date();
var year = today.getFullYear();
var month = today.getMonth();
var date = today.getDate();
for(let i=3; i <= 27; i+=4) {
if(sheet.getRange(i, 1).getValue()){
var classStart = sheet.getRange(i, 1).getValue();
var startMinutes = classStart.getMinutes();
classStart.setFullYear(year);
classStart.setMonth(month);
classStart.setDate(date);
classStart.setMinutes(startMinutes - 10);
console.log(classStart);
ScriptApp.newTrigger('pushClassInfo').timeBased().at(classStart).create();
}
}
}
function delTrigger() {
var triggers = ScriptApp.getProjectTriggers();
for(let i=0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() == "pushClassInfo") {
ScriptApp.deleteTrigger(triggers[i]);
}
}
}
어땠습니까?
나는 이것을 만들었을 때, 문계에서도 이런 것을 만들 수 있다고 감동했습니다.
문계 시선으로 가능한 한 알기 쉽게 해설을 넣을 생각이므로, 조금이라도 도움이 되면 기쁩니다.
덧붙여 미경험문계 대학생이 쓰고 있으므로, 잘못등 있을지도 모릅니다만 양해 바랍니다.
끝까지 일해 주셔서 감사합니다!
Reference
이 문제에 관하여(문장에서도 알 수 있는, GAS에 의한 수업 통지의 LINE bot 작성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Ko001/items/d35a74e3be452198b8f2텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)