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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Q&A

解決済

2回答

3298閲覧

GASを使い、過去1時間以内に送られてきたgメールをだけを取得するプログラムを、1時間ごとに実行したいです。

takoyaki87

総合スコア19

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

0グッド

0クリップ

投稿2020/03/04 00:48

前提・実現したいこと

ここに質問の内容を詳しく書いてください。

ネットフリマで売れた商品の売上管理表を、スプレッドシートで作っております。商品が売れるたび購入通知をgmailで取得し、メールに記載されている商品情報 (商品名・購入された日時など)がシート上に自動追記されるプログラムをGASで作っておりま
商品情報が重複で取得されないよう、トリガーで1時間ごとにプログラムを実行し、毎度1時間前以内に送られてきた購入通知のメールだけを取得したいです。

当方プログラミングに関しては素人です。
独学で調べ、「件名の定型文章」 「送信元のアドレス」 を検索条件にして購入通知メールを取得し、その商品情報をシートに書き出すところまでプログラムが書きあがりました。

あとは先述の方法で日時指定ができればプログラムが完成します。
日時指定の検索コードをどのように書けばいいか、試行錯誤してもわからずにいます。

ご教示いただけると幸いです。
ぜひ、よろしくお願いいたします。

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

商品の購入通知のメールを取得後、商品情報がシート上に重複で書き出されてしまっています。 以前までメールのメッセージIDとsomeメソッドを使って重複を避けられないか試しておりましたが、なかなかうまくいかず時間だけが経っていたので、他の方法がないか考えました。 その結果、「GASトリガーで1時間ごとにプログラムを実行し、毎度1時間前以内に送られてきた購入通知のメールだけを取得すれば重複を避けられるのでは」という判断に至りました。 ですが、そのためのコードの書き方がわからないままです。

該当のソースコード

function autoRefresh() { var condition = ("subject:発送をお願いします from:no-reply@mercari.jp"); var thread = GmailApp.search(condition, 0, 5); var messages = GmailApp.getMessagesForThreads(thread); for(var i=0; i<messages.length; i++){ var id =messages[i][0].getId(); var date = messages[i][0].getDate(); var sheet = SpreadsheetApp.getActiveSheet(); var lastRow = sheet.getLastRow(); var plainBody = messages[i][0].getPlainBody(); var name =plainBody.match(/商品名.*/); var price =plainBody.match(/商品価格.*/); var site =plainBody.match(/メルカリをご利用.*/); sheet.getRange(lastRow+1,1).setValue(id); sheet.getRange(lastRow+1,3).setValue(name[0].replace('商品名 : ', '')); sheet.getRange(lastRow+1,5).setValue(site[0].replace('をご利用いただきありがとうございます。', '')); sheet.getRange(lastRow+1,7).setValue(date); sheet.getRange(lastRow+1,8).setValue(price[0].replace(/[^0-9]/g, '')); sheet.getRange(lastRow+1,9).setValue(0); } }

試したこと

getDateメソッドを使ってメールが送られてきた日時を取得し、それを検索条件にして新規の商品情報だけをシートに書き出せないか試しておりました。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

takoyaki87

2020/03/04 10:30

ご回答ありがとうございます。 こちらのページを昨日から参考にしておりましたが、うまくできずにおりました、、。 ですがもう少し頑張ってみようと思います。 お忙しいところ教えてくださり、ありがとうございますm(_ _)m
guest

回答2

0

参考にさせていただきます、ということですがあまり参考にはして貰えてないみたいですね・・・
問題の切り分けはされましたか?
デバッグ実行はされましたか?
作ってみて動かなかったから現象だけ伝えて丸投げではちょっとこれ以上お手伝いは難しいです。

ちなみにプログラムを拝見してわかりましたが、一個前の質問で動かなかったのは
メールアドレスの後ろに半角スペースがないからでしたね。
前回の私の回答の原因一例でも上げていた部分です。

ともあれ、解決済みのこのスレッドでの質問回答よりは、新しいスレッドを立てて
他のユーザーにも広く意見を伺ってみてはいかがでしょうか。

追記:
(間違えて回答の方に書き込んじゃいました)

投稿2020/03/11 10:04

編集2020/03/11 10:24
mkk

総合スコア378

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

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

takoyaki87

2020/03/11 12:08

お世話になっております。 こちらの認識が足りていなかったようで、大変失礼いたしました。 もう少し自分で取り組んでみます。お忙しいなかご協力くださり、ありがとうございましたm(_ _)m
guest

0

ベストアンサー

GmailApp.search のところで、送信元アドレスの指定以外に、受信日時を指定してみてはいかがでしょうか。

