質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

解決済

1回答

4440閲覧

【GAS】Gmail→スプレッドシートへの自動転記。本文内の項目を取得してセルにおさめたい。

kishimon0612

総合スコア3

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

1クリップ

投稿2021/08/24 16:16

前提・実現したいこと

Gmailに届く内容をスプレッドシートに自動転記したいと考え、
スプレッドシートにスクリプトを記入していますが、エラーが表示され思ったように動きません。

なおメールで届く文面は下記のようなものです。

お問い合わせがありました。
────────────────────────────────────
■お名前
◯◯

■お名前(ふりがな)
◯◯

■お問い合わせ内容
◯◯

■郵便番号
◯◯

■住所1
◯◯

■住所2
◯◯

■住所3
◯◯

■住所4
◯◯

■電話番号
◯◯

■メールアドレス
◯◯@◯◯

■太陽光発電設備の有無
◯◯

■自由記載
◯◯

追記
合わせて抽出する内容は
名前、お問合せ内容、郵便番号+住所1~4(同じセルに記入)、電話番号、メールアドレス、太陽光発電設備の有無、自由記載
になります。

発生している問題・エラーメッセージ

(匿名) @ コード.gs:31 (匿名) @ コード.gs:11 myFunction @ コード.gs:6

該当のソースコード

