高效获取信息之RSS邮件补充
RSS mail supplement for efficient information acquisition.
来自:Pixiv 画师(MORNCOLOUR)
前言
在上一篇高效获取信息文章中,介绍了烧制RSS和邮件转化RSS。之前的思路是【自动化服务→Google sheets→GS→构造rss格式】,这里再来补充一个订阅邮件的方式,相比之前的会简单点,易用性更高。
需要用到的服务
- CloudFlare Workers(其他云函数服务亦可)
- testmail.app(自动化邮件测试服务)
操作流程
(1)创建testmail服务
注册登录testmail.app,并创建一个命名空间(免费方案只能建一个)。获得一个测试邮件,格式为 {NameSpace}.{Tag}@inbox.testmail.app 。
(2)创建云函数
怎么创建自行Google,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
const allowedTags = ["TAG"]; const testmailNamespace = "NAMESPACE"; const testmailToken = "TOKEN"; const deployUrl = "LINKS"; class TestMail { static testmailApi = "https://api.testmail.app/api/graphql"; static async getMails(tag) { const query = `{ inbox ( namespace: "${testmailNamespace}" tag: "${tag}" limit: 99 ) { emails { id subject html from timestamp downloadUrl attachments { cid downloadUrl } } } }`; const init = { method: "POST", headers: { "content-type": "application/json;charset=UTF-8", Authorization: `Bearer ${testmailToken}`, Accept: "application/json", }, body: JSON.stringify({ operationName: null, query, variables: {}, }), }; return fetch(this.testmailApi, init); } } addEventListener("fetch", (event) => { event.respondWith(handleRequest(event)); }); /** * Respond to the request * @param {Event} event */ async function handleRequest(event) { const { request } = event; let url = new URL(request.url); // parse tag const requestTag = url.pathname.substring(1); if (!allowedTags.includes(requestTag)) { return new Response("Unknown tag.", { status: 403 }); } let mailResponse = await TestMail.getMails(requestTag); if (mailResponse.status != 200) { return new Response("Internal Server Error.", { status: 500 }); } let data = await gatherResponse(mailResponse); let responseXML = await makeRss(data.data.inbox.emails, requestTag); response = new Response(responseXML, { status: 200, headers: { "content-type": "application/xml; charset=utf-8", }, }); response.headers.append("Cache-Control", "max-age=600"); return response; } /** * gatherResponse awaits and returns a response body as a string. * Use await gatherResponse(..) in an async function to get the response body * @param {Response} response */ async function gatherResponse(response) { const { headers } = response; const contentType = headers.get("content-type"); if (contentType.includes("application/json")) { return await response.json(); } else if (contentType.includes("application/text")) { return await response.text(); } else if (contentType.includes("text/html")) { return await response.text(); } else { return await response.text(); } } async function makeRss(emails, tag) { let items = emails.map((value) => { if (value.attachments.length > 0) { for (let i of value.attachments) { // update the image link value.html = value.html.replace(`cid:${i.cid}`, i.downloadUrl); } } return `<item> <title><![CDATA[${value.subject}]]></title> <description><![CDATA[${value.html}]]></description> <pubDate>${new Date(value.timestamp).toGMTString()}</pubDate> <guid isPermaLink="false">${value.id}</guid> <link>${value.downloadUrl}</link> <author><![CDATA[${value.from}]]></author> </item>`; }); return `<?xml version="1.0" encoding="UTF-8"?> <rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"> <channel> <title><![CDATA[${tag}邮件订阅]]></title> <link>${deployUrl + tag}</link> <atom:link href="${ deployUrl + tag }" rel="self" type="application/rss+xml" /> <description><![CDATA[${tag}邮件订阅]]></description> <generator>mail2rss</generator> <webMaster>lengthmin@gmail.com (Artin)</webMaster> <language>zh-cn</language> <lastBuildDate>${new Date().toGMTString()}</lastBuildDate> <ttl>300</ttl> ${items.join("\n")} </channel> </rss>`; } |
其中TAG换成自己设置的一串字符(其作用相当于后面调用时的请求路径),NAMESPACE换成testmail的NameSpace,STOKEN换成testmail的API keys,LINKS则是当前workers的调用地址或是设置自己的域名https://xxx.abc.com(细节自行Google)。
那么后面要用到的RSS地址为:workers的调用地址+TAG。假设我的Tag的ribfg,域名为jiemo.top,那么我的订阅地址将是https://testmail.jiemo.top/ribfg。
(3)连接到自己的邮箱【设置转发】
以Gmail为例,设置中设置转发到testmail的测试邮箱,即{NameSpace}.{Tag}@inbox.testmail.app
-设置转发-
完成转发需要向测试邮箱发送一封验证邮件,如何查看这个验证邮件。来到testmail控制台。
-点击clickhere-
查看验证邮件内容,点击其中的验证链接完成转发设置。
(4)测试转发
使用另外的邮箱向Gmail发送邮件,clickhere可以查看到发送的邮件即可。自行操作
(5)订阅邮箱
订阅前可以先手动访问一下RSS地址(https://testmail.jiemo.top/ribfg)
-发送的邮件包含其中-
-订阅它,结束-
结语
cloudflare workers 每天免费请求量 100,000 次。
testmail.app 免费版每个月可以接收 100 封邮件,邮件可以保存一天。
也就是说,只要你的RSS阅读器请求频率小于一天,你都能毫无遗漏的接收每一封邮件。
此法也是0成本的方案。