参考サイト
https://qiita.com/akatsuki174/items/d7471760754829ced7df
https://qiita.com/3mc/items/39b2c8241c6b52811ad2

また、今の仕様では1時間毎に更新にしていますが、「今リストを更新したい」というニーズも出てきそうですよね。
それであれば例えば前回の更新日時をスプレッドシートのどこかに残しておくようにして
次回更新する際には 前回の更新日時 ~ 現在日時 を指定して取得するとスムーズかもしれません。


蛇足ですが、最後にプログラム初心者とのことですのでGAS以外の解決方法もご紹介です。
※プログラムの勉強のため、GASで解決したいということでしたらすいません。

参考サイト
https://rpa.ne.jp/post-88/

ZapierやIFTTTといった、プログラムなしでソフトとソフトを自動連携してくれるツールもあります。
これを使って、gmailに特定のメールが来たときにスプレッドシートに転記させるのも良いかもしれません。

投稿2020/03/05 03:18

mkk

総合スコア378

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

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

takoyaki87

2020/03/05 08:08

コメントありがとうございます。 GAS以外の解決方法も教えてくださり恐縮です。 当方としましては、業務が効率化すればそのための手段にはこだわらないので、GAS以外のものも試せるなら是非試してみたいと思います。 教えていただいた情報を踏まえ、もう少しやってみようと思います。すみませんがまた不明な点が出てきましたらご質問させていただくかもしれません。 お忙しい中わざわざご教授いただき、ありがとうございますm(_ _)m
takoyaki87

2020/03/05 13:06

お世話になっております。 教えていただきましたように、GmailApp.searchに日時指定のコードを添えましたが、スクリプトでエラーメッセージは出ないもののシート上では何も更新されていないようです。 以前からこうしたことが起きており行き詰まっているのですが、何が原因かご存知でしたらお伺いしてもよろしいでしょうか? たびたび申し訳ございませんが、よろしくお願いできれば幸いです。
mkk

2020/03/06 01:22

