🗨️使用Pipedream同步RSS至BlueSky

2024-12-2|2025-1-1
Yawatasensei
Yawatasensei
type
status
date
slug
summary
tags
category
icon
password
😀
BlueSky是一个新的社会化媒体平台,由Jack Dorsey于2019年提出并创立。随着X.com的商业化内容越来越多,以及马斯克的各种骚操作,BlueSky最近也算出尽了风头,不少用户从X.com(Twitter)转移到了BlueSky,并将BlueSky作为新的Social Media传播平台进行使用。在使用这种Social Media平台时,我最关心的部分就是如何进行不同平台之间的信息同步,例如之前我将豆瓣上的书、影、音等记录同步到Twitter和Mastodon,或者将最新的博客内容同步发送至Twitter和Mastodon等等。目前已经有较为成熟的方案在RSS与X.com之间进行自动化同步(可惜ifttt和dlvr.it都已经收费了),但还没有较为成熟的BlueSky同步方案,今天就将一个国外博主Raymond Camden的方案翻译一下给需要的朋友。

为什么BlueSky用户增长这么多?

X.com(Twitter)的最新使用条款提到:
在最新用户使用条款中第三条服务内容中的您对内容的权利和授予的权利中明确规定,用户通过 X平台发布的任何内容 (包括文字、图片、音频和视频等) 都将授予X免费使用,包括用于训练人工智能模型。同时X平台还有权利将用户内容提供给其他公司、组织或个人使用,以上两种情况X都不会向用户支付任何报酬。
这个新条款已经在2024年11月15日生效。这让用户与内容生产者们感到恐惧。在X.com(Twitter)的最新使用条款助攻下,BlueSky在昨天活跃用户数量已经超越了Threads,也许在未来的某个时间点,BlueSky可以和X.com做到分庭抗礼吧。

📝 方案来源

📝 方案内容

目前Raymond Camden所使用的方案是通过自动化平台Pipedream实现,需要一些代码基础,相对于类IFTTT或者Dlvr.it等成熟的平台,对用户有一些技术上的门槛,不过Pipedream提供了丰富的开发工具,例如Python、NodeJS、Golang等等,借助这些开发语言与BlueSky的开发文档,也能够实现同步的功能。

注册Pipedream

打开Pipedream的官网:https://pipedream.com/auth/signup 进行注册,只需要邮箱和密码即可完成注册。目前不确定国内访问Pipedream是否需要科学上网。图省事也可以直接使用Google或者Github账号。

创建项目及工作流

Pipedream中,首先需要创建项目,一个项目可以包括多个自动化的流程,但是其实我们只需要用到一个自动化工作流就好。点击右上角的“New Project”进行创建。
notion image
 
填写一下项目的名称即可,建议自己填写一个较短的、易于辨识的名字,不要使用默认的名字,不然删除项目的时候有点麻烦。
notion image
然后点击New - Wrokflow,保持所有内容默认,直接点击Create Workflow创建工作流即可进入工作流的编辑配置页面。
notion image
 

添加RSS Trigger

notion image
点击Add Trigger,添加触发器,选择My Sources - New Item in RSS Feed ,也就是RSS源中的新内容。
notion image
  • Timer:循环时间,建议不要选择过于频繁,查询次数太多,占用免费额度,同时RSS源的内容更新也没那么频繁,同步也不一定需要太高的时效性,我选择的是6小时。
  • Feed URL:RSS源地址,填写你博客的地址,或者你希望同步的RSS源地址,例如豆瓣的RSS
  • Published After:即在此时间之后的内容才会被同步,建议选择当前时间靠前一点,如果使用默认时间,可能会第一次同步过多内容。
完成以上内容的填写之后,点击Configure to save ,Pipedream会自动尝试获取RSS源的内容。如果你同步的RSS所使用的域名使用了Cloudflare的“自动程序攻击模式”,可能Pipedream无法抓取内容,会被Cloudflare识别为自动程序而阻拦,可以在“安全性 - 自动程序 - 自动程序攻击模式”中进行关闭。目前我测试下来,豆瓣提供的RSS是可以正常抓取的。
Slelect a different event中随便选择一条由RSS中读取的条目,即可在Result中查看到对应trigger获取到的信息,点击Continue 进入到添加Action动作环节。
notion image

添加Action(动作)及部署

我们已经从触发器能够正常的获取信息,并配置好了如何触发,那么下一步就是在触发之后,需要Pipedream进行什么操作。在本篇文章中,我们所需要进行的操作就是将获取到RSS内容,以卡片的形式发布到BlueSky中。
选择Node - Run Node Code
notion image
 
