ラベル Google Apps Script の投稿を表示しています。 すべての投稿を表示
ラベル Google Apps Script の投稿を表示しています。 すべての投稿を表示

2013年10月10日木曜日

GoogleSpreadSheetでToDoタスクを作り、期限が近づいたらメールで通知する。

GoogleSpreadSheetは非常に便利だ。

Excelと同じように表計算やマクロ機能(Google Apps Script)を持っているが
何と言っても一番はスケジューラ機能だ。
スプレッドシートの内容を、指定した時間にメールで通知するなんてことも可能。
これはExcelだけではなかなかできないと思う。

という訳で自分の仕事を円滑に進められるようにするためにということで、
GoogleSpreadSheetを多様しているのだが、中でもToDoリストとしての活用は
いろいろな方でも使えるものだと思うのでサンプルコードを書いてみた。

コードはGitHubにアップしているのでそれを参考にしていただければ思う。
https://github.com/maar4569/notifyToDoWithGAS

そのサンプルを元にToDoアプリを作ってみようと思う。

このToDoアプリができること。
・利用者はスプレッドシートにToDoを書く。
・ToDoの締め切り日が近づいてくるとメールで通知してくれる。
 N日前ですよとか、締め切り当日ですよとか、過ぎてますよとか。

作成手順
1.GitHubからコードをダウンロードしておく。
2.まずはGoogleドライブ上に新規のスプレッドシート「ToDoList」を作成する。
  2-1.シート名を「ToDo」に変更する。
  2-2.ToDoListに1行目のカラムに「task」「deadline」「notes」「deleted」と記述する。
 task やるべきことを書いておく。
 deadline 期日を書く。(yyyy/mm/dd形式で)
 notes 補足事項があれば書いておく。
 deleted メールで通知する必要が無くなった場合「1」と書いておくと通知しなくなる。
     つまりもう済んだタスクは1と書いておく。書かないとずっとメールで通知して
     くることになる。

  2-3.2行名以降にはやるべきtaskを書く。


3.ダウンロードしたコードを挿入する。
  3-1.空のプロジェクトを選択。 

  3-2.[ファイル]-[新規作成]-[スクリプトファイル]を選択。

  3-3.main.gsというファイル名に変更し、ダウンロードしたコードをコピペする。

4.関数 notifyDoDoを探し、変数に設定する。(赤い字のところを変更する)
function notifyToDo(){
  //Spread Sheet Config
  var sheetName      = "ToDo";  <-シート名を設定する。手順2.1でToDoにしたのでここは編集しなくてもよい。
  var spreadSheetKey = "your spread sheet Key"; <-スプレッドシートのキーを設定する
スプレッドシートを開いたときのURLで下のアドレスバーの黒塗りの箇所に該当する文字列を登録する。

  //mail config
  var subject        = "[MyToDoリストからの通知]ステータスのお知らせ";  <-メールのタイトルを設定する
  var recipients     = new Array("mailaddress"); <-メールアドレスを設定する。複数ある場合は、カンマ区切りで設定する。ex)aaa@x.com,bbb@x.com
  //notification config
  var threshold      = 4;   <-期限の4日間になったら通知する

5.関数notifyToDoを実行する。

6.SpreadSheet、Gmailの利用承認を求められる。
  6-1.「続行」をクリックする。


  6-2.「承認する」をクリックする。
   これによってこのアプリがSpreadSheetへのアクセスとメール送信が許可される。


7.トリガーを設定する。
 これは定期的にToDoの状況をメールで通知するようにするためである。

  7-1.「リソース」から「現在のプロジェクトのトリガー」を選択。

  7-2.「トリガーが設定されていません。・・・」をクリックする。

  7-3.トリガーを設定する。
          実行は、notifyTodo関数
          イベントは、時間主導型、日タイマー、午後4時から5時。
          これで毎日午後4〜5時の間にタスクのステータスがメールで通知される。



8.トリガーで設定した時間になるとメールで通知される。(めでたしめでたし)


 


2013年10月8日火曜日

ZaimとGoogleSpreadSheetが連携できない。