function myFunction() { // 検索条件に該当するスレッド一覧を取得 var threads = GmailApp.search('subject:お問い合わせがありました'); // スレッドを一つずつ取り出す threads.forEach(function(thread) { // スレッド内のメール一覧を取得 var messages = thread.getMessages(); // メールを一つずつ取り出す messages.forEach(function(message) { // メール本文を取得 var plainBody = message.getPlainBody(); // メール本文が取得できているかログに出力して確認 Logger.log(plainBody); // 日時を取得 var date = message.getDate(); // メールアドレスを取得 var email = plainBody.match(/■メールアドレス[\s\S]*//); // お名前を取得 var name = plainBody.match(/■お名前[\s\S]*//); // 書き込むシートを取得 var sheet = SpreadsheetApp.getActive().getSheetByName('お問い合わせ'); // 最終行を取得 var lastRow = sheet.getLastRow() + 1; // セルを取得して値を転記 sheet.getRange(lastRow, 1).setValue(date); sheet.getRange(lastRow, 2).setValue(email[1]); sheet.getRange(lastRow, 3).setValue(name[1]); }); // スレッドに処理済みラベルを付ける var label = GmailApp.getUserLabelByName('処理済み'); thread.addLabel(label); }); }

試したこと

参考となりそうなサイトで上記と異なるGASの記述を試みたり、
正規表現のページをみてあれこれ試しましたが解決せず・・非エンジニアですが、いよいよ頭を抱えてしまいました。
問題解消のアドバイスを頂けたら有難いです。

補足情報(FW/ツールのバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

以下のように matchAll で切り出してみてはいかがでしょうか。

function myFunction() { // 書き込むシートを取得 var sheet = SpreadsheetApp.getActive().getSheetByName('お問い合わせ'); // ラベルを取得 var label = GmailApp.getUserLabelByName('処理済み') || GmailApp.createLabel("処理済み"); // 検索条件に該当するスレッド一覧を取得 var threads = GmailApp.search('subject:お問い合わせがありました'); // スレッドを一つずつ取り出す threads.forEach(function(thread) { // スレッド内のメールのうち先頭を取得 var message = thread.getMessages()[0]; // メール本文を取得 var plainBody = message.getPlainBody(); // メール本文が取得できているかログに出力して確認 Logger.log(plainBody); const item = new Map() for(const t of plainBody.matchAll(/\r\n■(.+)\r\n(.+)\r\n/gm)){ item.set(t[1],t[2]); } // 日時を取得 var date = message.getDate(); // メールアドレスを取得 var email = item.get("メールアドレス"); // お名前を取得 var name = item.get("お名前"); // 最終行を取得 var lastRow = sheet.getLastRow() + 1; // セルを取得して値を転記 sheet.appendRow([date,email,name]) // スレッドに処理済みラベルを付ける  thread.addLabel(label); }); }

投稿2021/08/26 09:52

編集2021/09/09 13:33
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kishimon0612

2021/09/01 03:59

qnoirさん ご回答ありがとうございます。 上記の内容をそのままコピーしてスプレットシートのスクリプトエディタに貼り付けて 実行すると下記内容のエラーが出てしまいます。 (匿名) @ コード.gs:38 (匿名) @ コード.gs:11 myFunction @ コード.gs:6
退会済みユーザー

退会済みユーザー

2021/09/01 04:37 編集

修正したのですがどうでしょうか。 エラーの詳細がわかりませんのでまだ直っていない可能性はあります。 38行目で発生するエラーとして、「お問い合わせ」という名前のシートが存在しない可能性が考えられましたので、その場合の処理(「お問い合わせ」という名前のシートが存在しない場合は終了する)も追加しています。 あと、エラー時は本当にそれだけしか出なかったのでしょうか? (エラーが発生したときに、古いバージョンのGASエディタを使っている場合は、メニューの「表示」→「ログ」でエラーログを表示できますが、その場合も、上記のような(匿名)@コード~~ という表示だけだったのでしょうか?)
kishimon0612

2021/09/01 09:27

qnoirさん 大変お手数をおかけして申し訳ありません。 コードの修正も助かりました。 実行して無事完了しました。 ごめんなさい もう2つだけご質問があります。 1点 シートは「お問い合わせ」という名前で作成しましたがスクリプトを実行すると 「お問い合わせ」という名前のシートが見つからなかったか、アクティブなシートが存在しませんでした。終了します。」となってしまいます。 この場合は何か連携方法などございますでしょうか。 2点 今後件名に「お問い合わせがありました」というワードが入っていれば、 ■お名前 ◯◯ の部分の◯がスプレッドシートに自動的に入力されるという認識で大丈夫でしょうか。 初心者の大変厚かましいお願いですが、 どうかよろしくお願い致します。
kishimon0612

2021/09/01 09:36

先ほど スプレッドシートへ自動で入力がされました。 ありがとうございます。 ごめんなさい また難点が問題がありまして、 メールアドレス・名前 以外の項目は入力されず、 また、メールアドレスや名前も入力されない方もいらっしゃるので これは同のように対応すればよいでしょうか。 初歩的なご質問で本当にごめんなさい
退会済みユーザー

退会済みユーザー

2021/09/01 11:32 編集

諸々、確認させていだだきたいのですが、まずシート名の件(「シートは「お問い合わせ」という名前で作成しましたがスクリプトを実行すると「お問い合わせ」という名前のシートが見つからなかったか、アクティブなシートが存在しませんでした。終了します。」となってしまいます。」というエラー)は解消したのでしょうか?その点が気になっております。
kishimon0612

2021/09/03 01:43

ごめんなさい。 その点については解消できました。 ありがとうございます。
退会済みユーザー

退会済みユーザー

2021/09/04 01:44 編集

承知しました。 >メールアドレス・名前 >以外の項目は入力されず、 >また、メールアドレスや名前も入力されない方もいらっしゃるので >これは同のように対応すればよいでしょうか。 メールアドレスや名前以外の項目も、 item.get("項目名"); という形式でアクセスできます。 たとえば お問い合わせ内容もスプレッドシートに記載したい場合は、 // お名前を取得 var name = item.get("お名前"); の直後に、 var inquiry= item.get("お問い合わせ内容"); を追加し、 sheet.getRange(lastRow, 1,1,3).setValues([[date,email,name]]); の部分を sheet.getRange(lastRow, 1,1,4).setValues([[date,email,name, inquiry]]); というように変えれば追加されます。
kishimon0612

2021/09/07 05:52

qnoirさん 細かなご説明大変助かります。 無事出力することができました。 ごめんなさい 最後に一点お聞きしてもよいでしょうか。 上記の■の項目がないメールは出力しないようしたいのですが、 それは可能でしょうか。 都度都度ご質問して申し訳ございません。 申し訳ございませんが、 どうかよろしくお願い致します。
退会済みユーザー

退会済みユーザー

2021/09/07 12:57 編集

「■の項目がないメールは出力しない」とは、「件名に『お問い合わせがありました』を含むメールのうち、『■』(の項目)を含まないメールは、このスクリプトの対象としない」という理解でよろしいでしょうか。
kishimon0612

2021/09/08 00:55

qnoirさん 説明不足で大変申し訳ございません。 件名が「お問い合わせがありました」というものに返信メールをすると、 その内容までスプレッドシートに出力されるので それは出力されないようにしたいです。 わかりずらく申し訳ございません。
退会済みユーザー

退会済みユーザー

2021/09/09 13:34

回答欄のコードを修正しました。スレッドの先頭のメールだけ抽出することで、返信等は除外するようにしています。 (件名にRe:が含まれるものを除外するやり方もありますが割愛します)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問