🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
LINE Messaging API

LINE Messaging APIは、メッセージの送信・返信ができるAPIです。Web APIを経由しアプリケーションサーバとLINEのAPIでやり取りが可能。複数のメッセージタイプや分かりやすいAPIリファレンスを持ち、グループチャットにも対応しています。

Google カレンダー

Google カレンダーは、Google社が提供する無料のスケジュール管理ツールです。パソコンやスマートフォン、タブレットなどからアクセスし、スケジュールの追加・変更が可能。Googleアカウントがあれば誰でも使用できます。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

解決済

1回答

397閲覧

カレンダーのイベントに特定の文字がある時だけLINE通知したい

Sou23

総合スコア38

LINE Messaging API

LINE Messaging APIは、メッセージの送信・返信ができるAPIです。Web APIを経由しアプリケーションサーバとLINEのAPIでやり取りが可能。複数のメッセージタイプや分かりやすいAPIリファレンスを持ち、グループチャットにも対応しています。

Google カレンダー

Google カレンダーは、Google社が提供する無料のスケジュール管理ツールです。パソコンやスマートフォン、タブレットなどからアクセスし、スケジュールの追加・変更が可能。Googleアカウントがあれば誰でも使用できます。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

0クリップ

投稿2021/03/28 07:51

編集2021/06/22 07:44

前提・実現したいこと

カレンダーの終日イベントに特定の文字がある時だけLINE通知したいです。

発生している問題・エラーメッセージ

x.match is not a functionというエラーが出ます。

GAS

