如何使用 JavaScript 在 Bluesky 上发布带有嵌入卡的链接

如何使用 javascript 在 bluesky 上发布带有嵌入卡的链接

随着 bluesky 的不断流行,更多的工具正在围绕它开发。最流行的应用程序之一是后期调度和自动化。

但是,bluesky 的 api 目前不提供直接发布 opengraph 卡片链接的方法。对于想要共享具有有吸引力预览的链接的用户来说,这可能是一个挑战。

在本教程中,我们将向您展示如何使用 javascript 在 bluesky 上发布带有嵌入卡的链接。此方法可以解决 api 限制,让您更有效地共享链接。

让我们开始吧!

立即学习“Java免费学习笔记(深入)”;

使用 javascript api 在 bluesky 上发帖

使用 bluesky api 非常简单。文档非常好。首先,我们需要从 npm 安装 @atproto/api 包:

npm install @atproto/api

接下来,我们创建 bluesky agent 的实例并使用您的 bluesky 凭据登录。

我建议为您的 bluesky 帐户创建一个新的应用程序密码,而不是使用您的主密码。这将使您在需要时更容易撤销访问权限并确保您的主帐户安全。另请确保在项目中设置 bluesky_username 和 bluesky_password 环境变量。

import { atpagent } from "@atproto/api"const getblueskyagent = async () => {  const agent = new atpagent({    service: "https://bsky.social",  })  await agent.login({    identifier: process.env.bluesky_username!,    password: process.env.bluesky_password!,  })  return agent}

一旦你有了代理,你就可以用它来发布到 bluesky,这非常简单。

/** * send a post to bluesky * @param text - the text of the post */export const sendblueskypost = async (text: string, url?: string) => {  const agent = await getblueskyagent()  await agent.post({ text })}

就这样,您刚刚向 bluesky 发送了一条帖子。不幸的是,即使您在帖子的文本中包含链接,它也不会自动转换为锚链接。我们很快就会解决这个问题。

自动检测 bluesky 上的分面链接

当您在 bluesky 上的帖子文本中包含链接时,它不会自动转换为锚链接。相反,它显示为纯文本。

要解决此问题,您需要检测链接并将其转换为分面链接。

虽然有手动方法可以实现这一点,但幸运的是,atproto 提供了一个 richtext 类,可以自动检测链接并将其转换为分面链接。

import { richtext } from "@atproto/api"/** * send a post to bluesky * @param text - the text of the post */export const sendblueskypost = async (text: string) => {  const agent = await getblueskyagent()  const rt = new richtext({ text })  await rt.detectfacets(agent)  await agent.post({    text: rt.text,    facets: rt.facets,  })}

那太好了,但我们仍然需要将嵌入卡添加到帖子中。接下来我们就开始吧。

在 bluesky 上创建嵌入卡

在帖子中包含链接固然很棒,但如果您可以添加嵌入卡就更好了。

为了实现这一点,我们需要使用 bluesky 的网站卡片嵌入功能。本质上,您向帖子添加一个嵌入密钥,其中至少包括 url、标题和描述。

有多种方法可以获得所需的数据。如果您在发布时知道它,则可以简单地对其进行硬编码。否则,您可以抓取 url 以收集标题、描述和图像。

但是,我发现最简单的方法是使用 dub.co metatags api 获取 url 元数据,然后从中创建嵌入卡。让我们看看它是如何工作的。

type metadata = {  title: string  description: string  image: string}/** * get the url metadata * @param url - the url to get the metadata for * @returns the metadata */const geturlmetadata = async (url: string) => {  const req = await fetch(`https://api.dub.co/metatags?url=${url}`)  const metadata: metadata = await req.json()  return metadata}

我们创建了一个简单的函数,用于获取 url 元数据,然后以清晰的格式返回数据。

接下来,让我们创建一个函数,使用元数据将图像上传到 bluesky,然后创建嵌入卡。

