ChatworkとGmailを連携して、請求をラクにしたい

2019/2/1 ms office outlookからのメール、HTML形式が来ると動作がおかしかったのでコード修正。エモアイコン変換されるので[code]で囲む。

# 毎月の請求を作るのが辛い
毎月、チャットワークやメールを読み返して、
金額について触れている部分を精査し、
請求金額を確定して請求書を作っている。

チャットワークだとまだいい。
装飾で金額部分を目立たせるルールでやり取りしているため、本文読まずとも流し読みで金額が拾えるからだ。

問題はメールベース、電話ベースで対応行っているお客さん。
メールを読み込んで、金額の部分を探し、それが無ければどれくらいの作業だったか思い出して、、
と請求作成にとにかく気力がいるのである。

毎月のことだし。
これなんとかしたい。

# チャットワーク式に管理できないか
世の中にはもっと効率的な請求管理システムがあるのかもしれない。
ただ、常に見積もり通りにはいかない。
相手とのやり取りの中でなんとなく仕事が発生する場合もあるのが常なんだ。
だからやり取り追って金額センテンスを見つけなければならないのだ。

まだ効率的な管理方式がイメージできていないため、
とりあえずメールベースのお客さんも、チャットワークの前述の方式に合わせられないか試行錯誤する。

検索したら一発で出てきた。
[[e]Gmailとチャットワークを連携させたら仕事が効率化して最高だった](https://ehicalog.net/chatwork-gmail.html)

本当は、お客様にチャットワークを使ってくれるようお願いするのが早いのだけれど、、

とりあえず、
メールをチャットワークに転記して、都度装飾でメモ的に金額を張り付けていく
ようなルールでやってみようということになった。

# 実装の流れ
上記リンク通りでだいたいいいんだけども、後ろのほうに何点か改善したスクリプトを記載します。
1. GoogleDriveからGoogleAppsScriptの初期設定
2. スクリプトの設置
3. 結果

## 1. GoogleDriveからGoogleAppsScriptの初期設定
上記リンク先通りで大丈夫です。
注意点としては使用するgmailのアカウントでGoogleDriveにログインして設定するんだと思う。

## 2. スクリプトの設置、トリガーの設定
上記リンク先だと何点か問題があったので修正してます。

- chatwork投稿時にはじめから装飾されてるので、装飾を簡素にした
- ログの閲覧性を上げるため、メール本文に200文字までの制限、空行の除去、引用行の除去を追加。
- 相手のメールだけログで読めればいいため、自分fromのメールは除外するようにした
- 上記リンクの「スクリプトの問題点」部分をなんとなく回避
  - スレッドのメッセージごとに処理してるはずなので、スレッドの一件目が延々と送られてくることはないはず
- メッセージ既読にしないようにした
  - 「既読」にしたりis:unreadで管理するとタイミングによって転記されなくなりそうなのでラベル付けして管理に変更
  - Gmail側でラベルの事前作成が必要。ネストしたラベルの場合はaaa/chtwrk等にスクリプト変更が必要だろうけど未テスト
  - ほんとはGoogleAppsScript側でラベル作成まで出来ればよかったんだけどできないようなので妥協

アカウントIDは数字のみのタイプを使わないと、やはりtoで呼びかけに失敗するようだ。
chatwork idではないので注意。調べ方は以下リンク先で。
http://help.receptionist.jp/?p=5225

```javascript
var CW_TOKEN          = 'xxxxxxxxxxx'; // チャットワークAPIトークン
var ROOM_ID           = 1234567890123; // 通知宛先ルームID
var ACCOUNT_ID        = 'xxxxx123456'; // アカウントID
var exclude_mail_addr = "xxx__123456_,_@gmail.com"; // 除外する自分のメールアドレス
var gmlabel_title     = "chtwrk"; // ラベル名
var search_str        = '"A会社" OR "B会社"'; // 検索クエリ
var max_body_read_num = 200; // bodyの文字数制限
var on_msoutlook_originalmsg_delete = true;

function sendMessage(body){
    var params = {
        headers : {"X-ChatWorkToken" : CW_TOKEN},
        method : "post",
        payload : { body : body }
    };
    var url = "https://api.chatwork.com/v2/rooms/" + ROOM_ID + "/messages";
    UrlFetchApp.fetch(url, params);
}
function fetchContactMail() {
    var terms = '(in:inbox newer_than:1d -label:'+gmlabel_title+' '+search_str+')'; // 過去1日の受信トレイと文字列を検索
    var myThreads = GmailApp.search(terms);

    myThreads.forEach(function(thread) {
        var messages = thread.getMessages();
        messages.forEach(function(message) {
            var mid     = message.getId();
            var plink   = thread.getPermalink();
            var subject = message.getSubject();
            var body    = message.getPlainBody();
            var to      = message.getTo();
            var from    = message.getFrom();
            var date    = Utilities.formatDate(message.getDate(), 'Asia/Tokyo', "yyyy年M月d日(E) HH:mm:ss");

            if (from.indexOf(exclude_mail_addr) != -1) return;

            var label = GmailApp.getUserLabelByName(gmlabel_title);
            label.addToThread(thread);

            var my_msg_body = body.trim();
            my_msg_body = my_msg_body.replace(/(\r?\n)+/g,"\n"); // 空行trim
            my_msg_body = my_msg_body.replace(/[>].*(\r?\n)/g,""); // 引用行trim
            if (on_msoutlook_originalmsg_delete) {
              my_msg_body = my_msg_body.replace(/-*?Original\sMessage\-*?(\r?\n)([\n\r]|.)*/,''); // MS Outlookの引用行以降を削除
            }
            my_msg_body = my_msg_body.slice(0,max_body_read_num);

            var msg_body = "[To:" + ACCOUNT_ID + "]" + "from: " + from + " title: " + subject + " 日付: "+ date + "[hr][code]" + my_msg_body + "[/code]";
            sendMessage(msg_body);
        });
    });
}
```
# 実行結果
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/25349/20e1eaf0-3663-ec35-a77d-9ae70fb52dcd.png)
↓
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/25349/71b1ef99-8a2a-a60a-fde5-06d05e23b972.png)

一旦これで運用してみてまた機会があれば更新したい。