2015/09/13

楽天メールdeポイントのURLを抽出しスプレッドシートに自動で出力する方法

学生のころは、時間はたっぷりあるけどお金がないということで、楽天(インフォシーク)の「メールdeポイント」のURLをクリックして小銭を稼いでいた。
しかし、社会人になって「労力 >>>>>> 対価」だと気づき、ずいぶんと放置していた。

Infoseek メールdeポイント とは
1通ごとに必ずポイント&ポイナビ補助券がついてくるお得なメールサービスです。
【楽天PointClub】Infoseek メールdeポイントでポイントが貯まる


でも、ある程度自動化できたら便利じゃない?


ということで、Gmailに届いた「メールdeポイント」から対象URLを抽出し、Googleスプレッドシートに自動で出力するスクリプトをつくってみた。




注意事項


利用規約の禁止事項について

第7条 1.(2)自動化プログラム等を用いて、ポイントまたは景品等を取得すること

【メールdeポイント】規約 - Infoseek ポイナビ

メールdeポイントの利用規約に上記がある。
対象URL抽出だけならギリギリ違反しないという勝手な判断でスクリプトをつくっている。
(自動でURLにアクセスするのも簡単だけど、それは完全にアウト!)

そのため、当記事のスクリプトを使って、いかなるトラブルや損害などが生じても一切責任を負いません。自己責任でお願いします。



メールの仕分け


Gmailのフィルタ機能を使って、「メールdeポイント」のメールに分かりやすいラベルをつける。
私の場合は、pm-info@mail.rakuten.comから受信したモノに『2楽天Point』というラベルをつけている。



Googleスプレッドシートをつくる


Googleスプレッドシートから、新規スプレッドシートを作成する。


スプレッドシートの[ツール]→[スクリプトエディタ]をクリック。

[空のプロジェクト]を作成する。



Google App Script をかく


function getGmail() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var start = 0;
  var max = 500;
  var threads = GmailApp.search('label:2楽天Point newer_than:1d', start, max);
  var row = sheet.getLastRow() + 1;
  
  for (var n in threads) {
    var the = threads[n];
    var msgs = the.getMessages();
    for (var m in msgs) {
      var msg = msgs[m];
      var body = msg.getBody()
          .match(/http(s)?:\/\/pmrd\.rakuten\.co\.jp\/[\w?=%&;]+/)[0]
          .replace(/amp;/g, '');
      sheet.getRange(row, 1).setValue(body);
      the.markRead();
      row++;
    }
    Utilities.sleep(500);
  }
}

5行目:Gmailでつけたラベル名を指定。newer_than:1d は今日受信したメールに限定する。
Google App Scriptは起動から6分ほど経つと「起動時間の最大値を超えました」というエラーがでてしまう。回避する方法もあるにはあるが、複雑になるのでこまめに受信したほうが良い。


13~15行目:メールの中から対象URLを正規表現で取得。

対象URLはhttp://pmrd.rakuten.co.jp/から始まる。
後ろの [\w?=%&;]+ はURLのクエリをヒットさせるためのもの。
「a-z, A-Z, 0-9, _, ?, =, %, &, ;」が1回以上繰り返されているという意味。

クエリ部分が & となってしまうため、replaceで無効化している。



自動実行させるための設定


今回の場合は、毎日1回だけ実行させたい。
「現在のプロジェクトのトリガー」を使って、スクリプトが実行されるタイミングを設定する。
ということで、「時間主導型」で「午前0時~1時」に実行するように設定した。



Gmailとスプレッドシートを使うため、アプリの認証が必要になるので許可する。



実行してみる


こんな感じにスプレッドシートに対象URLがズラーっと表示される。
あとはひとつずつクリックしていけばOK!(たぶん)



参考サイト


Google App Scriptのほとんどを参考にさせていただきました。


以上

written by @bc_rikko

