- ヨシモト
総記事本数:17
営業部ヨシモトです。
以前GASを使ってGmailから本文の一部を抜き出すという記事を書きましたが、今回はその応用編とも言えます。
Gmailで受信したメールをスプレッドシートで集計する方法として、以前ご紹介したのは下記のようなメールを「何行目から~」という方法でした。
—————-
≪お客様≫からお問合せがありました。
内容は以下の通りです。
■ご用件:資料請求について
■お名前:ヨシモト
■ご連絡先電話番号:090-****-****
■ご連絡先メールアドレス:sample@example.com
■お問い合わせ内容:資料を送ってください。
■送信元:スマートフォン
—————-
ですが、これがもしも
—————-
≪お客様≫からお問合せがありました。
内容は以下の通りです。
■ご用件:資料請求について
■お名前:株式会社ヨシモト
ヨシモト部 ヨシモト
■ご連絡先電話番号:090-****-****
■ご連絡先メールアドレス:sample@example.com
■お問い合わせ内容:資料を送ってください。
今日の17時までにください。
難しければお電話ください。
■送信元:スマートフォン
—————-
(やや無理やりですが)というメールだった場合はメールによって行数が変わるため、行番号を指定するという以前の方法では取得位置がズレます。
これを解決するために正規表現を使います。
正規表現とはwikipediaによると
“正規表現(せいきひょうげん、英: regular expression)とは、文字列の集合を一つの文字列で表現する方法の一つである。正則表現(せいそくひょうげん)とも呼ばれ、形式言語理論の分野では比較的こちらの訳語の方が使われる。まれに正規式と呼ばれることもある。”
だそうです。
ものすごく嚙み砕いていうと、
「イニシャルサイト」という文字列の集合を一つの文字列で表現すると「カタカナ」です!
みたいな感じです。
「イニシャルサイト」・・・文字列の集合
「カタカナ」・・・一つの文字列で表現する
なぜ正規表現を使うのかというと、
—————–
イニシャルサイトは横浜市中区の会社です。
—————–
このような文章から「カタカナだけを抜き出す」という指示をすると「イニシャルサイト」という文字だけ抜き出すことができるからです。
前回の記事と同様に「受信日」「ご用件」「送信元」を抜き出すことにします。
前回のコードをそのまま実行すると
こうなります。ズレていますね。
では正規表現を使って抜き出してみましょう
コードはこうしてみました。※\は円マークでなくバックスラッシュなのでご注意ください。
function RegExpForm() {
var sheet = SpreadsheetApp.getActiveSheet();
var thds = GmailApp.search("お問合せがありました", 0, 30);
var messe = GmailApp.getMessagesForThreads(thds);
for(var i = 0; i < messe.length; i++) {
for(var j = 0; j < messe[i].length; j++) {
var date = thds[i].getMessages()[j].getDate();
var body = messe[i][j].getPlainBody();
var regBiz = new RegExp('■ご用件:' + '.*?' + '\r' );
var Biz = body.match(regBiz)[0].replace('■ご用件:', '').replace('\r', '');
var regSend = new RegExp('■送信元:' + '.*?' + '\r' );
var Send = body.match(regSend)[0].replace('■送信元:', '').replace('\r', '');
sheet.appendRow([date, Biz, Send]);
}
}
//受信日時順の昇順に並び替え
var range = sheet.getRange("A:C");
range.sort({column: 1, ascending: true});
}
これを実行すると
ズレずに取れました。
for(var i=0; i < messe.length; i++) {
for(var j=0; j < messe[i].length; j++) {
・
・(処理)
・
}
}
Gmailは基本的にスレッドでメッセージを管理していて、
getMessagesForThreads()を使うと該当するスレッドの全てのメッセージを取得してくれます。
その構造としては、
var regBiz = new RegExp('■ご用件:' + '.*?' + '\r' );
var Biz = body.match(regBiz)[0].replace('■ご用件:', '').replace('\r', '');
ここで正規表現を使います。
new RegExp()で何に一致させるのかを指定します。
上の行は’■ご用件’にから始まり、.*?(任意の文字が0回以上含まれていて)、\r(改行)で終わる部分に一致させるようにしています。
「■ご用件:資料請求について」ここですね。下の行では「■ご用件:」と\r(改行)をreplaceで空欄に置き換えて「資料請求について」だけが残るようになっています。
sheet.appendRow([date, Biz, Send]);
appendRow()を使うと中に入れてある要素を行の最後に追加してくれます。
ここでは「受信日」「用件」「送信元」を配列にして指定しています。
正規表現を自在に使えるととても強力なのでなんとしてもものにしたいところですね。
今回は下記の記事を参考にさせていただきました。ありがとうございます。
Google Apps Scriptでメールから正規表現で抽出したデータをスプレッドシートに蓄積する方法
その他、スプレッドシートやGASに関する記事はこちらからどうぞ。
【GAS】正規表現を使ってGmailの本文から文章を抜き出す
【簡単】GASでスプレッドシートの送信リストからメールを送る
【GAS】正規表現を使って複数行の文章をGmailから抜き出す
【GAS】Gmailの受信トレイにあるメールの添付ファイルを自動でGoogleドライブへ保存する
【難しくない】GASでwebスクレイピングして正規表現でデータを集める
【GAS】お手軽なOCRの自動化をスプレッドシートで扱いやすくする
ReactとFirebase(Cloud Firestore)を使って独り言WEBアプリをつくる
それでは!
お問い合わせ内容の3行を抜き出したいときはどうすればいいのでしょうか?
GAS初心者 さん
コメントありがとうございます。
私もわからなかったので調べてみました。
記事に書いてみましたのでぜひご覧ください。
【GAS】正規表現を使って複数行の文章をGmailから抜き出す
ヨシモトさん
本当にありがとうございました!
まとめたページまで作っていただいてありがとうございました。
「’.*?’」の部分を「'[\\s\\S]*?’」に変えます。この部分が明確に記載できなくてすごい悩んでいました。
私はこの後、メール詳細の本文にある複数の改行を除きたくて、また時間がかかってしまいましたが、
おかげさまで実装できました。
まさか、ご回答いただけるとは思っておらず、本当に感謝しております。
P.S.
コメントにソースを書いていただいたとき、「'[\\s\\S]+?’」
現状の説明ページ「'[\\s\\S]*?’」
と、少し表現が違うようなのですが、同じ意味合いなのでしょうか。
ど素人の質問で申し訳ございません。
GAS初心者 さん
コメントありがとうございます。
>コメントにソースを書いていただいたとき、「'[\\s\\S]+?’」
>現状の説明ページ「'[\\s\\S]*?’」
>と、少し表現が違うようなのですが、同じ意味合いなのでしょうか。
今回のケースではほぼほぼ同じ動作をしますが、
厳密には
“X* Xが0 回以上”
“X+ Xが1 回以上”
という違いがあります。
こちらを参考にさせていただきました。
正規表現の基本 | Qiita
私も新しい知識を得ることができた良い機会でした。
ありがとうございました。
先程のコメントは投稿されていますでしょうか。
ttmさん
ttmさんからはこれが初めてのコメントのようです。
恐れ入りますが改めてご投稿いただけますでしょうか。
専門外のデザイナーですが、
ここを読んでやりたいことができました!ありがとうございます。
1件質問ですが、この方法だと本文を引用した返信の内容も検索結果に含まれてしまいますが
返信のみ(re付き)除外する方法はありますか?
また、問い合わせ欄に無回答の項目がある場合エラーで停止してしまうのですがnullの解決方法はありますでしょうか?
design akiさん
コメントありがとうございます。
>1件質問ですが、この方法だと本文を引用した返信の内容も検索結果に含まれてしまいますが
>返信のみ(re付き)除外する方法はありますか?
→Gmailの検索結果の時点で弾いてしまうのが簡単だと思います。
var thds = GmailApp.search(“お問合せがありました -subject:re”, 0, 30);
-subject:reとすると検索結果から、件名にreを含むものを除外してくれます。
これはGASというよりもGmailで使える知識なので覚えておくと便利ですよ。
参考: Gmail で使用できる検索演算子
>また、問い合わせ欄に無回答の項目がある場合エラーで停止してしまうのですがnullの解決方法はありますでしょうか?
→無回答であってもメールにラベル名(■ご用件:)を含んでいれば空で取得できると思いますが、ラベル名もなかった場合は止まると思います。
var regBiz = new RegExp(‘■ご用件:’ + ‘.*?’ + ‘\r’ );
var Biz = body.match(regBiz)? body.match(regBiz)[0]: “”;
Biz.replace(‘■ご用件:’, ”).replace(‘\r’, ”);
三項演算子というものを使います。
var a = x? x:y これはxがtrue(値がある)だったらx、false(値がない、nullやundefinedなど)だったらyをaに代入してくれます。
つまり、上のコードはラベル名含めてマッチすればそのまま、
マッチしなければ空にします。
これで解決すると思いますので試してみてください。
ヨシモト
コメントをどうぞ