长毛象新通知推送TGBot
其实蜗牛哥之前开发过一个Chrome扩展,可以在浏览器里显示一个图标和通知数量。但是我电脑上现在Chrome一打开十几个进程,我实在不想再新增扩展了。
所以这两天用Deepseek糊了一个搭配Cloudflare推送到TGBot的Worker脚本,效果如截图。设置好长毛象和TGBot的设置后,程序会每5分钟检测一次有没有新通知,有的话才进行推送操作。

准备KV
先添加一个KV,名称 KV_STORE
,备用。
准备长毛象TOken
获取长毛象Access Token,不放心的话在权限部分可以单独只设置通知获取权限
- 登录你的 Mastodon 实例(如 https://mastodon.social)。
- 进入 "Preferences(偏好设置) > Development(开发)(或直接访问 https:///settings/applications)。
- 点击 "New Application(新建应用):
- Application Name(应用名称):填写你的应用名称(如 MyBot)。
- Website(网站)(可选):填写你的应用网站(如果没有可留空)。
- Scopes(权限):选择你需要的 API 权限(如 read、write、follow 等)。
- 点击 "Submit(提交),系统会生成:
- Client Key(客户端 ID)
- Client Secret(客户端密钥)
- Access Token(访问令牌)(可直接使用)
准备Cloudflare Worker
再添加一个Worker,代码如下,并修改代码中的 config
部分的配置为你自己的设置,其中长毛象token
// 配置部分
const config = {
// Mastodon 配置
mastodon: {
instance: 'https://your-instance.social', // 替换为你的 Mastodon 实例地址
accessToken: 'ZTDJN2ZMZMZI5MTU1MZHH', // 替换为你的 Mastodon 访问令牌
lastNotificationIdKey: 'last_notification_id' // KV 存储中保存最后通知ID的键名
},
// Telegram 配置
telegram: {
botToken: 'your-bot-token', // 替换为你的 Telegram Bot Token
chatId: 'your-tg-chart-id' // 替换为接收消息的聊天ID
},
// 检查间隔(分钟)
checkInterval: 5
};
// 主处理函数
export default {
async scheduled(event, env, ctx) {
// 执行检查通知任务
await checkNotifications(env);
},
async fetch(request, env) {
// 手动触发检查
if (new URL(request.url).pathname === '/check') {
await checkNotifications(env);
return new Response('Notification check triggered');
}
return new Response('Not found', { status: 404 });
}
};
// 检查未读通知
async function checkNotifications(env) {
try {
// 获取上次处理的通知ID
let lastNotificationId = await env.KV_STORE.get(config.mastodon.lastNotificationIdKey);
lastNotificationId = lastNotificationId || '0';
// 获取新通知
const notifications = await fetchMastodonNotifications(lastNotificationId);
if (notifications.length > 0) {
// 有新通知,发送到 Telegram
await sendToTelegram(notifications, env);
// 更新最后处理的通知ID
const latestId = notifications[0].id;
await env.KV_STORE.put(config.mastodon.lastNotificationIdKey, latestId);
console.log(`Sent ${notifications.length} new notifications to Telegram. Latest ID: ${latestId}`);
} else {
console.log('No new notifications.');
}
} catch (error) {
console.error('Error checking notifications:', error);
}
}
// 从 Mastodon 获取通知
async function fetchMastodonNotifications(sinceId) {
const url = new URL(`${config.mastodon.instance}/api/v1/notifications`);
url.searchParams.append('exclude_types[]', 'follow');
url.searchParams.append('exclude_types[]', 'follow_request');
url.searchParams.append('since_id', sinceId);
const response = await fetch(url.toString(), {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
'Authorization': `Bearer ${config.mastodon.accessToken}`
}
});
if (!response.ok) {
throw new Error(`Mastodon API error: ${response.status} ${response.statusText}`);
}
return await response.json();
}
// 发送通知到 Telegram
async function sendToTelegram(notifications, env) {
// 按时间倒序排列通知
notifications.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
let message = `📨 你有 ${notifications.length} 条新通知:\n\n`;
notifications.forEach(notification => {
const sender = notification.account; // 通知发起者
const senderName = sender.display_name || sender.username;
const senderHandle = `@${sender.acct}`;
const senderUrl = sender.url;
// 根据不同通知类型构建不同消息
switch(notification.type) {
case 'mention':
const mentionContent = stripHTML(notification.status.content);
message += `💬 <b>${senderName}</b> (${senderHandle}) 提到了你:\n${mentionContent}\n\n`;
break;
case 'reply':
const replyContent = stripHTML(notification.status.content);
message += `↩️ <b>${senderName}</b> (${senderHandle}) 回复了你:\n${replyContent}\n\n`;
break;
case 'reblog':
const reblogContent = notification.status
? stripHTML(notification.status.content)
: "[内容不可用]";
message += `🔁 <b>${senderName}</b> (${senderHandle}) 转发了你的嘟文:\n${reblogContent}\n\n`;
break;
case 'favourite':
const favContent = notification.status
? stripHTML(notification.status.content)
: "[内容不可用]";
message += `⭐ <b>${senderName}</b> (${senderHandle}) 喜欢了你的嘟文:\n${favContent}\n\n`;
break;
case 'poll':
message += `📊 <b>${senderName}</b> (${senderHandle}) 的投票已结束\n`;
break;
case 'follow':
message += `👤 <b>${senderName}</b> (${senderHandle}) 关注了你\n`;
break;
case 'follow_request':
message += `🫂 <b>${senderName}</b> (${senderHandle}) 请求关注你\n`;
break;
default:
message += `ℹ️ 你有一条新通知 (${notification.type}) 来自 <b>${senderName}</b>\n`;
}
});
// 添加来源链接
message += `\n查看所有通知: ${config.mastodon.instance}/notifications`;
// 发送到 Telegram
const url = `https://api.telegram.org/bot${config.telegram.botToken}/sendMessage`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
chat_id: config.telegram.chatId,
text: message,
disable_web_page_preview: true,
parse_mode: 'HTML'
})
});
if (!response.ok) {
throw new Error(`Telegram API error: ${response.status} ${response.statusText}`);
}
}
// 去除 HTML 标签
function stripHTML(html) {
return html.replace(/<[^>]*>?/gm, '');
}
配置KV和定时执行
去Cloudflare Worker设置页面绑定KV和设置定时执行。

除了定时执行外,你还可以用 https://wokrerurl.dev/check 手动触发