質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.35%
Google Apps Script

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

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

Q&A

解決済

1回答

1113閲覧

Google Calendarの通知時間と同時にTwitterにも投稿したい

kuroryu

総合スコア7

Google Apps Script

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

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

0グッド

0クリップ

投稿2020/02/04 00:12

編集2020/02/05 12:15

Google CalendarにRSSを読み込んだスケジュールを、Google App Scriptを実行して、カレンダーの通知時間(15分前)にTwitterに投稿したいです。
公開されているGASのコードを参考にTwitter投稿用に書き換えたのですが、通知時間になっても投稿がされません。
以下のようなコードで実行していますが、どこが間違っているのでしょうか?
Twitter認証は完了しており、通知時間になるとポップアップでデスクトップ通知は正常にされています。
GASは「時間主導型」「分ベース」「1分ごと」でトリガー設定してあり、エラーも一切なく、ログを見ると毎分「完了」となっています。
どうぞよろしくお願いいたします。

// Twitter AppのConsumer Api Key var API_KEY = "xxxxxxxxxxxxxxxx"; var API_SECRET = "yyyyyyyyyyyyyyyyyyy"; /* サービスの設定 */ function getService() { return OAuth1.createService('Twitter') .setAccessTokenUrl('https://api.twitter.com/oauth/access_token') .setRequestTokenUrl('https://api.twitter.com/oauth/request_token') .setAuthorizationUrl('https://api.twitter.com/oauth/authorize') .setConsumerKey(API_KEY) .setConsumerSecret(API_SECRET) .setCallbackFunction('authCallback') .setPropertyStore(PropertiesService.getUserProperties()); } /* コールバック関数 */ function authCallback(request) { var service = getService(); var authorized = service.handleCallback(request); if (authorized) return HtmlService.createHtmlOutput('認証成功'); } /* 認証リセット */ function reset() { getService().reset(); } /* 認証用URL */ function getOAuthURL() { Logger.log(getService().authorize()); } /*------------------------------------* * 毎分カレンダーから1週間先までの予定を見る。 * ↓ * 予定が現在、または通知を登録していた時間だった場合お知らせする *------------------------------------*/ function MinuteCheckCalender() { //カレンダーからイベントの取得 var myCals = CalendarApp.getCalendarById('zzzzz@gmail.com'); //特定のIDのカレンダーを取得 if (myCals != null) { //権限がないなどの時はnullになるので処理をスルーする //カレンダーから現在〜1週間後までのイベントを取得 var startDate = new Date(); startDate = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate(), startDate.getHours(), startDate.getMinutes(), 0); var endDate = new Date(); endDate.setDate(endDate.getDate()+7); var myEvents = myCals.getEvents(startDate, endDate); if (myEvents.length > 0) { //カレンダーに予定がない時はスルーする //お知らせが必要な予定一覧を作成する var strBody = ""; for(var i = 0; i < myEvents.length; i++){ var alertTime = -1; var strStart = myEvents[i].getStartTime(); //イベントの開始時刻 //予定の日付と今日が同じかチェックする if (startDate.getFullYear() == strStart.getFullYear()) { if (startDate.getMonth() == strStart.getMonth()) { if (startDate.getDate() == strStart.getDate()) { //予定の日時と今が同じ時分かチェックする if (startDate.getHours() == strStart.getHours()) { if (startDate.getMinutes() == strStart.getMinutes()) { //何分前の通知かを保持 alertTime = 0; } } } } } var intReminders = myEvents[i].getPopupReminders(); //何分前にお知らせするか if (intReminders != null) { if (intReminders.length > 0) { //予定の日時じゃなくても通知が登録されていれば通知時間にお知らせする if (alertTime == -1) { for (var j = 0; j < intReminders.length; j++) { //通知として登録していた日時を取得 var minute = intReminders[j]; var alertDate = new Date(strStart.getTime()); alertDate.setMinutes(alertDate.getMinutes()-minute); //通知の日時と今日が同じかチェックする if (startDate.getFullYear() == alertDate.getFullYear()) { if (startDate.getMonth() == alertDate.getMonth()) { if (startDate.getDate() == alertDate.getDate()) { //通知の日時と今が同じ時分かチェックする if (startDate.getHours() == alertDate.getHours()) { if (startDate.getMinutes() == alertDate.getMinutes()) { //何分前の通知かを保持 alertTime = minute; break; } } } } } } } } } if (alertTime >= 0) { var strTitle = myEvents[i].getTitle(); //イベントのタイトル var strEnd = myEvents[i].getEndTime(); //イベントの終了時刻 var strLocation = myEvents[i].getLocation(); //放送局 var strEvent = ""; if (strBody != "") { //他の予定の後に追加する場合は空白行を追加する strEvent += "\n\n"; } if (0 < alertTime && alertTime < 60) { strEvent += Utilities.formatDate(strStart,'JST','HH:mm')+"~"+Utilities.formatDate(strEnd,'JST','HH:mm')+" "+strLocation+"\n「"+strTitle+"」"; } if (strEvent != "") { strBody += strEvent; } } } if (strBody != "") {//Twitterに予定一覧を投稿する var service = getService(); var endPointUrl = 'https://api.twitter.com/1.1/statuses/update.json'; var response = service.fetch(endPointUrl, { method: 'post', payload: { status: strBody } } ) } } } }