const getblueskyembedcard = async (url: string | undefined, agent: atpagent) => {  if (!url) return  try {    const metadata = await geturlmetadata(url)    const blob = await fetch(metadata.image).then(r => r.blob())    const { data } = await agent.uploadblob(blob, { encoding: "image/jpeg" })    return {      $type: "app.bsky.embed.external",      external: {        uri: url,        title: metadata.title,        description: metadata.description,        thumb: data.blob,      },    }  } catch (error) {    console.error("error fetching embed card:", error)    return  }}

一旦我们有了嵌入卡,我们就可以将其添加到帖子中。

export const sendblueskypost = async (text: string, url?: string) => {  const agent = await getblueskyagent()  const rt = new richtext({ text })  await rt.detectfacets(agent)  await agent.post({    text: rt.text,    facets: rt.facets,    embed: await getblueskyembedcard(url, agent),  })}

现在我们有一个功能,可以使用嵌入卡向 bluesky 发送帖子。

完整示例

希望,如果您已经按照说明进行操作,现在应该已经有了完整的代码。如果没有,这里是完整的代码,您可以将其复制并粘贴到您的项目中。它:

创建 bluesky 代理获取 url 元数据创建嵌入卡使用嵌入卡向 bluesky 发送帖子并自动检测多面链接

import { AtpAgent, RichText } from "@atproto/api"type Metadata = {  title: string  description: string  image: string}/** * Get the URL metadata * @param url - The URL to get the metadata for * @returns The metadata */const getUrlMetadata = async (url: string) => {  const req = await fetch(`https://api.dub.co/metatags?url=${url}`)  const metadata: Metadata = await req.json()  return metadata}/** * Get the Bluesky embed card * @param url - The URL to get the embed card for * @param agent - The Bluesky agent * @returns The embed card */const getBlueskyEmbedCard = async (url: string | undefined, agent: AtpAgent) => {  if (!url) return  try {    const metadata = await getUrlMetadata(url)    const blob = await fetch(metadata.image).then(r => r.blob())    const { data } = await agent.uploadBlob(blob, { encoding: "image/jpeg" })    return {      $type: "app.bsky.embed.external",      external: {        uri: url,        title: metadata.title,        description: metadata.description,        thumb: data.blob,      },    }  } catch (error) {    console.error("Error fetching embed card:", error)    return  }}/** * Get the Bluesky agent * @returns The Bluesky agent */const getBlueskyAgent = async () => {  const agent = new AtpAgent({    service: "https://bsky.social",  })  await agent.login({    identifier: process.env.BLUESKY_USERNAME!,    password: process.env.BLUESKY_PASSWORD!,  })  return agent}/** * Send a post to Bluesky * @param text - The text of the post * @param url - The URL to include in the post */export const sendBlueskyPost = async (text: string, url?: string) => {  const agent = await getBlueskyAgent()  const rt = new RichText({ text })  await rt.detectFacets(agent)  await agent.post({    text: rt.text,    facets: rt.facets,    embed: await getBlueskyEmbedCard(url, agent),  })}

我希望您发现本教程很有帮助,并且您会考虑在自己的项目中使用它。

发帖快乐!

以上就是如何使用 JavaScript 在 Bluesky 上发布带有嵌入卡的链接的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1499399.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月19日 21:45:18
下一篇 2025年12月19日 21:45:30

