相信许多没有Telegram Premium订阅的人时常被各种各样的垃圾私聊信息骚扰,或者不方便直接和陌生人进行沟通,那么这个双向机器人部署教程于你而言就再适合不过了,它实现的功能就是通过创建聊天,可以实现一对多的聊天,支持消息、语音、表情包和视频的转发,且会标记发信者的username 你可以通过此创建一个客户支持Bot或者纯粹作为自用
下面开始教程,本教程使用Cloudflare Worker进行部署,如果每天只有几百条信息那么是免费的
首先请找到Cloudflare KV数据库,点击这里前往: https://dash.cloudflare.com/workers/kv/namespaces
创建一个名字叫telegrambot的数据库
然后打开 Cloudflare Worker ,随机创建一个Worker即可,然后点击右上角“编辑代码”可以更改Worker的脚本,将默认脚本全部删除并复制我下面的脚本粘贴并保存:
const TOKEN = ENV_BOT_TOKEN;
const WEBHOOK = '/endpoint';
const SECRET = ENV_BOT_SECRET;
const ADMIN_UID = ENV_ADMIN_UID;
const KV_NAMESPACE = telegrambot;
const LAST_USER_KEY = 'last_user';
const USER_MESSAGES_KEY_PREFIX = 'user_message_';
const ADMIN_RESPONSES_KEY_PREFIX = 'admin_response_';
addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (url.pathname === WEBHOOK) {
event.respondWith(handleWebhook(event));
} else if (url.pathname === '/registerWebhook') {
event.respondWith(registerWebhook(event, url, WEBHOOK, SECRET));
} else if (url.pathname === '/unRegisterWebhook') {
event.respondWith(unRegisterWebhook(event));
} else {
event.respondWith(new Response('No handler for this request'));
}
});
async function handleWebhook(event) {
if (event.request.headers.get('X-Telegram-Bot-Api-Secret-Token') !== SECRET) {
return new Response('Unauthorized', { status: 403 });
}
const update = await event.request.json();
event.waitUntil(onUpdate(update));
return new Response('Ok');
}
async function onUpdate(update) {
if ('message' in update) {
await onMessage(update.message);
}
}
async function onMessage(message) {
const chatId = message.chat.id;
const userName = message.from.username ? `@${message.from.username}` : message.from.first_name;
if (chatId == ADMIN_UID) {
// 处理管理员消息
let userChatId;
if (message.reply_to_message) {
const repliedMessageId = message.reply_to_message.message_id;
userChatId = await KV_NAMESPACE.get(`admin_message_${repliedMessageId}`);
if (!userChatId) {
await sendPlainText(ADMIN_UID, '无法找到要回复的用户消息。');
return;
}
} else {
// 获取最后一个活跃的用户
userChatId = await KV_NAMESPACE.get(LAST_USER_KEY);
if (!userChatId) {
await sendPlainText(ADMIN_UID, '没有最近活跃的用户会话。');
return;
}
}
// 根据管理员发送的消息类型,转发给对应的用户
let responseText = '';
if (message.photo) {
const photo = message.photo[message.photo.length - 1];
await sendPhoto(userChatId, photo.file_id);
responseText = `管理员发送了一张图片: ${photo.file_id}`;
} else if (message.sticker) {
await sendSticker(userChatId, message.sticker.file_id);
responseText = `管理员发送了一张贴纸: ${message.sticker.file_id}`;
} else if (message.voice) {
await sendVoice(userChatId, message.voice.file_id);
responseText = `管理员发送了一条语音消息: ${message.voice.file_id}`;
} else if (message.document) {
await sendDocument(userChatId, message.document.file_id);
responseText = `管理员发送了一份文件: ${message.document.file_id}`;
} else if (message.video) {
await sendVideo(userChatId, message.video.file_id);
responseText = `管理员发送了一段视频: ${message.video.file_id}`;
} else if (message.location) {
await sendLocation(userChatId, message.location.latitude, message.location.longitude);
responseText = `管理员发送了一个位置: 纬度 ${message.location.latitude}, 经度 ${message.location.longitude}`;
} else {
const text = message.text || '收到一个非文本消息';
await sendPlainText(userChatId, text);
responseText = text;
}
await KV_NAMESPACE.put(`${ADMIN_RESPONSES_KEY_PREFIX}${userChatId}`, responseText);
} else {
// 处理用户消息
let userMessageText = '';
let response;
if (message.photo) {
const photo = message.photo[message.photo.length - 1];
userMessageText = `用户发送了一张图片: ${photo.file_id}`;
response = await sendPhoto(ADMIN_UID, photo.file_id, `来自用户 ${userName} 的图片`);
} else if (message.sticker) {
userMessageText = `用户发送了一张贴纸: ${message.sticker.file_id}`;
response = await sendSticker(ADMIN_UID, message.sticker.file_id);
} else if (message.voice) {
userMessageText = `用户发送了一条语音消息: ${message.voice.file_id}`;
response = await sendVoice(ADMIN_UID, message.voice.file_id);
} else if (message.document) {
userMessageText = `用户发送了一份文件: ${message.document.file_id}`;
response = await sendDocument(ADMIN_UID, message.document.file_id);
} else if (message.video) {
userMessageText = `用户发送了一段视频: ${message.video.file_id}`;
response = await sendVideo(ADMIN_UID, message.video.file_id);
} else if (message.location) {
userMessageText = `用户发送了一个位置: 纬度 ${message.location.latitude}, 经度 ${message.location.longitude}`;
response = await sendLocation(ADMIN_UID, message.location.latitude, message.location.longitude);
} else {
const text = message.text || '用户发送了非文本消息';
userMessageText = text;
response = await sendPlainText(ADMIN_UID, `来自用户 ${userName} 的消息:\n${text}`);
}
// 保存管理员消息ID与用户聊天ID的映射
if (response && response.result && response.result.message_id) {
const adminMessageId = response.result.message_id;
await KV_NAMESPACE.put(`admin_message_${adminMessageId}`, chatId.toString());
}
await KV_NAMESPACE.put(`${USER_MESSAGES_KEY_PREFIX}${chatId}`, userMessageText);
// 更新最后一个活跃的用户
await KV_NAMESPACE.put(LAST_USER_KEY, chatId.toString());
}
}
function apiUrl(methodName) {
return `https://api.telegram.org/bot${TOKEN}/${methodName}`;
}
async function sendPlainText(chatId, text) {
const response = await fetch(apiUrl('sendMessage'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chat_id: chatId, text })
});
return response.json();
}
async function sendSticker(chatId, fileId) {
const response = await fetch(apiUrl('sendSticker'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chat_id: chatId, sticker: fileId })
});
return response.json();
}
async function sendPhoto(chatId, fileId, caption = '') {
const response = await fetch(apiUrl('sendPhoto'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chat_id: chatId, photo: fileId, caption })
});
return response.json();
}
async function sendVoice(chatId, fileId) {
const response = await fetch(apiUrl('sendVoice'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chat_id: chatId, voice: fileId })
});
return response.json();
}
async function sendDocument(chatId, fileId) {
const response = await fetch(apiUrl('sendDocument'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chat_id: chatId, document: fileId })
});
return response.json();
}
async function sendVideo(chatId, fileId) {
const response = await fetch(apiUrl('sendVideo'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chat_id: chatId, video: fileId })
});
return response.json();
}
async function sendLocation(chatId, latitude, longitude) {
const response = await fetch(apiUrl('sendLocation'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chat_id: chatId, latitude, longitude })
});
return response.json();
}
async function registerWebhook(event, requestUrl, suffix, secret) {
const webhookUrl = `${requestUrl.protocol}//${requestUrl.hostname}${suffix}`;
const response = await fetch(apiUrl('setWebhook'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url: webhookUrl, secret_token: secret })
});
const r = await response.json();
return new Response('ok' in r && r.ok ? 'Ok' : JSON.stringify(r, null, 2));
}
async function unRegisterWebhook(event) {
const response = await fetch(apiUrl('setWebhook'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url: '' })
});
const r = await response.json();
return new Response('ok' in r && r.ok ? 'Ok' : JSON.stringify(r, null, 2));
}可以看到上面的代码有三个变量 **你必须要更改的,分别是
ENV_BOT_SECRET ENV_BOT_TOKEN 和 ENV_ADMIN_UID**
让我们一个个来,请转到 Worker设置——变量和机密——添加+
类型请选择 文本 ,变量名称就先是 ENV_BOT_SECRET
然后访问这个网站: https://www.uuidgenerator.net/ 然后点击生成一个uuid,填写到值里面去,这个任意uuid都行,不重要
然后重复步骤,添加变量 ENV_BOT_TOKEN ,去Telegram的Bot Father里: https://t.me/botfather 自己创建一个机器人,自己取username并命名,然后拿到Token 填到值里面,以后这个就是你的双向机器人了
最后再重复一次步骤,添加变量 ENV_ADMIN_UID ,这个就是你自己的uid了,不知道怎么获取的话用这个bot: https://t.me/GetIDcnBot
获取到的ID填写进值里面
最后,访问一下你的Worker URL,设置Webhook,填入你的Worker URL并在结尾加上/registerWebhook
例如:https://example.workers.dev/registerWebhook
页面返回OK字样设置就成功了
常见问题
其实Telegram上也有双向机器人,但我不推荐使用,因为上面的代码只是执行了简单逻辑让消息互通,并让每个聊天独立,如果可以的话,一些不怀好意的人完全可以直接在服务器上部署,然后写日志或者保存到数据库里,默认监听你所有的聊天,这样就没有隐私了,自己部署终归还是好一些的
另外和第三方TG客户端一样,一些坏双向机器人可能会在你给朋友转账的时候“掉包”收款地址、甚至收款二维码,这些只要想都能做到,所以还是很危险的
希望这篇教程对你有帮助!
评论 (0)