然后复制以下代码到CODE的输入框里,原作者的代码由于会提示steps.trigger.event.link being undefined,所以根据评论中的内容进行了修改。
需要注意的是,这里有两点需要根据自己的账号进行修改:
  • identifier:修改为你的bluesky的用户名,例如xxxxx.bsky.social 。如果使用第三方的域名,可能无法正常使用,我还没有做测试。
  • password:修改为你自己配置的App Password,配置位置位于BlueSky的Settings - Privacy and security - App passwords,添加一个新的App Password即可,需要注意的是,当添加完成后显示的密码需要及时保存,因为关闭弹窗之后就不会再显示了。
 
代码使用了cheerio@atproto/api库,用于在Bluesky社交平台上自动发布内容。逐行解释如下:
  1. import * as cheerio from 'cheerio';
    1. 导入cheerio库,用于在Node.js环境中解析和操作HTML文档。
  1. import Atproto from '@atproto/api';
    1. 导入@atproto/api库,这个库包含与Bluesky API交互的工具。
  1. const { RichText, BskyAgent } = Atproto;
    1. Atproto中解构出RichTextBskyAgent类,用于处理文本和与Bluesky API通信。
  1. export default defineComponent({
    1. 导出一个默认的组件定义,通常用于在框架中定义一个可执行组件。
  1. async run({ steps, $ }) {
    1. 定义一个异步的run方法,该方法接收一个包含steps$的对象作为参数。steps包含工作流的步骤数据,例如我们通过RSS Trigger所获取到的数据。
  1. const agent = new BskyAgent({ service: 'https://bsky.social' });
    1. 创建一个新的BskyAgent实例,用于与Bluesky API交互,并指定服务地址。
  1. await agent.login({ identifier: 'bluesky用户名', password: 'App PassWord' });
    1. 使用指定的用户名和应用密码登录到Bluesky平台。
  1. let card = { uri:steps.trigger.event.link, title:steps.trigger.event.title, }
    1. 初始化一个card对象,包含从触发事件中提取的链接和标题。
  1. let req = await fetch(steps.trigger.event.link);
    1. 使用fetch函数请求事件中链接的HTML内容。
  1. let html = await req.text();
    1. 将请求的响应转换为文本格式(HTML)。
  1. let $$ = cheerio.load(html);
    1. 使用cheerio加载 HTML 内容,以便后续解析。
  1. card.description = $$('meta[property="og:description"]').attr('content');
    1. 使用cheerio提取HTML中的Open Graph描述元标签的内容,并赋值给card.description
  1. let image = $$('meta[property="og:image"]').attr('content');
    1. 提取Open Graph图像元标签的内容,用于后续上传。
  1. let blob = await fetch(image).then(r => r.blob());
    1. 下载图像并将其转换为Blob对象。
  1. let { data } = await agent.uploadBlob(blob, { encoding:'image/jpeg'} );
    1. 使用agent.uploadBlob方法上传图像Blob,并指定编码格式为JPEG,存储返回的数据。
  1. card.thumb = data.blob;
    1. 将上传的 Blob 数据存储在card对象的thumb属性中。
  1. let rt = new RichText({ text: 发现了新的内容: "${steps["trigger"]["event"]["title"]}" });
    1. 创建一个新的RichText实例,并设置文本内容,包含触发事件的标题。
  1. await rt.detectFacets(agent);
    1. 使用detectFacets方法检测文本中的特性(如链接、标签等),可能用于格式化或增强文本。
  1. await agent.post({
    1. 使用agent.post方法在Bluesky平台上发布一个新帖子。
  1. text: rt.text, facets: rt.facets, langs: ['en-US'], createdAt: new Date().toISOString(), embed: { $type: "app.bsky.embed.external", external: card }
    1. 设置发布帖子的内容,包括文本、特性、语言、创建时间,以及嵌入的外部卡片信息。
  1. return;
    1. 结束run方法的执行。
       
完成上述步骤之后,点击Test按钮进行代码测试,不出意外的话,应该会提示Success成功,在Bluesky中也可以看到一条新的同步的消息,这时候点击Deploy就可以正式部署了。
代码中所绘制的卡片样式大概是,JS能力强的朋友,也可以根据自己的需要进行代码上的修改。
notion image

🤗 总结归纳

整体流程其实还是很简单的,无非就是配置触发器、配置动作以及部署。Pipedream提供的免费额度也足够个人使用,支持10个工作流,我个人的话,豆瓣加上个人的博客同步,也就使用2个工作流。
另外顺便研究了一下,Pipedream的Action中包括发布Mastodon动态,所以理论上也可以同步至Mastodon。
notion image
对于X.com(Twitter)来说,目前没有找到成熟的Action,可能需要自行申请Developer Access然后使用代码方式同步。
 

📎 参考文章

 
💡
有关家庭网络配置或者使用上的问题,欢迎您在底部评论区留言,一起交流~
PVE环境RouterOS开启Container指南Dae安装及配置指南
Loading...