6 件のコメント :

  1. 突然の質問すいません。
    以下の箇所がわからないのですが、
    どういった意味なのでしょうか?
    for( var i in threads ) {
    var thread = threads[i];
    var msgs = thread.getMessages();
    for(var i in threads)は繰返しのforなのでしょうか?
    お願いいたします

    返信削除
    返信
    1. コメントありがとうございます!

      ご質問の箇所について、詳しく説明しますね。

      まず、JavaScriptはご存知でしょうか?
      Google App ScriptはJavaScriptそのものです。
      ですのでご質問の「for (var n in threads)」もJavaScriptとおなじ挙動になります。

      それを踏まえた上で、さらに詳しく説明すると…

      5行目で変数threadsにGmailから取得したメールの配列が格納されます。

      次に8行目で、その配列threadsを1つずつ処理していきます。
      JavaScriptのfor...inは、C#のforeachなどと違い、変数nにはオブジェクトそのものではなく。オブジェクトを参照するためのキーが次々と代入されていきます。
      そのため、9行目でそのキーnを用いて、threadsからオブジェクトを取得しています。


      もしかすると次のような書き方の方がわかりやすいかもしれませんね。

      ```
      var threads = // 省略

      for (var i = 0, i < threads.length; i++) {
      var the = threads[i];
      // 以下略
      }
      ```

      いかがでしょうか?
      まだわからないことがありましたら、またコメントいただけると幸いです。


      // 補足
      GmailApp.searchはGmailThread[]を返すので、本来for...inで走査するのは間違いかもです。
      本来なら上で説明した普通のforループを使う方が良いと思います。(理由は省略)

      イマドキ(ES6)の書き方でしたら、以下のようになると思います。
      ```
      threads.forEach((thread) => {
      const msgs = thread.getMessages();
      msgs.forEach((msg) => {
      // 以下略
      }
      });
      ```

      削除
    2. B.C.Rikko様

      ご回答ありがとうございます。
      GASはJavaScriptと一緒なのですね!
      丁寧な解説ありがとうございます、
      javascriptの基礎から学んでいこうと思います。
      初歩的な質問に付き合っていただきありがとうございます。

      削除
    3. お役に立てたようでなによりです!

      このブログでも、JavaScriptについての記事がいくつかありますので、もしよろしければ勉強の参考にしていただければと思います。(GitHubにもいくつか公開しています)
      https://kuroeveryday.blogspot.jp/p/javascript.html
      https://github.com/BcRikko?tab=repositories

      またわからないことがありましたら、ブログ右側の問い合わせフォームやTwitterなどでから直接質問していただければと思います。

      削除
  2. 上記内容でスクリプトを実行すると本文に最初にヒットするURLは抽出されますが
    複数の検索したいURLがある場合はどのようにスクリプトを書けばよいか教えていただけますか。

    返信削除
  3. URLが中途半端に抽出されます。なぜでしょうか?ご教授頂けないでしょうか?

    引っ張り出したいURL

    https://point-g.rakuten.co.jp/campaign/pickup/ichiba_special_rpp_c_second/

    抽出されるURL

    http://point-g.rakuten.co.jp/mailmag です。

    コードは下記です。
    function getGmail() {
    var sheet = SpreadsheetApp.getActiveSheet();
    var start = 0;
    var max = 500;
    var threads = GmailApp.search('label:2楽天Point newer_than:1d', start, max);
    var row = sheet.getLastRow() + 1;

    for (var n in threads) {
    var the = threads[n];
    var msgs = the.getMessages();
    for (var m in msgs) {
    var msg = msgs[m];
    var body = msg.getBody()
    .match(/http(s)?:\/\/point-g\.rakuten\.co\.jp\/[\w?=%&;]+/)[0]
    .replace(/amp;/g, '');
    sheet.getRange(row, 1).setValue(body);
    the.markRead();
    row++;
    }
    Utilities.sleep(500);
    }
    }

    返信削除