相关推荐

  • 深入理解React useEffect依赖项:解决登录后用户资料不自动更新问题

    本文深入探讨React useEffect钩子的核心机制,特别是其依赖项数组的作用,以解决用户登录后个人资料无法自动更新,需要手动刷新页面才能生效的问题。我们将分析常见错误,并提供一套正确的实践方案,包括如何合理管理组件状态、优化数据获取逻辑,并确保useEffect在关键状态变化时正确地重新执行,…

    2025年12月20日
    000
  • 实现滚动时SVG遮罩层缩放动画效果

    本文旨在指导开发者如何利用SVG遮罩(mask)和JavaScript实现一个在页面滚动时,SVG遮罩层能够动态缩放并适配视口的效果。通过本文,你将学习到SVG遮罩的基本原理、CSS样式设置以及JavaScript控制SVG元素属性的方法,最终实现一个具有吸引力的视觉效果。 SVG遮罩原理 SVG遮…

    2025年12月20日
    000
  • Next.js与Hygraph数据集成:解决map错误及API认证指南

    本文旨在解决Next.js应用中从Hygraph拉取数据时遇到的Cannot read properties of undefined (reading ‘map’)错误。核心问题在于Hygraph API请求缺少必要的认证令牌。教程将详细指导如何配置Hygraph API访…

    2025年12月20日
    000
  • 如何用JavaScript实现一个算法可视化工具?

    答案:通过JavaScript结合Canvas实现冒泡排序可视化,用柱状图展示数组,高亮比较交换元素并延时执行。步骤包括定义目标、搭建HTML结构、绘制数组状态、实现异步排序逻辑、添加交互控制及扩展功能如算法切换与速度调节。 实现一个算法可视化工具,关键在于将算法执行过程中的每一步通过图形界面清晰展…

    2025年12月20日
    000
  • 生成准确表达文章主题的标题 在JSX中处理动态对象属性与可选链式调用

    本文深入探讨了在React JSX中如何高效、安全地处理动态对象属性访问。文章首先阐述了使用方括号表示法来访问动态键的正确姿态,纠正了常见的语法错误。随后,针对多层嵌套对象的冗长访问和潜在错误,介绍了ES2020引入的可选链式调用(Optional Chaining),展示了它如何简化代码并提升健壮…

    2025年12月20日
    000
  • 在JSX中处理动态字段和复杂嵌套数据结构的高效指南

    本文旨在指导开发者如何在JSX中优雅地处理动态命名的对象字段,并利用JavaScript的可选链操作符简化对深层嵌套属性的访问。我们将探讨正确的动态字段访问语法,并展示如何通过可选链显著提升代码的可读性和健壮性,从而避免冗长且易错的条件判断。 在JSX中访问动态命名字段 在react组件的jsx中,…

    2025年12月20日
    000
  • 如何利用Monaco Editor构建功能丰富的在线代码编辑器?

    Monaco Editor是微软开发的浏览器端代码编辑器,源自VS Code核心,支持语法高亮、智能补全、错误检查、代码折叠和主题切换等功能。通过npm安装monaco-editor包并结合Webpack或Vite等构建工具可快速集成。创建容器元素后,使用monaco.editor.create()…

    2025年12月20日
    000
  • 如何利用 CSS-in-JS 技术动态地管理组件的样式和主题?

    使用 CSS-in-JS 可实现组件级样式动态管理与主题切换,通过 styled-components 等库结合 props 和 ThemeProvider,使样式与状态联动。1. 安装 styled-components 并创建带 props 的动态样式按钮;2. 定义 lightTheme 与 …

    2025年12月20日
    000
  • 在JavaScript中,异步编程除了Promise和Async/Await还有哪些模式?

    回调函数用于简单异步任务但易形成回调地狱;2. 事件监听适用于解耦的多次触发场景;3. Generator函数结合yield实现类同步写法,需手动驱动;4. Observable适合处理连续数据流,支持丰富操作符;5. Promise与async/await因语法简洁成为主流,但实际常混合使用多种模…

    2025年12月20日
    000
  • JSX中动态字段的渲染与安全访问指南

    本文旨在指导开发者如何在React JSX中高效处理动态命名字段。我们将深入探讨如何利用方括号语法(Bracket Notation)正确访问运行时生成的对象属性,并介绍如何通过可选链操作符(Optional Chaining)简化对深度嵌套对象的条件渲染,从而提升代码的健壮性和可读性。 在现代前端…

    2025年12月20日
    000
  • MERN栈React应用中useEffect实现登录后用户资料即时更新

    本教程深入探讨了MERN栈React应用中useEffect钩子在用户登录后,用户资料未能即时更新,需要刷新页面才能显示最新数据的问题。文章详细分析了useEffect依赖数组的正确使用,指出常见错误,并提供了基于用户状态变化的依赖管理方案,确保用户资料在登录后能立即响应并更新,从而提升用户体验。 …

    2025年12月20日
    000
  • React useEffect 登录后数据不同步问题:原理与解决方案

    本文深入探讨了React useEffect钩子在用户登录后,个人资料数据未能即时更新,需要页面刷新才能生效的常见问题。文章分析了useEffect依赖项的正确使用方式,指出了将自身状态作为依赖项的常见误区,并提供了基于用户认证状态(如用户ID或对象)来触发数据更新的专业解决方案,旨在帮助开发者实现…

    2025年12月20日
    000
  • 如何用Service Worker实现智能资源缓存策略?

    Service Worker通过缓存策略实现离线访问和性能优化,需先注册并经历安装、激活等生命周期阶段。采用缓存优先、网络优先或先缓存后更新等策略可提升资源加载效率,结合版本控制与缓存清理确保数据有效性,仅在HTTPS或本地环境中使用。 Service Worker 是实现离线体验和高效资源加载的核…

    2025年12月20日
    000
  • 如何实现一个JavaScript的无限滚动(Infinite Scroll)组件?

    答案:实现JavaScript无限滚动需监听滚动事件,判断接近底部时加载数据,通过isLoading防止重复请求,使用节流优化性能,并动态插入内容到DOM提升体验。 实现一个 JavaScript 的无限滚动组件,核心思路是监听用户滚动行为,在接近页面底部时自动加载更多内容。关键在于判断何时触发加载…

    2025年12月20日
    000
  • React中基于JavaScript类的全局状态管理:实践与考量

    本文探讨了在React应用中,尤其是在使用旧版Class组件时,如何利用JavaScript类实现全局状态管理。文章首先介绍基础的类结构,随后重点讲解了基于ES模块的推荐实践,通过导出类的实例实现状态共享,并提及了在HTML中加载模块的注意事项。最后,文章还讨论了在极端必要时使用window或glo…

    2025年12月20日
    000
  • 如何在 React 中使用 While 循环遍历数组并传递索引值

    本文旨在介绍如何在 React 中安全有效地使用 while 循环遍历数组,并正确传递索引值。我们将探讨使用 while 循环在 React 组件中动态生成元素的方法,并提供避免常见错误的实践建议。通过本文,你将掌握如何在 React 中正确地使用 while 循环来处理数组数据,并生成动态的 UI…

    2025年12月20日
    000
  • 使用SVG Mask实现滚动展开动画效果

    本文详细介绍了如何使用SVG Mask技术,结合滚动事件,实现图片在滚动时逐渐展开并填充视口的动画效果。通过动态调整SVG Mask的缩放比例,创造出引人注目的视觉体验,并提供了完整的代码示例和关键步骤解析,帮助开发者轻松掌握该技巧。 核心原理 实现滚动展开效果的核心在于利用SVG的mask属性。m…

    2025年12月20日
    000
  • 使用SVG遮罩实现滚动展开效果教程

    本文将指导你如何使用 SVG 遮罩(mask)技术,结合 JavaScript 监听页面滚动事件,实现一个当页面滚动时,SVG 遮罩区域逐渐展开并覆盖视口的动态效果。我们将详细讲解实现原理、代码实现以及关键步骤,助你轻松掌握该技术。 原理概述 实现该效果的核心在于以下几点: SVG 遮罩 (Mask…

    2025年12月20日
    000
  • 使用 SVG 遮罩实现滚动展开动画效果

    本文将介绍如何使用 SVG 遮罩实现一个滚动展开动画效果。通过监听滚动事件,动态调整 SVG 遮罩的缩放比例,从而实现遮罩区域随滚动条位置变化而展开的效果。教程将提供完整的 HTML、CSS 和 JavaScript 代码示例,并详细解释实现原理和关键步骤。 实现原理 核心思路是利用 SVG 的 元…

    2025年12月20日
    000
  • 使用 SVG 遮罩实现滚动时图像放大效果教程

    本教程将引导你使用 SVG 遮罩技术,实现当页面滚动时,SVG 遮罩区域内的图像逐渐放大并填充视口的效果。我们将提供详细的代码示例和解释,帮助你理解和应用这种动态视觉效果。通过本教程,你将掌握如何利用 SVG 遮罩、JavaScript 和 CSS,创建引人入胜的滚动动画。 1. 准备工作 首先,我…

    2025年12月20日
    000

发表回复

登录后才能评论
关注微信