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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Gmail

GmailとはGoogleによって提供されているウェブメールのサービスのことです。

Google Apps Script

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

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

Q&A

解決済

3回答

2153閲覧

GASを用いてメール内容の転記をしたいが、正規表現エラーで躓いている

aunyan831

総合スコア1

Gmail

GmailとはGoogleによって提供されているウェブメールのサービスのことです。

Google Apps Script

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

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

0グッド

1クリップ

投稿2021/06/06 13:46

前提・実現したいこと

Google Apps Scriptを用いて受信ボックス内にある「事前課題」というラベルがついているメールの内容を指定のスプレッドシートに転記することを自動化したいと考えています。
取得したい内容:氏名・メールアドレス・電話番号
またメッセージIDも取得し、転記処理に重複なく処理できるようにしたいと考えており、以下を参考にしてみました。

参考URL
また可能であればお尋ねしたいのですが、スプレッドシート上に事前課題というシートがあります。
これを指定・定義するにはどう記述したら良いのでしょうか。

お力添えをいただけますと幸いです。よろしくお願いいたします。

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

エラー TypeError: Cannot read property '0' of null getMail @ コード.gs:36

該当のソースコード

//シートを取得する。 var sheet = SpreadsheetApp.getActiveSheet(); function getMail() { // メール検索する文字列:今回はラベルにある事前課題 var str = "label:事前課題"; // 上記の文字列に合致するスレッドを取得(とりあえず100件取得します) var threads = GmailApp.search(str,0,100); // メッセージを取得する var messages = GmailApp.getMessagesForThreads(threads); for(var i = 0; i < messages.length; i++){ for(var j = 0; j < messages[i].length; j++){ //メッセージIDを取得(重複を防ぐため) var messageId = messages[i][j].getId(); //もし、スプレッドシートに存在したら実行しない if(!hasId(messageId)){ //メール受信日時を取得 var mailDate = messages[i][j].getDate(); // メッセージの本文をプレーンテキストで取得 var body = messages[i][j].getPlainBody(); //正規表現をつくる var regName = new RegExp('氏名 :' + '.*?' + '\r' ); var regMail = new RegExp('メールアドレス :' + '.*?' + '\r' ); var regTel = new RegExp('電話番号 :' + '.*?' + '\r' ); //正規表現をマッチさせたうえで、転記するときに、 //セルに"お名前:"などが入らないように、正規部分を削る var Name = body.match(regName)[0].replace("氏名:",""); var Mail = body.match(regMail)[0].replace("メールアドレス :",""); var Tel = body.match(regTel)[0].replace("電話番号 :",""); //セルに行を追加する(ID、日時、氏名、アドレス、電話番号) sheet.appendRow([messageID,mailDate,Name,Mail,Tel,]); } } } } // 同じIDのメールは転記しないようにするため、すでにIDがあるかどうか調べる関数 function hasId(id){ //今回は1列目にメールIDを入れていくので1列目から探す var data = sheet.getRange(1, 1,sheet.getLastRow(),1).getValues(); var hasId = data.some(function(value,index,data){ //コールバック関数 return (value[0] === id); }); return hasId; }

試したこと

正規表現についても調べてみましたが、始めたてでまだつかめていないことも多いです。
どこから手を付けたらよいか、今見当もついていない状況です。

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

Gmail,Google Spreadsheetでテストしています。

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

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

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

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

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

guest

回答3

0

単に正規表現にヒットしていないからではないでしょうか?

エラーメッセージにある行番号はこちらですが

js

1var Name = body.match(regName)[0].replace("氏名:","");

判定の根拠になっているのは、ここですよね。

js

1//正規表現をつくる 2var regName = new RegExp('氏名 :' + '.*?' + '\r' ); 3

本来なら真っ先に考えるべきは、bodyにどんな文字列が入っているのか。
ですが、そもそも\rはどんな意図で入れていますか?
多分これのせいで引っかからないんじゃないかなーとは思いますが。

純粋にJavaScriptの範疇なのでサンプルにGASを使っていませんが書いてみました。
動作サンプル - https://jsfiddle.net/mahny/6co1bthf/

js

1var regName = new RegExp('氏名 :.*?'); 2 3var ret = '氏名 : ほげふが'.match(regName); 4console.log(ret); // ["氏名 :", index: 0, input: "氏名 : ほげふが", groups: undefined] と出力

投稿2021/06/06 14:03

neonemo

総合スコア191

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

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

aunyan831

2021/06/10 05:43

Javascriptでの解法は今まで考えたこともなかったので、勉強になりました。 本当にありがとうございました!
guest

0

ベストアンサー

正規表現でエラーが出ないように書いてみました。

var name = /氏名[ | ]*:(.*?)\r\n/.test(body)? RegExp.$1 : ''; var mail = /メールアドレス[ | ]*:(.*?)\r\n/.test(body)? RegExp.$1 : ''; var tel = /電話番号[ | ]*:(.*?)\r\n/.test(body)? "'"+RegExp.$1 : '';

testにすることで、trueのときだけRegeExp.$1 (=正規表現内の()の中に一致した文字列)を代入します。

( )? a: b は、条件演算子です。

telの「"'"+RegExp.$1」の先頭の「'」は、090151…などの数字で先頭の「0」が消えるのを防いでいます。

ご参考になりましたら幸いです。

投稿2021/06/06 16:02

gas.engine

総合スコア608

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

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

aunyan831

2021/06/10 05:41

ありがとうございます!  試したところ、問題が解決できました。 大変助かりました。
guest

0

正規表現にエラーがあるわけではなく、body.match(regName)で、bodyregNameに一致する部分が無くnullが返されていると考えられます。nullに対して[0]で値を取り出そうとしたのでエラーとなるわけです。
なので

GAS

1var Name = body.match(regName); 2if (Name !== null) { 3 Name = Name[0].replace("氏名:",""); 4} 5else { 6 // エラー処理 7}

のようなエラー処理が必要です。

投稿2021/06/06 14:08

itagagaki

総合スコア8402

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

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

aunyan831

2021/06/10 05:42

ありがとうございます! itagaki様の記述も試したところ、うまく期待通りの動きをしてくれました。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問