Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions Bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ const TOKEN = ENV_BOT_TOKEN;
const WEBHOOK = '/endpoint';
const SECRET = ENV_BOT_SECRET;
const ADMIN_UID = ENV_ADMIN_UID;
const REQUIRED_CHANNEL = '@QuantX';
const REQUIRED_CHANNEL_URL = 'https://t.me/QuantX';
const KV_NAMESPACE = telegrambot;
const LAST_USER_KEY = 'last_user';
const USER_MESSAGES_KEY_PREFIX = 'user_message_';
Expand Down Expand Up @@ -41,6 +43,14 @@ 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) {
const membership = await getRequiredChannelMembership(message.from.id);
if (membership !== true) {
await sendChannelRequirement(chatId, membership === null);
return;
}
}

if (chatId == ADMIN_UID) {
// 管理员消息处理
let userChatId;
Expand Down Expand Up @@ -153,6 +163,48 @@ function apiUrl(methodName) {
return `https://api.telegram.org/bot${TOKEN}/${methodName}`;
}

function hasActiveChannelMembership(chatMember) {
return ['creator', 'administrator', 'member'].includes(chatMember.status) ||
(chatMember.status === 'restricted' && chatMember.is_member === true);
}

async function getRequiredChannelMembership(userId) {
try {
const response = await fetch(apiUrl('getChatMember'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chat_id: REQUIRED_CHANNEL, user_id: userId })
});
const result = await response.json();
if (!result.ok) {
console.error('getChatMember failed:', JSON.stringify(result));
return null;
}
return hasActiveChannelMembership(result.result);
} catch (error) {
console.error('getChatMember request failed:', error);
return null;
}
}

async function sendChannelRequirement(chatId, verificationFailed = false) {
const text = verificationFailed
? '暂时无法验证频道关注状态,请稍后重新发送消息。'
: '请先关注频道 @QuantX,关注完成后返回这里重新发送消息。';
const response = await fetch(apiUrl('sendMessage'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
chat_id: chatId,
text,
reply_markup: {
inline_keyboard: [[{ text: '📢 关注 @QuantX', url: REQUIRED_CHANNEL_URL }]]
}
})
});
return response.json();
}

async function sendPlainText(chatId, text) {
const response = await fetch(apiUrl('sendMessage'), {
method: 'POST',
Expand Down
43 changes: 43 additions & 0 deletions Config/Script/Worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const TOKEN = ENV_BOT_TOKEN // Get it from @BotFather
const WEBHOOK = '/endpoint'
const SECRET = ENV_BOT_SECRET // A-Z, a-z, 0-9, _ and -
const ADMIN_UID = ENV_ADMIN_UID // your user id, get it from https://t.me/username_to_id_bot
const REQUIRED_CHANNEL = '@QuantX'
const REQUIRED_CHANNEL_URL = 'https://t.me/QuantX'

const NOTIFY_INTERVAL = 3600 * 1000;
const fraudDb = 'https://github.com/Moli-X/TelegramBot/raw/main/Date/Fraud.db';
Expand Down Expand Up @@ -106,6 +108,13 @@ async function onUpdate (update) {
* https://core.telegram.org/bots/api#message
*/
async function onMessage (message) {
if(message.chat.id.toString() !== ADMIN_UID){
const membership = await getRequiredChannelMembership(message.from.id)
if(membership !== true){
return sendChannelRequirement(message.chat.id, membership === null)
}
}

if(message.text === '/start'){
let startMsg = await fetch(startMsgUrl).then(r => r.text())
return sendMessage({
Expand Down Expand Up @@ -190,6 +199,40 @@ async function onMessage (message) {
return handleGuestMessage(message)
}

function hasActiveChannelMembership(chatMember){
return ['creator', 'administrator', 'member'].includes(chatMember.status) ||
(chatMember.status === 'restricted' && chatMember.is_member === true)
}

async function getRequiredChannelMembership(userId){
try {
const result = await requestTelegram('getChatMember', makeReqBody({
chat_id: REQUIRED_CHANNEL,
user_id: userId
}))
if(!result.ok){
console.error('getChatMember failed:', JSON.stringify(result))
return null
}
return hasActiveChannelMembership(result.result)
} catch(error) {
console.error('getChatMember request failed:', error)
return null
}
}

function sendChannelRequirement(chatId, verificationFailed = false){
return sendMessage({
chat_id: chatId,
text: verificationFailed
? '暂时无法验证频道关注状态,请稍后重新发送消息。'
: '请先关注频道 @QuantX,关注完成后返回这里重新发送消息。',
reply_markup: {
inline_keyboard: [[{ text: '📢 关注 @QuantX', url: REQUIRED_CHANNEL_URL }]]
}
})
}

async function handleGuestMessage(message){
let chatId = message.chat.id;
let isblocked = await nfd.get('isblocked-' + chatId, { type: "json" })
Expand Down