プログラムが正常に動かない理由というのは実行環境を含め様々あるため、 今いただいている情報だけではちょっと判断しかねる部分です。 うまくできないとのことでしたので、こちらでもサンプルプログラムを書いて確認しました。 takoyaki87 さんのプログラムと、ご案内した参考URLのプログラムの複合です。 私の環境でテストしたため、メルカリ関係の絞込や記載は削除していますのでご了承下さい。 まずはこれが動くか試してみて下さい。 ※対象となるアドレス部分は変更してご利用下さい。 function autoRefresh() { //受信日時指定 const date = new Date() ;//現在時刻を取得 const unixTime = date.getTime();//UNIX TIMEに変換 const now = Math.floor(unixTime/1000); //ミリ秒を秒に変換 const term = now - 3600; //現在時刻から1時間(3600秒)前 const termStr = term.toString(); //検索期間を文字列に変換 const strTerms = 'after:'+ termStr; //検索条件:termの期間条件に合致するメール var condition = ("from:sample@gmail.com " + strTerms ); var thread = GmailApp.search(condition, 0, 5); var messages = GmailApp.getMessagesForThreads(thread); for(var i=0; i<messages.length; i++){ var id =messages[i][0].getId(); var mailDate = messages[i][0].getDate(); var sheet = SpreadsheetApp.getActiveSheet(); var lastRow = sheet.getLastRow(); var plainBody = messages[i][0].getPlainBody(); sheet.getRange(lastRow+1,1).setValue(id); sheet.getRange(lastRow+1,2).setValue(mailDate); sheet.getRange(lastRow+1,3).setValue(plainBody); } }
takoyaki87

2020/03/09 13:10

ご連絡ありがとうございます。 返信が遅くなってしまい、大変申し訳ございません。 お忙しい中わざわざご協力くださり恐縮です。 送っていただいたコードで、アドレスの部分だけ変更して実行してみました。結果は、エラーメッセージは出ないもののシート上はやはり何も更新されておらず、白紙のままです。 対策を当方でも調べておりますがまだ見つかっておりません。 よろしければ、mkk様のアドバイスを頂けると幸いです。何度もお手数をおかけし申し訳ございませんが、よろしくお願いいたしますm(_ _)m
takoyaki87

2020/03/09 13:38

なお、ネットで調べた対策として、スクリプトページから「ウェブアプリケーションとして導入」→「新規のプロジェクトバージョンで更新」の操作をしましたが、やはり動かないままです。 お時間ある時で結構ですので、ご連絡お待ちしておりますm(_ _)m
mkk

2020/03/10 01:16

長文で失礼します。 うまく動かない場合、問題の切り分けをする必要があります。 うまく更新がされない原因を考えたときに例えば ①プログラムは正常に動いているが、検索条件に引っかかるメールがない ②プログラムのどこかに誤記がある ③環境の問題(スプレッドシートやGAS等の設定) みたいなことが考えられます。(他にも色々あるかもしれませんが) takoyaki87 さんでも既にいくつかされているかもしれませんが、 まずはどこに原因があるか調べるために、下記の部分の確認をして結果を教えて下さい。 ・前回提示したプログラムの日時指定の絞込を外してみて、正常に動くか  →正常に動けば絞込の記載方法に問題があるか、時間の範囲指定が適正でない   例えばメールアドレスの後ろに半角スペースが必要だが、消してしまっているなど ・デバッグ実行してみて、データ取得失敗なのか、シート書込の失敗なのかを確認  →GASの行番号の左側をクリックすると赤い●が付きます   その状態で、デバッグボタン(実行(▶)ボタンの右にある虫みたいなボタン)を押して実行   そうするとプログラムを赤い●を付けたところで止めることができるため   提示したプログラムのforのところで止めてみて、messagesの中身を確認 ・ログインしているgmailアカウントのチェック  →例えばgmailに複数のアドレスでログインしていて、違うgmailを見に行っている可能性を確認   GASの入力画面の右上の部分にログイン中のアドレスがでていますが、正常でしょうか? プログラムにまだ慣れられていないということで、詰まった時にどうすればいいか分からないかと思います。 その時にはまず上記のように原因の切り分けをして、結果を載せて質問してみて下さい。 回答者側も色んな原因を想定をして総当たりの答えを出す必要がなくなるため、回答を得やすくなります。
takoyaki87

2020/03/10 11:26

お世話になっております。 問題の切り分けの旨、ぜひ参考にさせていただきます。ありがとうございます。 試しにメールアドレス横の日時指定「+ strTerms」を 「, strTerms」にして実行してみましたところ、プログラムが作動しました! ようやく一歩進みました、ありがとうございます! 頂いたコードで、さっそく売上票のスクリプトに書き足す作業に進みました。 毎度1時間おきに、過去1時間以内に新しく購入された商品データをシートに自動入力するようにしております。 シート一番下にそのつど新しい行が追加され、データがその行に表示されていくイメージで行なっています。 すみませんが、ここで一つお伺いしたいことがございます。 過去1時間以内に購入がまったくない状態で、書き足し済みのスクリプトを試しに実行してみました。するとシート一番下に新しい空白の行のみが追加されました。 過去1時間内の購入メールがゼロなので、本来でしたら何も更新されないはずと認識していたのですが、なぜこうした事が起きるのかわからず原因を調べております。 これに関して、よろしければご教示いただけると幸いです。 _______________________________ 以下、現時点のコードです。 function autoRefresh() { //受信日時指定 const date = new Date() ;//現在時刻を取得 const unixTime = date.getTime();//UNIX TIMEに変換 const now = Math.floor(unixTime/1000); //ミリ秒を秒に変換 const term = now - 3600; //現在時刻から1時間(3600秒)前 const termStr = term.toString(); //検索期間を文字列に変換 const strTerms = 'after:'+ termStr; //検索条件:termの期間条件に合致するメール const condition = ("subject:発送をお願いします from:no-reply@mercari.jp",strTerms); //半角スペースで連結 const thread = GmailApp.search(condition, 0, 5); //条件にマッチしたスレッドを取得 const messages = GmailApp.getMessagesForThreads(thread); //スレッドからメールを取得する for(var i=0; i<messages.length; i++){ var nichiji = messages[i][0].getDate(); var sheet = SpreadsheetApp.getActiveSheet(); var lastRow = sheet.getLastRow(); var plainBody = messages[i][0].getPlainBody(); var name =plainBody.match(/商品名.*/); var price =plainBody.match(/商品価格.*/); var site =plainBody.match(/メルカリをご利用.*/); sheet.getRange(lastRow+1,2).setValue("=ROW()-75"); sheet.getRange(lastRow+1,3).setValue(name[0].replace('商品名 : ', '')); sheet.getRange(lastRow+1,5).setValue(site[0].replace('をご利用いただきありがとうございます。', '')); sheet.getRange(lastRow+1,7).setValue(nichiji); sheet.getRange(lastRow+1,8).setValue(price[0].replace(/[^0-9]/g, '')); sheet.getRange(lastRow+1,9).setValue(0); sheet.getRange(lastRow+1,2,1,15).setBorder(true, true, true, true, true, true); } } ___________________________ ※念のため日時指定のコードを取り除いて実行してみましたところ、過去5件分の商品データが正常に自動入力されました。日時指定があるとなぜか空白の1行が追加されてしまいます。 ご連絡お待ちしておりますm(_ _)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問