・・・メールの返信(ブログの投稿)と Twitterへのつぶやきを タイマー予約出来る様にして診た。
警告 - 20150418 141039)
このスクリプト中、Twitter投稿での認証処理で用いている OAuthConfig が
今年頭から出ていた警告通り、20150420に廃止され 利用出来なくなります。
それに伴い、このスクリプトでは Twitter投稿部分が機能しなくなります。
同ログ中でもお世話になった きじとらさんのトコで、該当部分の代替のスクリプトが紹介されています。
おきつねさまのスクリプトのほうでも、ソチラへ差し替えを行う予定にしていますが、
単にTweetするだけなら別の認証方法もあり、ドチラを用いるべきか 検討しているトコロだったりします。
・・・まぁ このログが雑多に羅列してしまって読み辛いので、代替処理が完成したら新たにログを投稿する予定。 |
後述する書式の日時文字列を 本来の件名文字列より前につけた件名を持つプレーンテキストの短文メールに 返信先を指定した状態で
以下スクリプトを仕込んだ 該当Googleアカウントのメールアドレスへ送信しておくだけで予約が可能になる。
おきつねさま環境での 実際の運用は、そうしたメールを 自動作成して送信する様に構成された 別のローカル動作なVBScriptとの併用を
前提としているのだが、メールを送る環境さえあれば、件名を適宜入力し 対象アドレスへ送信するだけで 同様に利用出来るようになっている。
送信済みメールにもスターが付き、次回以降の処理ループ対象となってしまっていた。
対策として スターを外す処理を追記。 |
コレを実現するには、当然ながら Googleのアカウントが必要になる。
スクリプトに関しては、この ▼ きじとらさんトコのソースをベースに・・・
対象オブジェクトを [下書き] から [受信トレイ] ないし [スター付きメール] に、
日付文字列書式を "{yyyy/mm/dd hh:nn} " から "{yyyy/mm/dd hh:nn:ss} " に
送り先は メールにセットされている[送信先アドレス] から [返信先アドレス] へ それぞれ合わせて変更してある。
と云うのも、Gmailの [下書き] は ブラウザで操作して用意する必要があるので おきつねさまの用途的に使い悪く、
対象を [受信トレイ] か [スター付き受信メール] に変更する必要があり、且つ 日付文字列書式に関しては
おきつね環境での VBScript と Windows の 標準ロケールに合わせカタチ・・・
コレなら 予約メールの件名書式を | {yyyy/mm/dd hh:nn:ss} メール件名文字列 | ・・・と してあれば、 |
自分のメールアカウントで そのメールアカウントのアドレス宛に、メールの返信先として Bloggerなどでサポートされている
[ブログ投稿メールアドレス] などを セットした状態で送信すれば、指定日時に ブログを投稿してくれる と云う運用。
VBScriptでのメール投稿であれば 送信の際に[返信先(ReplyTo)]アドレスをセット出来るが、
MS-OutlookなどのMAPIクライアントでは、面倒だがアカウント設定画面でしか指定出来ない。
対処としては、Outlookなら 同じGmailアカウントで もう1つ別名を充てたOutlook内での[電子メールアカウント]を追加し、
その[詳細設定]画面 [全般]タグ [その他のユーザー情報]枠 [返信電子メール]項目に、対象となるメールアドレスを設定する。
その準備が出来てれば、以後は メール作成画面で 利用する送信アカウントを選択出来るので、
追加したアカウントで予約メールを送信するだけでいい。 |
上述 件名文字列は 日時を囲むカッコ記号と 日時文字列とタイトル文字列の間に半角スペースが それぞれ必須である点に注意。
{2014/07/13 21:27:41} メール件名文字列 | ← 因って、使う際にはこう云うカンジになる。 |
因みに、手元のWindows機材でVBScriptを用いて日付を扱う場合 その機器のWindowsでのロケール設定に依存するので、
メール送信VBScriptとの併用を行う場合は、以下ソースの対応する必要な行を それぞれ有効/無効にして利用すると良いだろう。
また、スター付きメールを扱うには、Gmailの設定画面で、受信したメールに対してスターを付ける条件を定義した
フィルタを設定しておく必要があるのだが、ソレが面倒で、且つ 他の用途に用いていない Gmailアカウントであれば、
受信トレイ全体を検索対象にするオブジェクトのほうを有効にしたほうがいいだろう。
・・・まぁ実際の用途としては、指定時刻にメールでブログを投稿し、それを
IFTTT で 検出させて
Twitterの対象アカウントに 適宜Tweetさせたいだけなんだケドねw
IFTTTにブログ投稿を監視させてTweetするのでは 遅延のバラつきが酷くて実用に耐えないと判断して廃止。
代わりに このスクリプト自体から直接つぶやくよう変更。
但し、ソレ起因で 仕様と云うか 扱いが大きく変わってしまった・・・
マズ GoogleDrive上で 単体の.gsファイルとしてではなく、
同Drive上の スプレッドシートの マクロ としての スクリプトファイルとなった。
他に機能を追加するには このほうが都合はイイと思うが、ナンか敗北感あるな・・・
単体の.gsファイルでも稼動出来ました、スプレッドシートは必要ありません。
|
自分のTwitterアカに この用途向けのアプリを設定する必要がある。
その登録時に 以下項目を
Callback URL: https://spreadsheets.google.com/macros
Permission: Read & Write |
・・・とした上で、他項目も適宜入力して利用準備を完了し、
続いて スクリプトのほうで、上述登録画面にて表示されるトークン文字列 APIKey と APISecret を
プロジェクトのプロパティに twitterAPIKey と twitterAPISecret を GUIで 手作業にて追加し、
▼ こう云う処理で GUI使わなくても プロパティにトークンをセットは出来るケド・・・
function twiProperties() {
var scriptProperties = PropertiesService.getScriptProperties();
if(!scriptProperties.getProperty('twitterAPIKey')) {
scriptProperties.setProperty('twitterAPIKey', 'ココにAPIKey');
}
if(!scriptProperties.getProperty('twitterAPISecret')) {
scriptProperties.setProperty('twitterAPISecret', 'ココにAPISecret');
}
return false;
} |
|
それぞれのトークンを 値としてセットする必要がある。
因みに、この設定をしなくても Tweet機能が動作しないだけで メール返信は処理されます。 |
・・・プレーンなままスクリプトに認証情報を置かなくていいのは こうした扱いでは便利だが、少し面倒(´ヘ`;)
せめてモノ救いは、Twiアカに紐付いているGoogleアカウントでなくても動作できる点だろうか・・・
|
GoogleAppScriptのサービス画面内のGUIで 手動で指定するトリガーではなく、
スクリプトの実行で得た 次のメール返信予約時刻を 次回のトリガーとして設定する構造に変更。
GoogleAppScriptのタイムアウトは5minだそうな・・・(´ヘ`;)
代わりに スクリプトのトリガー[起動する間隔や時間を指定する機能]のプロパティを
スクリプトで操作する方法が提供されていたので利用してみた。
これでダメなら正直お手上げ・・・
・・・暫定利用向けだから、同一プロジェクト(1つのスプレッドシートファイルや.gsファイル)で
複数の関数をトリガーしてる運用の場合には使えなくなってるので要注意。
既存の該当トリガーのみを削除するよう変更。
但し、最初の実行前にだけ、プロジェクトのプロパティとして triggerId を
値なし(未入力の空白のまま)でセットしておかないと エラーで停止すると思うな。
初期稼動時に プロパティ'triggerId' が無くても動作するよう補完。
|
|
まぁ 1hスクリプトを稼動させたままに出来るか? ってのは 概ね期待してなかったが やはりダメだったw
因って、10min毎に動作する指定にあわせて訂正・・・ とりま様子診だな・・・(´ヘ`;)
GMailのスレッド(オブジェクト)の仕様でアクセス数制限があるようnanoで 1min毎のスクリプト実行を改め、
1時間毎の動作設定に変更し、追加したマネージスクリプトで 必要な時間にのみ
返信スクリプト delaySendReceivedMail() を 処理させるようにしてみた。
仮に 運用に於いて 対象メール数が制限を超える数であった場合は効果がナイのだが、
そうした 突拍子もナイ数のメール返信を扱う予定がナイので コレでヨシとして診た。
|
さて、前置きはこの辺にして 肝心のソースを・・・
var scriptProperties = PropertiesService.getScriptProperties();
function SetupPropertys() {
var TwiAPIkey = '';
var TwiAPISecret = '';
var strFunction = 'delaySendControls';
if(!scriptProperties.getProperty('twitterAPIKey') && TwiAPIkey) {
scriptProperties.setProperty('twitterAPIKey', TwiAPIkey);
}
if(!scriptProperties.getProperty('twitterAPISecret') && TwiAPISecret) {
scriptProperties.setProperty('twitterAPISecret', TwiAPISecret);
}
if(!scriptProperties.getProperty('wTriggerIDa')) {
var w1TrigID = ScriptApp.newTrigger(strFunction).timeBased().atHour(15).nearMinute(0)
.onWeekDay(ScriptApp.WeekDay.WEDNESDAY).create().getUniqueId();
scriptProperties.setProperty('wTriggerIDa', w1TrigID);
}
if(!scriptProperties.getProperty('wTriggerIDb')) {
var w2TrigID = ScriptApp.newTrigger(strFunction).timeBased().atHour(18).nearMinute(0)
.onWeekDay(ScriptApp.WeekDay.WEDNESDAY).create().getUniqueId();
scriptProperties.setProperty('wTriggerIDb', w2TrigID);
}
var trigId = ScriptApp.newTrigger(strFunction).timeBased().after(60000).create().getUniqueId();
scriptProperties.setProperty('triggerId', trigId);
return false;
}
function delaySendControls() {
var objTrds = GmailApp.getStarredThreads();
var len = objTrds.length;
var arSendTimes = new Array();
var Pc = -1;
var sSetTime = 3600000;
if(!len){
setTrig('delaySendControls', sSetTime);
return false;
}
var NowS = new Date().getTime();
for (var i = 0, l = len; i < l; i++) {
var objMsg = GmailApp.getMessagesForThread(objTrds[i])[0];
var strSubject = objMsg.getSubject();
var inSubjects = strSubject.match(/^(\{(\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2} \d{1,2}:\d{1,2}:\d{1,2})\}) ?(.*)?/);
if (!inSubjects || !inSubjects[1]) {
objMsg.unstar();
continue;
}
var msgDT = (new Date(inSubjects[2].replace(/\-/g,'/')+' +09:00')).getTime();
if(!msgDT) {
continue;
}
if(msgDT > NowS) {
Pc = Pc + 1;
arSendTimes[Pc] = msgDT;
}
else {
if(msgDT < NowS) {
var to = objMsg.getReplyTo();
var subject = inSubjects[3] || '';
var body = objMsg.getPlainBody();
var options = {}, val;
if (!to || !body) {
continue;
}
if(tweetInitialize()) {
var twiMessage = subject + body;
twitterPost(twiMessage);
}
if (val = objMsg.getCc()) {
options['cc'] = val;
}
if (val = objMsg.getBcc()) {
options['bcc'] = val;
}
if (val = objMsg.getBody()) {
if ( val.indexOf('<div')!==-1 ) {
options['htmlBody'] = val;
}
}
if (val = objMsg.getAttachments()) {
options['attachments'] = val;
}
var status = GmailApp.sendEmail(to, subject, body, options);
if (status) {
objMsg.moveToTrash();
}
}
}
}
if(!arSendTimes[0]) {
}
else {
arSendTimes.sort(function(a,b){
if(a < b){return -1;}
if(a > b){return 1;}
return 0;
});
var sSetTime = (new Date(arSendTimes[0]).getTime()) - (new Date().getTime());
}
setTrig('delaySendControls', sSetTime);
var objTrds = null;
return false;
}
function setTrig(strFunction, sMsec) {
if(delTrig = scriptProperties.getProperty('triggerId')) {
var triggers = ScriptApp.getProjectTriggers();
for(var i in triggers) {
if(triggers[i].getUniqueId() == delTrig) {
ScriptApp.deleteTrigger(triggers[i]);
}
}
}
var trigId = ScriptApp.newTrigger(strFunction).timeBased().after(sMsec).create().getUniqueId();
scriptProperties.setProperty('triggerId', trigId);
return false;
}
function tweetInitialize() {
if(ScriptProperties.getProperty("twitterAPIKey") && ScriptProperties.getProperty("twitterAPISecret")) {
var oAuthConfig = UrlFetchApp.addOAuthService("twitter");
oAuthConfig.setAccessTokenUrl("https://api.twitter.com/oauth/access_token");
oAuthConfig.setRequestTokenUrl("https://api.twitter.com/oauth/request_token");
oAuthConfig.setAuthorizationUrl("https://api.twitter.com/oauth/authorize");
oAuthConfig.setConsumerKey(scriptProperties.getProperty("twitterAPIKey"));
oAuthConfig.setConsumerSecret(scriptProperties.getProperty("twitterAPISecret"));
return true;
}
}
function twitterPost(text) {
var options =
{
"oAuthServiceName" : "twitter",
"oAuthUseToken" : "always",
"method" : "POST"
};
text = text.replace(/[']/g,"’");
var encodedTweet = encodeURIComponent(text).replace(/[!'()*]/g, function(c) {
return "%" + c.charCodeAt(0).toString(16);
});
var result = UrlFetchApp.fetch("https://api.twitter.com/1.1/statuses/update.json?status=" + encodedTweet, options);
var o = Utilities.jsonParse(result.getContentText());
Logger.log(o);
Logger.log(result.getResponseCode());
}
function twiTest() {
if(tweetInitialize()) {
twitterPost("Testtext from Log");
}
}
|
因みに、メールの返信処理のみとして利用する場合は、Twitter向けのプロパティをセットしなければ そのように動作します。
Twitter向けプロパティ未設定で Twitter投稿機能無効化を可能に。
|
こうした GoogleAppScriptの Googleドライブへの配置と 稼動設定については、
上述の きじとらさんトコが詳しいので 参考にしてください。(丸投げw
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。