【GAS】Gmailとスプレッドシートの連携/自動転記について
解決済
回答 2
投稿
- 評価
- クリップ 0
- VIEW 2,554
前提・実現したいこと
Gmailで受信している問合せメールの内容の一部を、スプレッドシート/GASを使って下記の流れで自動的に転記できるようにしたいと考えています。
・特定のラベル付き+未読状態のメールを取得する
・メール内から該当箇所のみをスプレッドシートに転記する
・取得が終わったメールは既読状態に変更する
■元のメールデータ/例文
下記のようなメールから「問合せNo、問合せ日時、氏名、フリガナ、電話番号」の部分のみを取り出してスプレッドシートに転記したい。
(上記の項目名部分で文字列検索をする?)
XX様
この度はお問い合わせありがとうございます。
確認し、こちらからご連絡させて頂きます。
------問い合わせ日時------
問合せNo :000000
問合せ日時 :2019/12/31 00:00:00
--------お客様情報--------
氏名 :山田太郎 様
フリガナ :ヤマダタロウ 様
電話番号 :000-0000-0000
////////////////////////////
株式会社〇〇
住所
電話
メール
///////////////////////////
発生している問題・エラーメッセージ
・該当箇所のみをスプレッドシートに転記する
部分をどう記述すればいいかわからない状態です。
当方非プログラマーのため、メソッドの動作などを検索しながらサンプルコードを組み合わせて作成しておりましたが、
文字列のいい検索方法がわかりませんでした。
該当のソースコード
function getMail(){
var objSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var objSheet = objSpreadsheet.getSheetByName("シート1"); //出力先のシートを指定
var sheet = SpreadsheetApp.setActiveSheet(objSheet);
//メールチェック用の変数
var start = 0;
var max = 500;
//配列"threads"にラベルが問合せ、状態が未読のスレッドを検索、代入。
var threads = GmailApp.search('label:問合せ is:unread',start,max);
//変数"row"にスプレッドシートの最終行の次行を代入
var row = sheet.getLastRow() + 1;
//オブジェクト"threads"のプロパティ数ループする
for(var n in threads){
var thd = threads[n];
var msgs = thd.getMessages(); //未読スレッドに含まれるメッセージを配列として取得
for(var m in msgs){
var msg = msgs[m];
var body = msg.getBody(); //メール本文を1データの塊として取得する
var res = body.split("\n") //取得したメール本文を各改行列ごとに配列に代入
//indexOfで取得したい文字列が入っている配列のインデックス番号を取得→配列で書き込み?search?
//検索したい文字列に空白が含まれているのは正規表現の\sで対応?
var number = res.indexOf(/問合せNo\s\s\s:/);
var date = res.indexOf("問合せ日時 :");
var name = res.indexOf("氏名 :");
var name2 = res.indexOf("フリガナ :");
var tel = res.indexOf("電話番号 :");
//セルへの書き込みを行う
sheet.getRange(row,1).setValue(number);
sheet.getRange(row,2).setValue(res[date]);
sheet.getRange(row,3).setValue(res[name]);
sheet.getRange(row,4).setValue(res[name2]);
sheet.getRange(row,7).setValue(res[tel]);
row++
}
}
//スレッドを既読に変更する
thd.markRead();
Utilities.sleep(1000);
}
試したこと
・「var res = body.split("\n")」の段階で出力→改行部分でデータ分割はできている。
・セルへの書き込みで「number」そのものを出力すると「-1」が出力される。
→検索ができていない状態でしょうか?
補足情報(FW/ツールのバージョンなど)
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
function getMail(){
var objSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var objSheet = objSpreadsheet.getSheetByName("シート1"); //出力先のシートを指定
var sheet = SpreadsheetApp.setActiveSheet(objSheet);
//メールチェック用の変数
var start = 0;
var max = 500;
//配列"threads"にラベルが問合せ、状態が未読のスレッドを検索、代入。
var threads = GmailApp.search('label:問合せ is:unread',start,max);
//オブジェクト"threads"のプロパティ数ループする
for(var n in threads){
var thd = threads[n];
var msgs = thd.getMessages(); //未読スレッドに含まれるメッセージを配列として取得
for(var m in msgs){
var msg = msgs[m];
var body = msg.getBody(); //メール本文を1データの塊として取得する
var no = body.match(/^問合せNo\s*?:(.+)$/m)[1];
var dateandtime = body.match(/^問合せ日時\s*?:(.+)$/m)[1];
var name = body.match(/^氏名\s*?:(.+)$/m)[1];
var kana = body.match(/^フリガナ\s*?:(.+)$/m)[1];
var tel = body.match(/^電話番号\s*?:(.+)$/m)[1];
sheet.appendRow([no, dateandtime, name, kana, "", "", tel]);
}
}
//スレッドを既読に変更する
thd.markRead();
Utilities.sleep(1000);
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
papinianusさんの回答スクリプトが素晴らしく整理されてきれいに書かれているのでご活用されるのが良いと思います。
質問者さんの問題は(indexOfで指定しているワードが対象と一致していることが前提ですが)おそらくvar res = body.split("\n")が配列になっていないからと思われます。(indexOfは一致するものがないときに-1を返しますので)
var resarray = [];
resarray.push(res);
を足せばうまく動きませんか?
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.09%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2019/03/13 10:11
GASではconstでのスコープがグローバルっぽい動き(バグだと思うんですけど)するので、おそらくforの中のconstも再代入されずにずっと1行目のものが追加され続けると思われます。
GASでconstは本当の意味で再代入しない定数以外は使わないほうがいいです。
2019/03/13 10:12
var msgs = ["問合せNo :000000","問合せNo :000001","問合せNo :000002"];
for(var m in msgs){
var msg = msgs[m];
Logger.log(msg);
const no = msg.match(/^問合せNo\s*?:(.+)$/m)[1];
Logger.log(no);
}
}
2019/03/13 10:17 編集
信用しているので確認を怠って回答を直しました。
盲目的にconstにしていますが、ブロックスコープが働かないのだとすると(javaの影響でしょうかね?)、constにもあまり意味がないですね。
説明変数を持たずに、直接appendRowに変数を渡したほうがいいのかもしれないです。
2019/03/14 10:42 編集
付け焼刃のツギハギな知識でしたので、これを機に改めて基礎から学習していこうと思います。
papinianus様、hiroshi0240様、macaron_xxx様、ありがとうございました!