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

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

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

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

```jsx
//定期実行関数
function setTrigger() { 
  ScriptApp.newTrigger('getWakaFunc').timeBased().everyDays(7).create();  
}
```
***
以下の関数を実行すると言語ごとの使用時間のみを抽出できる

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

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

```jsx
//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;
    }
    
  })
}
```

```jsx
// 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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530710/82c278d3-8ad8-de28-ba35-bb72cd93b2fe.jpeg)
もっと詳細なデータが欲しくなったら、WakatimeAPIとか使ってみようと思います。