将web内容分享到twitter
将web内容分享到twitter
需求背景
公司为数百万个用户提供了年度报告的数据。因为不希望更新APP版本,所以决定用web的形式展示在APP内,并且可以一键分享到 twitter。同时分享到twitter的内容需要生成twitter卡片,而且卡片的内容是动态生成的;以图片的形式分享。
技术调研
如何分享
根据 twitter-for-websites 资料得知,分享到twitter,是通过链接跳转的形式完成的。但是携带过去的内容只能是字符串。如果携带的字符串包含一个合法 URL 的时候,twitter 就会开始分析这个地址所指向的页面内容以生成卡片。
生成规则
根据 twitter-for-websites 下 card 的 getting-started 资料得知,卡片的生成规则是识别页面的 head 标签里特殊的 meta 配置。例如:
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@nytimesbits" />
<meta name="twitter:creator" content="@nickbilton" />
<meta property="og:url" content="http://bits.blogs.nytimes.com/2011/12/08/a-twitter-for-my-sister/" />
<meta property="og:title" content="A Twitter for My Sister" />
<meta property="og:description" content="In the early days, Twitter grew so quickly that it was almost impossible to add new features because engineers spent their time trying to keep the rocket ship from stalling." />
<meta property="og:image" content="http://graphics8.nytimes.com/images/2011/12/08/technology/bits-newtwitter/bits-newtwitter-tmagArticle.jpg" />
twiiter 识别到的 meta 配置必须是静态的,也就是说用 js 动态创建的标签是无效的。
需求边界
卡片识别出的图片是动态的,动态内容主要从 web 页面到图片的生成,最后到一个动态的 html 结构。如何处理图片就需要额外注意:
- 当时间和预算都足够,可以根据用户活跃度的顺序,为一定量的用户提前生成好图片。最后把大量的图片放到购买的云存储服务上
条件有限时,按需生成的图片需要考虑服务器的负载情况
- 为了提高读取速度,服务器的存储是否足够
- 为了缓解存储压力,服务器的运行内存是否足够
开发调试
建议配合 vercel 来校验生成的效果,把 vercel 赋予的域名粘贴到 twiiter 里即可。但需要注意,一旦 twitter 从一个域名地址里识别到了生成卡片的配置,就会产生强缓存。只有地址变了,才会重新识别,所以可以每次校验的时候给域名随便添加一个参数即可。
具体实施
Web
<a href="https://twitter.com/intent/tweet?url=hello">share</a>
点击这个链接就会跳转到 twitter,并且会识别出 url 字段的字符自动弹出表单填入
- 如果作为 webview 被嵌入到 app 里,并且手机也安装了 twitter,跳转时会自动打开 twitter 并填入 url 字段的字符
- 如果只是为了填入表单,不作卡片识别,建议用 text 字段
Server
上述的 url 的字段,需要指向一个服务端渲染的 html 页面,内容还是动态的。以 Express 为例
export const shareTwitter: RequestHandler = async (req, res) => {
const url = ''; // 点击 twitter 卡片时跳转的地址
const image = ''; // 卡片识别到的图片地址
res.send(`<!DOCTYPE html>
<html lang="en">
<head>
<meta name="twitter:site" content="@xxx" />
<meta name="twitter:creator" content="@xxx" />
<meta property="og:url" content="${url}" />
<meta property="og:title" content="title" />
<meta property="og:image" content="${image}" />
<meta content="summary_large_image" name="twitter:card" />
</head>
<body>
</body>
</html>
`);
};
假设这个接口的请求地址为 https://xxx.com/api/shareTwitter ,那么在 web 页面下就是
<a href="https://twitter.com/intent/tweet?url=https://xxx.com/api/shareTwitter">share</a>
注意为 a 标签的 href 作 URL 编码
这时跳转到 twitter 后,自动填入表单的就是一个服务端渲染的 html 页面了。
从 web 内容到图片的生成就另一个技术方向了,可供选择的方案有很多,比如 sharp、puppeteer 等等。笔者的做法是采用的 sharp,因为 puppeteer 对内存的占用太大。即便如此,sharp 生成图片的单次请求,也会消耗几兆的内存。建议使用 vercel 的 satori 工具,可以将 html 转换成 svg,对内存消耗更小,呈现效果也更好。
作者:Alex文章发布日期:2023-01-28 13:11原文博客链接:https://alex-blog-site.vercel...GitHub: https://github.com/Alex-Progr...著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
转载自:https://segmentfault.com/a/1190000043429803