1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Wakatimeから週一で届くメールをGASでSpreadSheetに自動転記する】

Last updated at Posted at 2021-02-27

最近Wakatimeというツールを使ってコーディングの時間を可視化できるようにvscodeにインストールして使っているのですが、週一でそのデータがメールで送られてくるのでGASを使ってSpreadSheetに定期的に転記させるようにしてみた

wakatimeを使っていて、言語ごとの使用頻度とかだけ記録しておきたいひとはコピペすれば多分いける


以下のsetTrigger()を一度実行すれば7日ごとにgetWakaFunc()が実行される。

//定期実行関数
function setTrigger() { 
  ScriptApp.newTrigger('getWakaFunc').timeBased().everyDays(7).create();  
}

以下の関数を実行すると言語ごとの使用時間のみを抽出できる

→大まかな流れ
support@wakatime.comに一致するメールの中身を取得
・言語ごとの使用時間が記載されているところのみ抽出
・spreadSheetの最後の行に書き込み
・処理済みラベルをつけて2回読み込まれないようにする

追記......2021/5/6
wakatimeから送られてくるアドレスが変わりました。
support@wakatime.com -> noreply@wakatime.com

//wakatimeから受け取ったメールを古い順に並べる関数
function getWakamail(){
  let WakaAddress = 'noreply@wakatime.com';
  var threads = GmailApp.search(`from:${WakaAddress} has:nouserlabels`);
  var reversedThreads = threads.reverse();
  return reversedThreads;
}

// wakatimeから受け取ったメールを転記する関数
function getWakaFunc(){
  var threads = getWakamail();
  threads.forEach((thread) => {
    let messages = thread.getMessages();
    let plainBodies = [];
    
    messages.forEach((message) => {
      var kennmei = message.getSubject().slice(1,7);
      if(kennmei === 'weekly'){
        plainBodies.push(message.getPlainBody());
      }else{
        plainBodies = null;
      }
    })
            
    if(plainBodies){
       const splitPlainBodies = plainBodies[0].split('\n')
       
       const totalTime = splitPlainBodies[0].match(/(..) hrs (..) mins/)
       //Logger.log(totalTime)
       
       const reportRange = splitPlainBodies[1].split('?')
       const startEndRange = reportRange[1].split('&').map((range) => {
                 let splitRange = range.split('=')
                 return splitRange[1]
       })
       //Logger.log(startEndRange)
       
       let languages = []
       let frag = 0 
       splitPlainBodies.forEach(body => {
          //Logger.log(body)
          if(body.match(/(Languages:)/)){
              frag = 1
          }
          if(body.match(/(Editors:)/)){
              frag = 0
          }
          if(frag === 1){
              languages.push(body)
          }
       })
       const mapLanguages = languages.slice(1, -2).map((lang) => {
          return lang.trim().split(':')
       })
       //Logger.log(mapLanguages)
       // spreadSheetの下に追加させる関数
       writeSpreadSheetFunc(startEndRange.join(' until '), totalTime, mapLanguages)
       var label = GmailApp.getUserLabelByName("Gas処理済み");
       thread.addLabel(label);
       
    }else{
      return;
    }
    
  })
}
// spreadSheetの下に追加させる関数
function writeSpreadSheetFunc(range, weekTotalTime, languages){
    
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = ss.getSheets()[0];
    var lastRow = sheet.getLastRow() + 1;
    
    sheet.getRange(lastRow, 1).setValue(range);
    sheet.getRange(lastRow, 2).setValue(weekTotalTime);
    
    let n = 0;
    languages.forEach((lang) => {
        sheet.getRange(lastRow + n, 3).setValue(lang[0])
        sheet.getRange(lastRow + n, 4).setValue(lang[1])
        n++
    })
}

正規表現使って文字列を整えるのが大変でした。おかげで少し慣れた


以下のようにまとめることができる。
最近はNode.jsばっかり
A879CE63-4DEA-4B98-8211-FFB3B48753D4.jpeg
もっと詳細なデータが欲しくなったら、WakatimeAPIとか使ってみようと思います。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?