追記ですが、通知時間を判定する部分、
if (0 < alertTime && alertTime < 60)

if (0 == alertTime)
に書き換えたところ、イベント開始時間ちょうどにツイート投稿されました。
つまり、通知時間の記述の仕方が間違っているということでしょうか?
素人考えなのですが、Googleカレンダーの通知時間を15分に設定しているのに、alertTime==0と記述するとイベント開始時刻にツイートされるところに違和感があります。
alertTimeは自分で通知時間設定を変更する度に変化するものだと思っているのですが、そうではないのでしょうか?

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

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

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

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

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

papinianus

2020/02/05 01:57

設定値の確認なんですが、手動で関数を実行してtweetすることはできますよね?
kuroryu

2020/02/05 02:01

はい、手動でTweetはされました。
kuroryu

2020/02/05 12:00 編集

現況ですが、通知時間を判定する部分、 if (0 < alertTime && alertTime < 60) を if (0 == alertTime) に書き換えたところ、イベント開始時間ちょうどにツイート投稿されました。 つまり、通知時間の記述の仕方が間違っているということでしょうか? 素人考えなのですが、Googleカレンダーの通知時間を15分に設定しているのに、alertTime==0と記述するとイベント開始時刻にツイートされるところに違和感があります。 alertTimeは自分で通知時間設定を変更する度に変化するものだと思っているのですが、そうではないのでしょうか?
papinianus

2020/02/05 13:47

意図はこのコードを書いた人にしかわかりません。 変更したことにより、通知時間がいつであろうとも、開始時刻ちょうどには必ず通知されるコードになっています。 変更前に、何も起こらなかったという話からすると、通知が 60 分以上前なのではないか、とか、通知時刻ちょうどに動作しなかったのではないか、などが考えられます。 とりあえず参考にしたサイトを開示していただきたいです。
papinianus

2020/02/05 14:16 編集

確認しましたが、通知が 59 分以内であれば、変更前のコードのままで、通知時間にアラートがされそうです。(ツイッタのキーをもっていないので、strbody が意図したものであることしか見てないですが)
kuroryu

2020/02/06 05:33

時間ちょうどに、意図した投稿はされるため、strbodyの記述にも間違いはないと思います。 確認したところ、通知は「15分」に設定されております。 質問に記述した通り、1分おきにトリガーを実行するように設定しており、実行ログを見ても毎分「実行」になっているのですよね・・・
papinianus

2020/02/06 08:41

ロジック部分は変えてないことを確認しました。ありがとうございます。私としてはその通知時間にコードを手動実行して通知文が生成されることを見ているのでこれ以上の調査は難しいです。 作り方としては通知時刻を過ぎていて未通知だったら通知とか、一分ずれは許容するとか、をすれば確実かなと思います。 そこまで考え出すと、そもそもツイッターに何らかの放送情報を出すのにカレンダーが適切かとかそういう話になりそうな気もします。
guest

