2025-04-25 10:30:26 +08:00

118 lines
3.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// app.js
// 關掉 webhook專心用 polling 模式
// 執行以下指令取消 webhook只需要做一次
// curl -F "url=" https://api.telegram.org/bot7916405163:AAGllDyNHNRTPDJ4gjwFPDi-TFDyFwD4foA/setWebhook
require('dotenv').config(); // 加這行載入 .env 檔案
const TelegramBot = require('node-telegram-bot-api');
const { connectDB, saveUser, getGroupUsers } = require('./db');
connectDB(); // 建立資料庫連線
const token = process.env.BOT_TOKEN; // 從環境變數讀取 token
//括號裡面的內容需要改為在第5步獲得的Token
const bot = new TelegramBot(token, { polling: true });
//使用Long Polling的方式與Telegram伺服器建立連線
//收到Start訊息時會觸發這段程式
bot.onText(/\/start/, function (msg) {
const chatId = msg.chat.id; //用戶的ID
const resp = '你好'; //括號裡面的為回應內容,可以隨意更改
bot.sendMessage(chatId, resp); //發送訊息的function
});
bot.onText(/\/help/, function (msg) {
const chatId = msg.chat.id;
const helpText = `
🤖 Bot 指令清單:
/help - 顯示這份幫助說明
/roll [XdY] - 擲骰指令代表x顆y面骰範例/roll 2d6表示丟兩顆六面骰
/draw [項目1, 項目2, 項目3] - 隨機抽籤,從提供的項目中選一個
/everyone - 標記群組中所有有 username 的活躍使用者(僅限群組使用)
🎲 小提醒:/roll 的最大支援為 100 顆骰,最大面數為 1000
📌 你的發話紀錄會自動儲存,以便 /everyone 使用
🛠 更多功能開發中...
`;
if (msg.from.id === 6218259358) {
const resp = '才不告訴逆雷';
bot.sendMessage(chatId, resp);
} else {
bot.sendMessage(chatId, helpText);
}
});
/**
* 骰子系統
*/
bot.onText(/\/roll(?:@[\w_]+)?(?:\s+(\d*)d(\d+))?/i, function (msg, match) {
// console.log(`✅ Bot roll`);
const chatId = msg.chat.id;
let count = parseInt(match[1]) || 1;
let sides = parseInt(match[2]) || 6;
if (count > 100 || sides > 1000) {
return bot.sendMessage(chatId, '⚠️ 數字過大,請保持理性!');
}
const rolls = Array.from({ length: count }, () => Math.floor(Math.random() * sides) + 1);
const total = rolls.reduce((sum, v) => sum + v, 0);
const resp = `🎲 ${count}d${sides} 擲出:\n🎯 ${rolls.join(' + ')} = ${total}`;
bot.sendMessage(chatId, resp);
});
/**
* 抽籤系統
*/
bot.onText(/\/draw(?:@[\w_]+)?\s*\[(.+)\]/i, function (msg, match) {
const chatId = msg.chat.id;
if (!match[1]) {
return bot.sendMessage(chatId, '⚠️ 請提供正確的選項格式,例如:/draw [香蕉, 你個, 芭樂]');
}
const options = match[1].split(',').map(o => o.trim()).filter(o => o.length > 0);
if (options.length === 0) {
return bot.sendMessage(chatId, '⚠️ 沒有有效的選項');
}
const choice = options[Math.floor(Math.random() * options.length)];
bot.sendMessage(chatId, `🎯 從 [${options.join(', ')}] 中抽出:\n👉 ${choice}`);
});
bot.onText(/\/everyone/, async (msg) => {
if (msg.chat.type !== 'group' && msg.chat.type !== 'supergroup') {
return bot.sendMessage(msg.chat.id, '⚠️ 此指令僅限群組使用');
}
const groupId = msg.chat.id;
const users = await getGroupUsers(groupId);
if (users.length === 0) {
return bot.sendMessage(groupId, '😅 沒有人講過話,無法標記');
}
const mentions = users
.filter(u => !!u.username)
.map(u => `@${u.username}`)
.join(' ');
if (!mentions) {
return bot.sendMessage(groupId, '⚠️ 沒有人有公開 username無法標記');
}
bot.sendMessage(groupId, `📣 呼叫所有人:\n${mentions}`);
});
bot.on('message', async (msg) => {
if (!msg.from || !msg.chat || !msg.chat.id || !msg.from.id) return;
if (msg.chat.type !== 'group' && msg.chat.type !== 'supergroup') return;
await saveUser(msg.from, msg.chat.id);
});