1function gomi() { 2 //line 3 var token = '******'; 4 5 //calendar 6 var cal = CalendarApp.getCalendarById('***@***'); 7 var starttime = new Date(); 8 starttime.setHours(0); 9 starttime.setMinutes(0); 10 starttime.setSeconds(0); 11 var endtime = new Date(); 12 endtime.setHours(23); 13 endtime.setMinutes(59); 14 endtime.setSeconds(59); 15 var events = cal.getEvents(starttime,endtime); 16var values = []; 17 events.forEach(function(event){ 18 var title = event.getTitle(); 19 var allday = event.isAllDayEvent(); 20 if(allday === true){ 21 values.push([title]); 22 x = values.join; 23 } 24 25 26 var today = new Date(); 27 var day = today.getDay(); 28 var yasumi = x.match(/***/); 29 Logger.log(yasumi); 30 31if(yasumi === '***' && day == '1'){ 32 var x = 'ゴミの日です' 33}else if(yasumi === '***' && day == '3'){ 34 var x = '資源ごみの日です'; 35 }else if(yasumi === '***' && day == '4'){ 36 var x = 'ゴミの日です'; 37 }else{ 38 return; 39} 40let options = { 41 "method" : "post", 42 "headers" : { 43 "Authorization" : "Bearer "+ token 44 }, 45 "payload" : { 46 "message" : x 47 } 48 }//oprions done 49 let url = "https://notify-api.line.me/api/notify" 50 UrlFetchApp.fetch(url, options) 51 } 52 ) 53}//done

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/03/28 08:00 編集

[投稿 2021/03/28 16:51時点の内容に対する質問] 「しかしカレンダーに終日イベントがない場合があり、そうすると配列が空になってしまい動かなくなります。」という質問文中の「配列」とは、 コード中の「values」を指していると推測しましたが、合っていますか? 仮にこれが合っているとして、「動かなくなります。」とは、具体的にどのようなエラーが表示されているのでしょうか? コードでは values.push([title]); 以降、valuesがどこにも使われていません。 もし質問文に記載のない部分でエラーが発生しているならば、そのコードも記載してください エラーが発生していないのであれば、「動かなくなります」の具体的な意味を教えてください。 (可能ならば全部のコードを記載していただくのが改善の早道ですが)
Sou23

2021/06/22 07:44

大変遅くなり申し訳ございません。 エラー内容とコード全文を記載いたしました。 お時間ございましたらご一読いただけますと幸いです。
退会済みユーザー

退会済みユーザー

2021/06/22 14:20 編集

1. コード中の「***」というのは、実際は何か別の文字なのを便宜上置き換えているというわけではなく 本当に「***」(アスタリスク3つ)という解釈でよいのでしょうか? (「***」(アスタリスク3つ)をマッチさせればよいのか?という意味です。 もし、アスタリスク3つではなく、何か別の文字である場合は、その文字を教えてください。 このことを尋ねる理由:「アスタリスク3つ」をマッチさせる場合、特別な書き方が必要になるからです。また、アスタリスク3つではなくとも、マッチさせたい文字によって、match関数の引数の書き方が変わってくるからです。) 2. 仮に↑の質問1でマッチさせたい文字列が「***」であると仮定したうえで、下記について教えてください。 タイトルに「***」を含むイベントが同じ日に複数ある場合であっても、「ゴミの日です'」(または「資源ごみの日です」)というメッセージをLINEに投稿するのは、1回だけでよいのでしょうか。 それとも、「***」を含むイベントの数だけ投稿する必要があるのでしょうか?(例:2つのイベントのタイトルに「***」が含まれていた場合は2回投稿する)
Sou23

2021/06/22 23:39

ありがとうございます。 アスタリスクは実際の文字ではありません! また複数イベントがある場合でも1回のみ通知をしたいと思っており、またイベントがない場合にも一回通知をしたいと思っております。 よろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2021/06/23 00:34

上記のソースを見ると ・***にマッチする終日イベントがある場合は「ごみの日です」または「資源ごみ日です」というメッセージだけを通知する。(***にマッチしないイベントのタイトルは、通知メッセージに含まない) ・***にマッチする終日イベントが1つもない場合は、その日のすべてのイベントのタイトルを連結した文字列を通知する。 としたいように見えますが、この理解で合っていますでしょうか?
Sou23

2021/06/23 00:41

いえ、実際には***がとマッチする場合には通知をせず、***があり、かつ特定の曜日の場合には通知をするというふうにしたいのですが、「終日イベントがない場合」という条件の作り方がわからず(***がない場合は多くの場合終日イベント自体がありません)、現状のようになっています。 複雑で申し訳ありませんがよろしくお願いします。
guest

回答1

0

ベストアンサー

希望される正確な挙動が今一つわからなかったのですが、下記のように修正すればとりあえずエラーは出なくなると思います。
(「***」のところは実際に使用する文字に変えてください。アスタリスクが含まれる文字では正確に動きません)

function gomi() { //line var token = '******'; //calendar var cal = CalendarApp.getCalendarById('***@***'); var starttime = new Date(); starttime.setHours(0); starttime.setMinutes(0); starttime.setSeconds(0); var endtime = new Date(); endtime.setHours(23); endtime.setMinutes(59); endtime.setSeconds(59); var events = cal.getEvents(starttime,endtime); var x =''; var values = []; events.forEach(function(event){ var title = event.getTitle(); var allday = event.isAllDayEvent(); if(allday === true){ values.push([title]); x = values.join(); } var today = new Date(); var day = today.getDay(); var yasumi = x.match(/***/); if(yasumi.indexOf('***') !== -1 && day == 1){ var x = 'ゴミの日です' }else if(yasumi.indexOf('***') !== -1 && day == 3){ var x = '資源ごみの日です'; }else if(yasumi.indexOf('***') !== -1 && day == 4){ var x = 'ゴミの日です'; }else{ return; } let options = { "method" : "post", "headers" : { "Authorization" : "Bearer "+ token }, "payload" : { "message" : x } }//oprions done let url = "https://notify-api.line.me/api/notify" UrlFetchApp.fetch(url, options) } ) }//done

  • 説明
x = values.join; ↓ x = values.join();

→「join()」とする必要があります。
また、各々のif~else内でvar xとするよりは、それ以前で1回でまとめて var x = '';というように定義しておいた方がよいと思います。

if(yasumi === '***' && day == '1'){ ↓ if(yasumi.indexOf('***') !== -1 && day == 1){
  • xはmatch関数の結果を受け取っているので配列となっています。yasumiは配列xをjoin()で連結しているので、カンマで区切られた文字列になっています。

したがって、yasumiという文字列の中に「***」が含まれているかどうかは比較演算子===では正確には判定できません。 代わりに、indexOfで判定するやり方があります。
※(「***」のところは実際に使用する文字に変えてください。アスタリスクが含まれる文字では正確に動きません)

  • getDay()関数は数字(Number型)を返すので 比較先は文字列('1')ではなく、数字(1)にする必要があります。

 

参考:もし私であれば、下記のように仕様をきちんと明らかにしたうえで、下記のようなコードにします。
(質問者さんの希望動作と異なるかもしれませんがあくまで「例」なのでご了承ください)
[仕様]

  1. Googleカレンダーに登録されている関数実行当日のイベントのタイトルをLINE通知する。
  2. 通知対象イベント:必要条件=終日イベント(時間指定イベントは通知対象外とする)。かつ、通知の判断にあたっては、下記3,4,5の内容を考慮すること。
  3. 関数実行日が月曜日、水曜日、木曜日である場合のみ通知する。それ以外の場合は4に該当するか否にかかわらず通知しない。
  4. 通知対象イベントのタイトルに指定した文字(「※」)が含まれている場合は、曜日に応じて、下記のメッセージをタイトルに付加して通知する。

 月曜日:「[ゴミの日です]」
水曜日:「[資源ゴミの日です]」
木曜日:「[ゴミの日です]」
5. 3に該当する曜日であっても、通知対象イベントのタイトルに指定した文字(「※」)が含まれていない場合は、通知しない。
6. カレンダー上、同じ日に2つ以上イベントが登録されている場合は、1つのイベントごとに通知対象イベントであるかどうか判断した上で1つずつ通知を発行する。

function notifyGarbageCollection() { //line const token = '******'; // タイトルに含まれている場合に、「ごみの日」というメッセージを追加する文字 const EVENT_SIGN = '※' //calendar const cal = CalendarApp.getCalendarById('***@***'); const starttime = new Date(); starttime.setHours(0); starttime.setMinutes(0); starttime.setSeconds(0); const endtime = new Date(); endtime.setHours(23); endtime.setMinutes(59); endtime.setSeconds(59); const events = cal.getEvents(starttime, endtime); const day = new Date().getDay(); // カレンダーの終日イベント1件ごとにLINE通知を1回発行。 events.forEach(function(event){ const title = event.getTitle(); // 通知メッセージ let msg = title + ' '; // 取得したイベントが終日イベントでない場合はスキップ。 if(event.isAllDayEvent() === false) return; // 取得した終日イベントのタイトルに、EVENT_SIGNに指定した文字が含まれている場合, // 曜日に応じてメッセージを追加する。 if(title.indexOf(EVENT_SIGN) !== -1) { if(day == 1){ // 月曜日 msg += '[ゴミの日です]' }else if(day == 3){ // 水曜日 msg += '[資源ごみの日です]'; }else if(day == 4){ // 木曜日 msg += '[ゴミの日です]'; }else{ // 該当する曜日でない場合、通知しない。 return; } }else{ //EVENT_SIGNに指定した文字が含まれていない場合、通知しない。 return; } const url = 'https://notify-api.line.me/api/notify'; const options = { method : 'post', headers : { Authorization : 'Bearer ' + token }, payload : { message : msg } }/ UrlFetchApp.fetch(url, options); }); }

投稿2021/06/23 03:18

編集2021/06/23 03:47
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Sou23

2021/06/24 05:29

大変丁寧に教えていただきありがとうございます! 問題なく動きましたので、これからよく読み込んで勉強したいと思います。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問