使用ntfy接收gmail邮件通知。

由于gmail在中国被防火墙拦截了,无法打开,不想错过邮件通知。

通过自建ntfy接受gmail邮件通知。
怎么自建ntfy,后面再写。


2024年08月13日更新:

修改不通过添加邮件标签来标记已经发送的通知,通过Google Sheets来记录已经发送的通知。

为了不让Google Sheets文档的内容很多,导致文件变大,用脚本自动清理一个星期以前的数据。


准备工具

  • Ntfy服务
  • Google Script
  • Google Sheets

操作步骤

  1. 在Ntfy后台账号,设置访问令牌。
    访问令牌
  2. 添加订阅主题。
    订阅主题
  3. 进入Google Sheets创建一个表格.记住id,如下图:
    Google Sheets id
  4. 进入Google Script创建项目。填入以下代码(注意填入之前的ntfy地址和令牌):
function checkEmail() {
  var sheetId = "你的Google Sheets id";  // 替换为你的 Google Sheets ID
  var sheet = SpreadsheetApp.openById(sheetId).getActiveSheet();

  // 清理一星期以前的数据
  cleanOldData(sheet, 7 * 24 * 60);  // 保留7天(即一周)内的数据

  var sentEmails = getSentEmails(sheet);

  var threads = GmailApp.search('is:unread');
  Logger.log("Found threads: " + threads.length);

  if (threads.length === 0) return;

  threads.forEach(function(thread) {
    var threadId = thread.getId();

    if (!sentEmails.includes(threadId)) {
      thread.getMessages().forEach(sendNtfyNotification);
      recordSentEmail(sheet, threadId);
    }
  });
}

function sendNtfyNotification(email) {
  if (!email) {
    Logger.log("Email object is undefined or null.");
    return;
  }

  var message = `发件人: ${email.getFrom() || "未知发件人"}
主题: ${email.getSubject() || "无主题"}

内容: ${email.getPlainBody() || "无内容"}`;

  var url = "https://你的ntfy地址/Gmail";
  var options = {
    method: "post",
    payload: message,
    headers: {
      Authorization: "Bearer Ntfy的令牌"
    },
    muteHttpExceptions: true
  };

  try {
    var response = UrlFetchApp.fetch(url, options);
    Logger.log("Response: " + response.getContentText());
  } catch (e) {
    Logger.log("Error: " + e.message);
  }
}

function getSentEmails(sheet) {
  var data = sheet.getDataRange().getValues();
  return data.map(row => row[0]);  // Assuming email IDs are stored in the first column
}

function recordSentEmail(sheet, threadId) {
  sheet.appendRow([threadId, new Date()]);
}

function cleanOldData(sheet, minutes) {
  var now = new Date();
  var thresholdDate = new Date(now.getTime() - minutes * 60 * 1000); // 获取X分钟前的时间

  var data = sheet.getDataRange().getValues();
  var rowsToDelete = [];

  data.forEach(function(row, index) {
    var date = new Date(row[1]);  // 假设日期保存在第二列
    if (date < thresholdDate) {
      rowsToDelete.push(index + 1);  // 存储要删除的行号
    }
  });

  // 逆序删除(从最后一行开始删除,以避免行号改变)
  rowsToDelete.reverse().forEach(function(row) {
    sheet.deleteRow(row);
  });
}

4.Goole Script需要添加gmail服务,如图:
gmail服务

5.Google Script是有限制的不能频繁调用,可以设置五分钟调用一次。如图:
触发器

触发器设置详细

结尾

本人不会代码,以上代码都是通过chatgpt生成的。经过多次修改,刚开始会一直发送通知,后面修改后将已发送的通知放到一个“通知”的标签里。后续不会再次发送通知。

如需要发送通知后自动标记已读,可以把代码复制到chatgpt给你写。

效果预览:
效果预览