回答1

0

ベストアンサー

多分こういうことがしたかったのではないか、というコード

javascript

1// Twitter AppのConsumer Api Key 2const API_KEY = "xxxxxxxxxxxxxxxx"; 3const API_SECRET = "yyyyyyyyyyyyyyyyyyy"; 4/* サービスの設定 */ 5function getService() { 6 return OAuth1.createService('Twitter') 7 .setAccessTokenUrl('https://api.twitter.com/oauth/access_token') 8 .setRequestTokenUrl('https://api.twitter.com/oauth/request_token') 9 .setAuthorizationUrl('https://api.twitter.com/oauth/authorize') 10 .setConsumerKey(API_KEY) 11 .setConsumerSecret(API_SECRET) 12 .setCallbackFunction('authCallback') 13 .setPropertyStore(PropertiesService.getUserProperties()); 14} 15/* コールバック関数 */ 16function authCallback(request) { 17 var service = getService(); 18 var authorized = service.handleCallback(request); 19 if (authorized) return HtmlService.createHtmlOutput('認証成功'); 20} 21/* 認証リセット */ 22function reset() { 23 getService().reset(); 24} 25/* 認証用URL */ 26function getOAuthURL() { 27 Logger.log(getService().authorize()); 28} 29 30/*------------------------------------* 31 * 毎分カレンダーから1週間先までの予定を見る。 32 * ↓ 33 * 予定が現在、または通知を登録していた時間だった場合お知らせする 34 *------------------------------------*/ 35function MinuteCheckCalender() { 36 //カレンダーからイベントの取得 37 const myCal = CalendarApp.getCalendarById('@gmail.com'); //特定のIDのカレンダーを取得 38 if (myCal -== null) return; //権限がないなどの時はnullになるので処理をスルーする 39 40 //カレンダーからイベントを取得 41 const now = new Date(); 42 const startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), 0); 43 const endDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 7, now.getHours(), now.getMinutes(), 0); 44 const events = myCal.getEvents(startDate, endDate); 45 if(events.length < 1) return; //カレンダーに予定がない時はスルーする 46 47 48 //お知らせが必要な予定一覧を作成する 49 const messages = []; 50 for(var i = 0; i < events.length; i++){ 51 const startsAt = events[i].getStartTime(); //イベントの開始時刻 52 const nowAsString = checkDateString(startDate); 53 const noticeTimes = [0].concat(events[i].getPopupReminders()).map(function(delta) { return checkDateString(new Date(startsAt.getFullYear(),startsAt.getMonth(), startsAt.getDate(), startsAt.getHours(), startsAt.getMinutes() - delta,0));}); 54 if(noticeTimes.indexOf(nowAsString) < 0) continue; 55 56 const title = events[i].getTitle(); //イベントのタイトル 57 const ends = events[i].getEndTime(); //イベントの終了時刻 58 const loc = events[i].getLocation(); //放送局 59 messages.push(toHourMin(startsAt) + "~" + toHourMin(ends) + " " + loc + "\n「" + title + "」"); 60 } 61 if(messages.length < 1) return; 62 const service = getService(); 63 const endPointUrl = 'https://api.twitter.com/1.1/statuses/update.json'; 64 const response = service.fetch(endPointUrl, { 65 method: 'post', 66 payload: { 67 status: messages.join("\n\n") 68 } 69 } 70 ) 71} 72function checkDateString(d) { 73 return Utilities.formatDate(d,'JST','YYYY/MM/dd HH:mm'); 74} 75function toHourMin(d) { 76 return Utilities.formatDate(d,'JST','HH:mm') 77}

投稿2020/02/05 14:08

編集2020/02/05 14:19
papinianus

総合スコア12705

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

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

papinianus

2020/02/05 14:20

イベントの通知時刻で取得できるところまで検証。ツイッタはわからんです。
kuroryu

2020/03/04 01:47

テスト投稿したところ、Twitter投稿されました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問