Gmailで受信したメールをDiscordに転送する

Gmailの通知に気づかずDiscordはよくみるのでgmailを受信したらDiscordに転送する設定をした。

DiscordのWebhook urlを取得

Discordのチャンネル名の横にある歯車マーク->Integrations->Webhooks->New Webhookから新しいWebhookを作成する。作成したWebhookを選択してWebhook URLをコピーする。名前は使わないがわかりやすい名前にする。

このWebhook URLを使うことで指定したチャンネルにメッセージを送信できる。

Gmailで受信したメールを取得する

Gmailでメールを受信したときに発生するトリガーはないため、定期的にメッセージを確認する必要がある。今回はスプレッドシートに書き出して、すでに新規メッセージか既知のメッセージかを判断する。スプレッドシートを使わず、メッセージを既読にする方法もある。

Gmailで受信したメールをスプレッドシートに書き出す

スプレッドシートを新規に作成する。日付・タイトルだけ記入する。

Extensions->App ScriptからApp Scriptを開いて以下のコードをコピペする。

日付+件名を一位のキーとする。sendEmailToDiscordは後述する。

function saveGmailToSheet() {
  // スプレッドシートを取得
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

  // 既にスプレッドシートにある件名と日付を取得
  var lastRow = sheet.getLastRow();

  var existingData = sheet.getRange(1, 1, lastRow, 2).getValues(); // 日付と件名の2列を取得
  var existingEntries = existingData.map(function(row) {
    var formattedDate = Utilities.formatDate(new Date(row[0]), Session.getScriptTimeZone(), 'yyyy-MM-dd HH:mm:ss');
    return formattedDate + row[1]; // 日付と件名を結合して1つの文字列にする
  });

  // Gmailから最新のスレッドを取得 (受信トレイの最初の10スレッド)
  var threads = GmailApp.getInboxThreads(0, 10);
  
  var newEntries = []; // 新しいメールを記録するためのリスト

  for (var i = 0; i < threads.length; i++) {
    var message = threads[i].getMessages()[0];
    var date = message.getDate();
    var subject = message.getSubject();

    // 日付と件名を結合して比較するための文字列
    var dateString = Utilities.formatDate(date, Session.getScriptTimeZone(), 'yyyy-MM-dd HH:mm:ss');
    var uniqueEntry = dateString + subject;

    // 日付と件名が既にスプレッドシートにあるか確認
    if (!existingEntries.includes(uniqueEntry)) {
      newEntries.push([date, subject]); // 新しいメールをリストに追加
      // discordに送信する
      sendEmailToDiscord(message);
    }
  }

  // 新しいデータがあればスプレッドシートに追記
  if (newEntries.length > 0) {
    sheet.getRange(lastRow + 1, 1, newEntries.length, 2).setValues(newEntries);
  } else {
    Logger.log("新しいメールはありません。");
  }
}

Discordに転送する

Gmailで新規のメッセージを受信したらその内容をDiscordに転送する。

以下のコードをApp Scriptにコピペする。Webhook URLのチャンネルにメッセージを送る。

function sendEmailToDiscord(message) {
  var discordWebhookUrl = "https://discord.com/api/webhooks/YOUR_WEBHOOK_URL"; // Webhook URLをここに貼り付ける
  var subject = message.getSubject(); // メールの件名
  var from = message.getFrom(); // 送信者
  var body = message.getPlainBody(); // メール本文

  const user_id = 'user_id'; // メンションするために必要
  const mention = `<@${user_id}>`;
  var payload = JSON.stringify({
    "content": mention + "\n新しいメールが届きました\n**件名**: " + subject + "\n**送信者**: " + from + "\n**内容**: " + body
  });

  var options = {
    "method": "post",
    "contentType": "application/json",
    "payload": payload
  };

  UrlFetchApp.fetch(discordWebhookUrl, options);
}

Discordのuser idを取得する

ユーザーをメンションしたいときはuser idを取得する必要がある。特にメンションが必要なければコードのmention部分を削除する。

Discordの左下の歯車マーク->左メニューのAdvancedからDeveloper Modeをオンにする。

Developer Modeをオンの状態でユーザーのアイコンを右クリックするとCopy User IDが表示される。おそらく18桁の数字。

GASを定期実行する

saveGmailToSheet関数を実行すれば新規のメールをDiscordに転送してくれる。この関数を定期的に実行する。1分か5分おきに実行するのがおすすめ。

App Scriptの左メニューからTriggersを選択する。右下のAdd Triggerでトリガーを追加する。

実行する関数を選択する。ここではsaveGmailToSheetを選択する。

Select event sourceをTime-drivenにする。Minutes timer, Every 5 minutesを選択する。

Failure notification settingsはNotify me immediatelyを選択する。

これで定期的に関数が実行される。

動作確認

実際にメールを送ってみると5分以内にDiscordにメッセージが飛んでくる。最初は1分おきにトリガーを実行しても良いかもしれない。

終わりに

ChatGPTにやり方を聞きながら進めたら簡単にできた。GASすごい!

返信も取得したい場合は以下のように書くとできる。

var messages = threads[i].getMessages();
// スレッド内のメッセージを逆順でチェック(最新のメッセージから確認)
for (var j = messages.length - 1; j >= 0; j--) {
}

自分が返信で送ったメールを飛ばすように以下のように判定する。

var myEmail = Session.getActiveUser().getEmail();
if (sender !== myEmail) {
}

コメント

タイトルとURLをコピーしました