Zaimでは外部のサービスと連携するためにAPIを公開している。
認証はoAuth1.0aに対応しているのだが、GoogleAppsScriptと相性が悪いのか、
oAuthエラーというエラーが発生し認証に失敗する。

丸1日費やしたが失敗の原因がわからないのでひとまず撤収。
もし「できる!知ってるよ!」という方がいたら教えてください。
私が書いたコードを一応のせておきます。

var oAuthConfig = function(serviceName,accessTokenURL,requestTokenUrl,authorizationUrl){
  var m_methods = {};
  var m_oAuthConfig      = UrlFetchApp.addOAuthService(serviceName);
  m_oAuthConfig.setAccessTokenUrl( accessTokenURL );
  m_oAuthConfig.setRequestTokenUrl( requestTokenUrl );
  m_oAuthConfig.setAuthorizationUrl( authorizationUrl );
 
  var setConsumerKeyAndSecret = function(key,secret){
    ScriptProperties.setProperty('consumerKey', key);
    ScriptProperties.setProperty('consumerSecret', secret);
    m_oAuthConfig.setConsumerKey(ScriptProperties.getProperty('consumerKey'));
    m_oAuthConfig.setConsumerSecret(ScriptProperties.getProperty('consumerSecret'));
  }
  m_methods.setConsumerKeyAndSecret = setConsumerKeyAndSecret;
 
  var getConfig = function(){ return m_oAuthConfig; }
  m_methods.getConfig = getConfig;
 
  var authConfigDump = function(){
    Logger.log('AccessTokenURL->' + m_oAuthConfig.getAccessTokenUrl());
    Logger.log('AuthorizationUrl->'+ m_oAuthConfig.getAuthorizationUrl());
    Logger.log('Method->' + m_oAuthConfig.getMethod());
    Logger.log('ParameterLocation->' + m_oAuthConfig.getParamLocation());
    Logger.log('RequestTokenURL->' + m_oAuthConfig.getRequestTokenUrl());
    Logger.log('ServiceName->' + m_oAuthConfig.getServiceName());
  }
  m_methods.authConfigDump = authConfigDump;
 
  //create nonce from SHA-1 Digest 
  var getNonce = function(){
    var now = new Date();
    var nonce = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_1,now.getTime(),Utilities.Charset.US_ASCII);
    var strNonce = bytes2StringDigest(nonce);
    Logger.log('nonce(bytes2StringDigest)->'  + strNonce);
    return strNonce;
  }
  m_methods.getNonce = getNonce;
 
  return m_methods;
}
var urlString = function(url){
  var m_methods = {};
  var m_response = UrlFetchApp.getRequest(url);
  var m_methodName = m_response.method;
  var m_url        = m_response.url;

  var getMethod = function(){return m_methodName;}
  m_methods.getMethod = getMethod;
  var getUrl    = function(){ return encodeURIComponent( m_url.split('?')[0] );}
  m_methods.getUrl = getUrl;
  var getQueryStrings   = function(){ return encodeURIComponent( m_url.split('?')[1] ); }
  m_methods.getQueryStrings = getQueryStrings;
 
  var dump = function(){
    for(var i in m_response) {
       Logger.log(i + ": " + m_response[i]);
    }   
  }
  m_methods.dump = dump;
  return m_methods;
}
var getOAuthSignature = function(url,common_param_oauth){
  //HASHMAC Signature
  var urlStr = urlString(url);
  var sign_url   = encodeURIComponent(urlStr.getUrl());
  var sign_param = encodeURIComponent(urlStr.getQueryStrings());
  var sign_source = 'GET' + '&'+ sign_url + '&' +
  //  'oauth_body_hash'        + encodeURIComponent('=') + common_param_oauth.oauth_body_hash + '&' +
      'oauth_consumer_key'     + encodeURIComponent('=') + common_param_oauth.oauth_consumer_key + '&' +
        'oauth_nonce'            + encodeURIComponent('=') + common_param_oauth.oauth_nonce  +'&' +
          'oauth_signature_method' + encodeURIComponent('=') + common_param_oauth.oauth_signature_method  +'&' +
            'oauth_timestamp'        + encodeURIComponent('=') + common_param_oauth.oauth_timestamp + '&' +
              'oauth_version'          + encodeURIComponent('=') + '1.0';
  //if (sign_param != undefined){ sign_source = sign_source + '&' +  sign_param }
  Logger.log('SIGN_SOURCE->' + sign_source);
  //create Signature(HMAC SHA-1) and encode BASE64.
  var tmpSignature = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_1,sign_source,common_param_oauth.oauth_consumer_key);
  common_param_oauth.oauth_signature = Utilities.base64Encode(tmpSignature);
  Logger.log('Signature(bytecode)->' + tmpSignature );
  Logger.log('Signature(base64)->' + common_param_oauth.oauth_signature );
 
  return common_param_oauth.oauth_signature;
}
/////////////////////
//MAIN
/////////////////////
function main(){
  var serviceName      = 'Zaim';
  var accessTokenUrl   = "https://api.zaim.net/v2/auth/access";
  var requestTokenUrl  = "https://api.zaim.net/v2/auth/request";
  var authorizationUrl = "https://www.zaim.net/users/auth";
  var key              = 'Your consumerKey';
  var secret           = 'Your consumerSecret';
  var methodName       = 'get';         //default get
  var paramLocation    = 'auth-header'; //Allowed values are 'post-body', 'uri-query' and 'auth-header'.
  var tergetUrl = 'https://api.zaim.net/v2/home/user/verify';
  var response='';
  try{
    var oAuthConf = oAuthConfig(serviceName,accessTokenUrl,requestTokenUrl,authorizationUrl);
    oAuthConf.setConsumerKeyAndSecret(key,secret);
    oAuthConf.authConfigDump();
    oAuthConf.getConfig().setMethod( methodName );
    oAuthConf.getConfig().setParamLocation( paramLocation );
    oAuthConf.authConfigDump();
   
    Logger.log('key->' + ScriptProperties.getProperty('consumerKey'));
    Logger.log('secret->' + ScriptProperties.getProperty('consumerSecret'));
    var now = new Date();
    var common_param_oauth =
    {
      'oauth_consumer_key'     : ScriptProperties.getProperty('consumerKey'),
      'oauth_signature'        : '', //see after code.
      'oauth_signature_method' : 'HMAC-SHA1',
      'oauth_token'            : '',
      //'oauth_timestamp'        : now.getTime(),
      //'oauth_nonce'            : oAuthConf.getNonce(),
      'oauth_timestamp'        : '',
      'oauth_nonce'            : '',
      'oauth_version'          : '1.0'
      //'oauth_body_hash'        : ''
    };
    getOAuthSignature(tergetUrl,common_param_oauth );
    Logger.log('COMMON_PARAM_OAUTH->' + Utilities.jsonStringify(common_param_oauth));
   
    var options =
    {
      "oAuthServiceName" : serviceName,
      "oAuthUseToken" : "always",
      "method" : methodName,
      //"headers" : '',
      //"payload" : common_param_oauth,
      "muteHttpExceptions" : true
    };
    Logger.log('options->' + Utilities.jsonStringify(options));
    //var response = UrlFetchApp.fetch( tergetUrl  );
    response = UrlFetchApp.fetch( tergetUrl , options );
  }catch(e){
    Logger.log('main failure.' + e.message);
  }
}

2013/11/27
再チャレンジしたが認証エラーでやはりNG。
上のソースコードはかなり間違いがあるのだが、再度oauth_signatureの作成方法(アルゴリズム、パラメータのソート、URIエンコード・・・)などを
oauth1.0の仕様書に基づきトライしてもダメ。
ということでGoogle Apps Scriptとの連携は一旦あきらめる。



2013年9月30日月曜日

初回

とりあえずやってみようと思った事をやってみて、うまくいくか試そうと思う。

まずは自作で以前作ったGoogle Apps Scriptで作成したスケジュール作成アプリ。
UIを使って入力したスケジュールをGoogle Spread Sheet、Google CalendarやGoogle Tasksに登録し連携するもの。
仕事用に作ったかがかなり特化されているので、エッセンスを取り出してアップしていこうと思う。