微语/说说/微博/Mricoblog 嵌入博客网页
本文尝试使用一些程序搭建个人微博,并嵌入到博客网页。
缘起
以前使用 hexo butterfly 主题时,注意到有 说说/微语 的进阶配置。近年来看到不少类似的,或者别名,如微语/微言/说说/微言微语/碎碎念/碎语/Artitalk.js/哔哔/唠叨/嘀咕/时光机/Microblog/microblogging。大概,他们可以统称为 微博 或者说 微博客,不过为了与新浪微博分辨开消除歧义,可通过搜索上面的关键词来避开新浪微博相关词条。这类在 github 上有一个话题或者说标签 https://github.com/topics/microblog
开源微博
我注意到,这个 github 话题下实现 ActivityPub 如 Mastodon ,Misskey 比较流行。实际上,使用相关 API 可以很轻松的嵌入微博到个人博客网站中,互动也是比较方便的,只要一个账号就行了。此外实现了 ActivityPub 还有 Pleroma, PixelFed, PeerTube , GoToSocial, microblog.pub , Firefish(Misskey分支), Akkoma 等等。其中 GoToSocial, microblog.pub 很适合单人实例。分布式开源微博程序有 Farcaster, Mastodon, Nostr 等等,也可以探索使用其中一个,尝试嵌入网页。如果会写代码,写一个类似程序也很简单。
此外,也有仿照微信朋友圈的一些静态博客生成器主题可供选择,当然这类主题很难做到随手一记,不过也算有着简单易用的优点。如 https://github.com/FarseaSH/hugo-theme-moments Moments是适合发布短博文的Hugo主题,作为独立的短文/动态空间。Demo https://farseash.github.io/demo-hugo-theme-moments/moments/
此外可用的工具还有
后端:
Wordpress/Typecho/Mblog 等 php 博客程序插件
借助云函数 部署 Artitalk.js 部署说说/微语
自行部署 memos golang + sqlite 备忘录程序
自行部署 pocketbase golang + sqlite 快速开发后端程序
自行部署或使用 CMS 或 无头 CMS 程序 ,如 Ghost
自行编写后端
前端:
php 程序微语插件附带
mastodon/gotosocial/memos 自带网页 可使用 api 嵌入博客网页
pocketbase/CMS/自行编写后端 需要自行写前端网页
发布:
php 程序一般后台发布/api
mastodon 类使用客户端发布
memos 网页客户端发布
pocketbase 网页管理界面/API 发布
Artitalk.js 网页管理
使用 API 支持 http 请求的工具,或者嵌入到机器人,如微信测试号中,进行发布。
实际上,如果对前后端有一定了解,自习修改或编写自的前后端并不很困难,并且现在可以使用 ChatGPT 进行代码的提示,注释,讲解,生成,优化等等。
GoToSocial 和 PocketBase
如果有 Mastodon ,Misskey 账户,建议直接调用相关 API 。如果部署云函数可以选择 Artitalk.js, 个人实例建议选 gotosocial ,memos 或者 pocketbase 。memos 我没有尝试,本文也不会涉及,不过有热心的网友已经写好了相关教程 https://immmmm.com/bb-by-memos/
gotosocial 部署起来还算简单,但是部署后本身网页没有客户端,必须选择使用一个客户端。程序本身有 rss 和 markdown 支持 ,API 可直接获取到 HTML 。客户端可以选择原生应用,也可以选择 web 端,如基于 JS 客户端 SDK https://github.com/neet/masto.js/ 的
- 4.2k https://github.com/elk-zone/elk https://elk.zone/home/ 鹿鸣
- 600+ https://neet.github.io/masto.js/
或者
100+ https://github.com/NickColley/semaphore https://semaphore.social/
pocketbase 本身和微博客没有什么关系,这是一个快速开发后端程序,也就是一些 CURD 封装,可以搭建个人微博,评论系统之类的。实际上嵌入 js 也很容易实现如后端转 markdown 为 HTML 存储在一个字段之类的功能。自带网页管理面板,增删改查 UI 操作也算方便。
下面给出这两个程序 hugo 静态博客生成器 的 shortcodes ,适用于 pocketbase 和 mastodon 类程序。截至发文,可以在本文下面,或者 https://www.ftls.xyz/whispers/ 找到 demo。
下面这个两个 demo ,我都写个好几个版本,但是大差不差的。自己使用基本都会做一些改变。可以在 https://gitee.com/kkbt/www.ftls.xyz/tree/master/layouts/shortcodes 找到所有版本。
PocketBase
pocketbase shortcode 源码 https://gitee.com/kkbt/www.ftls.xyz/blob/master/layouts/shortcodes/pocketbase2.html
说明: 代码使用了一个依赖 moment.js ,用于将时间转换为 1小时前,3 天前,2000 年 01 月 01 日之类的,moment js 实际上需要引入两个文件,我手动合并成了一个,实际上可以选择更小的,不到 1kb 的 Lately.js ,显示效果差不太多。
<div id="pocketbase">
<div id="tweetList"></div>
<a id="moreButton" href="#" onclick="showMore(); return false;">更多</a>
</div>
<script type="text/javascript" src="/js/moment.js"></script>
<script type="text/javascript">
const tweetList = document.getElementById('tweetList');
const moreButton = document.getElementById('moreButton');
const apiUrl = "https://api.ftls.xyz/api/collections/whispers/records";
let currentPage = 1;
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function displayTweets(tweets) {
tweets.forEach(tweet => {
const blockquote = document.createElement('blockquote');
const createdAtDiv = document.createElement('div');
createdAtDiv.textContent = moment(tweet.createdAt).twitter(); // moment.js 或者 相对时间 Lately.js
const contentDiv = document.createElement('div');
contentDiv.innerHTML = escapeHtml(tweet.text).replace(/\!\[.*\]\((.+)\)/g, '<img src="$1" loading="lazy" />');
blockquote.appendChild(createdAtDiv);
blockquote.appendChild(contentDiv);
tweetList.appendChild(blockquote);
});
// window.Lately && Lately.init({ target: '.lately' }); // 相对时间 Lately.js 初始化
}
function fetchTweets(page) {
const params = new URLSearchParams({
sort: '-createdAt',
perPage: 10,
page: page
});
const url = `${apiUrl}?${params.toString()}`;
fetch(url)
.then(response => response.json())
.then(data => {
displayTweets(data.items);
if (data.page < data.totalPages) {
moreButton.style.display = 'block';
currentPage = data.page + 1;
} else {
moreButton.style.display = 'none';
}
});
}
function showMore() {
moreButton.style.display = 'none';
fetchTweets(currentPage);
}
// 页面加载时获取第一页推文
fetchTweets(currentPage);
</script>
<!-- 简易样式;如果 Hugo 主题有样式可能会被覆盖 -->
<style>
blockquote {
margin: 0;
}
blockquote p {
padding: 15px;
background: #eee;
border-radius: 5px;
}
</style>
需要注意的是该 demo 我把 URL 写死了,不需要参数,后端提供 markdown 文本,前端仅使用正则表达式替换 markdown 图片为 HTML 。
GoToSocial
gotosocial shortcode 源码 https://gitee.com/kkbt/www.ftls.xyz/blob/master/layouts/shortcodes/mastodon.html
该 shortcode demo 没有任何依赖,并未显示时间,而且会显示回复和转嘟,hugo 页面使用需要2或3个参数,参考上面页面源码。
发布可参考 手机发布微语说说
<div id="toots"></div>
<button id="toots-moreButton" onclick="tootsShowMore()">更多</button>
<script>
let maxId = null; // 初始值为 null,表示第一页
const tootsDiv = document.getElementById('toots');
const tootsMoreButton = document.getElementById('toots-moreButton');
// 获取 Mastodon 用户公开Toots
async function getPublicToots() {
const queryParams = maxId ? ("?limit={{ .Get 2 | default 5 }}&max_id=" + maxId) : "?limit={{ .Get 2 | default 5 }}";
const response = await fetch("{{ .Get 0 }}/api/v1/accounts/{{ .Get 1 }}/statuses" + queryParams);
const toots = await response.json();
return toots;
}
// 将Toots显示在页面上
async function displayToots() {
try {
const toots = await getPublicToots();
if (toots && toots.length > 0) {
toots.forEach(toot => {
const tootDiv = document.createElement('div');
tootDiv.innerHTML = `<p>${toot.content}</p><hr>`;
tootsDiv.appendChild(tootDiv);
maxId = toot.id; // 更新最大 ID
});
tootsMoreButton.style.display = 'block';
} else {
tootsMoreButton.style.display = 'none';
}
} catch (error) {
console.error('获取Toots时出错:', error);
tootsMoreButton.style.display = 'none';
}
}
function tootsShowMore() {
displayToots();
}
displayToots();
// 页面加载时调用显示Toots函数
// window.onload = displayToots;
</script>
mastodon 类程序不仅可以用于微博,还可以作为评论系统,如 https://cassidyjames.com/blog/fediverse-blog-comments-mastodon/ ,这位网友同步发布 toots ,然后在博文下面引用该嘟嘟的回复内容,实现了一个很不错的评论系统。
https://github.com/cassidyjames/cassidyjames.github.io/commit/1298d9b39b9e8adeba34f23f3ae83986e0a47260
https://github.com/cassidyjames/cassidyjames.github.io/blob/1298d9b39b9e8adeba34f23f3ae83986e0a47260/_includes/comments.html
https://github.com/cassidyjames/cassidyjames.github.io/blob/main/_includes/comments.html
https://github.com/mastodon/mastodon/issues/25892
这些是 mastodon 做评论系统的相关信息,总的来说,需要一个机器人账户,获取机器人账户 read:statuses 权限的 accesstoken ,访问 /api/v1/statuses/:id/context,显示在前端网页评论区。
这是我自己的探索结果,供参考 https://www.ftls.xyz/posts/2023-08-14-mastodon-comments/
Demo
不保证长期有效。
可见这里或下面
PocketBase API
Mastodon API
Mastodon 实例 API
Mastodon 用户 ID 可使用查看用户头像 URL,如 /accounts/avatars/108/736/608/744/946/761/original/xxx.png
,中间的数字合并起来就是。 也可以使用 Mastodon web 客户端,浏览器 F12 查看请求响应信息获取。
或者 gotosocial 实例 API ,和 mastodon 很相似
由于 shortcode 一页放多个会有干扰,所以仅放参数,不保证这些参数长期有效
{{< mastodon "https://gotosocial-kkbt-tools-xkzlczgovq.cn-hangzhou.fcapp.run" "01CZ5J6DTPXEAHWZYZG73TPNH9" 3 >}}
用户 ID 注册后查看用户头像 URL 获取,或者 web 客户端查看。
本 demo 源码可以在该博客文章左下角,查看本页源码获取源码。
总结
本文介绍了一些工具,搭建微博并嵌入 Hugo 生成的博客网页。我个人尝试了 gotosocial,pocketbase 。
我使用 gotosocial api 开源程序,经过修改适配搭建了一个网页 https://www.ftls.xyz/whispers/ 同时使用 ObcsapiV4 的微信测试号/PWA web 调用 API 发布微语,Mastodon 客户端进行管理。这个方案就博客嵌入来说自由度受限,字段冗余,不过互动比较方便。使用者可根据自身需要选择不同方案。
欢迎赞赏~
赞赏