Upload 4 files
Browse files- Dockerfile +7 -0
- README.md +35 -0
- bot.js +1315 -0
- package.json +9 -0
Dockerfile
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM node:18-slim
|
| 2 |
+
WORKDIR /app
|
| 3 |
+
COPY package.json ./
|
| 4 |
+
RUN npm install
|
| 5 |
+
COPY . .
|
| 6 |
+
EXPOSE 7860
|
| 7 |
+
CMD ["node", "bot.js"]
|
README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: TikTok Radar v11
|
| 3 |
+
emoji: ๐ก
|
| 4 |
+
colorFrom: purple
|
| 5 |
+
colorTo: blue
|
| 6 |
+
sdk: docker
|
| 7 |
+
app_port: 7860
|
| 8 |
+
pinned: false
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
# ๐ก TikTok Radar v11.0 - ุงููุณุฎุฉ ุงูู
ุญุณููุฉ
|
| 12 |
+
|
| 13 |
+
## ุงูู
ู
ูุฒุงุช ุงูุฌุฏูุฏุฉ:
|
| 14 |
+
- โ
ุฃุณู
ุงุก ุงููุฏุงูุง ุจุงูุนุฑุจู (200+ ูุฏูุฉ)
|
| 15 |
+
- โ
ุตูุงุฏูู ูุญูุงุฆุจ ุงูุนู
ูุงุช ู
ุน ุงููุงุฆุฒูู (ุงูุงุณู
+ ุงูููุฒุฑููู
+ ุนุฏุฏ ุงูุนู
ูุงุช)
|
| 16 |
+
- โ
ุงูุชุนูููุงุช ู
ุน ุนุฑุถ ุฃุบูุจ ุงูุฑุณุงุฆู ููู ู
ุนูู
|
| 17 |
+
- โ
ุญุฐู ุชููุงุฆู ููุฑุณุงุฆู ุงูุณุงุจูุฉ ุนูุฏ ุงูุถุบุท ุนูู ุฒุฑ ุฌุฏูุฏ
|
| 18 |
+
- โ
ุชูุธูู ุงูุฐุงูุฑุฉ ูู 50 ุฏูููุฉ ูู
ูุน ุงูุซูู
|
| 19 |
+
- โ
ุชุบููุฑ ุงูู
ุฐูุน ู
ู ุชูููุฑุงู
: `/change username`
|
| 20 |
+
- โ
ููุงุฉ ุชูููุฑุงู
ุซุงููุฉ: `/channel2 CHAT_ID`
|
| 21 |
+
- โ
ุชุตู
ูู
ูุฎู
ูุงุญุชุฑุงูู ู
ุน ุฑุชุจ ุนุฑุจูุฉ
|
| 22 |
+
|
| 23 |
+
## ุงูุฃูุงู
ุฑ:
|
| 24 |
+
- `/change username` ุฃู `/ุบูุฑ username` - ุชุบููุฑ ุงูู
ุฐูุน ุงูู
ุฑุงูุจ
|
| 25 |
+
- `/channel2 CHAT_ID` ุฃู `/ููุงุฉ CHAT_ID` - ุชุนููู ููุงุฉ ุซุงููุฉ
|
| 26 |
+
- `/status` ุฃู `/ุญุงูุฉ` - ุนุฑุถ ุญุงูุฉ ุงูุจูุช
|
| 27 |
+
- `/clear` ุฃู `/ู
ุณุญ` - ู
ุณุญ ุงูุฅุญุตุงุฆูุงุช
|
| 28 |
+
|
| 29 |
+
## ุงูู
ุชุบูุฑุงุช ุงูู
ุทููุจุฉ (Secrets):
|
| 30 |
+
- `TIKTOK_USERNAME` - ููุฒุฑููู
ุงูู
ุฐูุน
|
| 31 |
+
- `TELEGRAM_TOKEN` - ุชููู ุจูุช ุชูููุฑุงู
|
| 32 |
+
- `TELEGRAM_CHAT_ID` - ู
ุนุฑู ุงูููุงุฉ/ุงูุดุงุช
|
| 33 |
+
- `SESSION_ID` - (ุงุฎุชูุงุฑู) ุณูุดู ุชูู ุชูู
|
| 34 |
+
- `SIGN_API_KEY` - (ุงุฎุชูุงุฑู) ู
ูุชุงุญ API
|
| 35 |
+
- `TELEGRAM_CHAT_ID_2` - (ุงุฎุชูุงุฑู) ููุงุฉ ุซุงููุฉ
|
bot.js
ADDED
|
@@ -0,0 +1,1315 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 3 |
+
* โ โ
|
| 4 |
+
* โ ๐ฏ TikTok Radar Ultimate v11.0 - ุงููุณุฎุฉ ุงูู
ุญุณููุฉ ๐ฏ โ
|
| 5 |
+
* โ โ
|
| 6 |
+
* โ โ
ุฃุณู
ุงุก ุงููุฏุงูุง ุจุงูุนุฑุจู โข ุตูุงุฏูู ูุญูุงุฆุจ ู
ุน ุงููุงุฆุฒูู โ
|
| 7 |
+
* โ โ
ุชุนูููุงุช ู
ุน ุฃุบูุจ ุงูุฑุณุงุฆู โข ุญุฐู ุชููุงุฆู ููุฑุณุงุฆู ุงูุณุงุจูุฉ โ
|
| 8 |
+
* โ โ
ุชุฎุฒูู ูู 50 ุฏูููุฉ โข ุชุบููุฑ ุงูู
ุฐูุน ู
ู ุชูููุฑุงู
โข ููุงุฉ ุซุงููุฉ โ
|
| 9 |
+
* โ โ
|
| 10 |
+
* โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 11 |
+
*/
|
| 12 |
+
|
| 13 |
+
const http = require('http');
|
| 14 |
+
const axios = require('axios');
|
| 15 |
+
|
| 16 |
+
process.env.WHITELIST_AUTHENTICATED_SESSION_ID_HOST = 'tiktok.eulerstream.com';
|
| 17 |
+
const PORT = process.env.PORT || 7860;
|
| 18 |
+
|
| 19 |
+
// โโโโโโโโโโโโโโโโโโโโโโโ CONFIG โโโโโโโโโโโโโโโโโโโโโโโ
|
| 20 |
+
const CONFIG = {
|
| 21 |
+
TIKTOK_USERNAME: (process.env.TIKTOK_USERNAME || 'a200_89').trim(),
|
| 22 |
+
SESSION_ID: (process.env.SESSION_ID || '').trim(),
|
| 23 |
+
TT_TARGET_IDC: (process.env.TT_TARGET_IDC || 'alisg').trim(),
|
| 24 |
+
TELEGRAM_TOKEN: (process.env.TELEGRAM_TOKEN || '').trim(),
|
| 25 |
+
TELEGRAM_CHAT_ID: (process.env.TELEGRAM_CHAT_ID || '').trim(),
|
| 26 |
+
TELEGRAM_CHAT_ID_2: (process.env.TELEGRAM_CHAT_ID_2 || '').trim(),
|
| 27 |
+
PROXY_URL: (process.env.PROXY_URL || '').trim().replace(/\/$/, ''),
|
| 28 |
+
SIGN_API_KEY: (process.env.SIGN_API_KEY || '').trim(),
|
| 29 |
+
REPORT_INTERVAL: parseInt(process.env.REPORT_INTERVAL || '10'),
|
| 30 |
+
};
|
| 31 |
+
|
| 32 |
+
// โโโโโโโโโโโโโโโโโโโโโโโ ุฃุณู
ุงุก ุงููุฏุงูุง ุจุงูุนุฑุจู โโโโโโโโโโโโโโโโโโโโโโโ
|
| 33 |
+
const GIFT_NAMES_AR = {
|
| 34 |
+
'Rose': 'ูุฑุฏุฉ ๐น', 'rose': 'ูุฑุฏุฉ ๐น', 'Finger Heart': 'ููุจ ุจุงูุฅุตุจุน ๐ค',
|
| 35 |
+
'GG': 'ุฌู ุฌู ๐ฎ', 'Ice Cream Cone': 'ุขูุณ ูุฑูู
๐ฆ', 'Doughnut': 'ุฏููุงุช ๐ฉ',
|
| 36 |
+
'TikTok': 'ุชูู ุชูู โช', 'Love you': 'ุฃุญุจู ๐', 'Confetti': 'ูุตุงุตุงุช ู
ูููุฉ ๐',
|
| 37 |
+
'Hand Heart': 'ููุจ ุจุงููุฏ ๐', 'Heart Me': 'ููุจูู โค๏ธ', 'Tiny Diny': 'ุชุงููู ุฏููู ๐ฃ',
|
| 38 |
+
'Cheer You Up': 'ุงุจุชุณู
๐', 'Sunglasses': 'ูุธุงุฑุงุช ุดู
ุณูุฉ ๐', 'Hearts': 'ูููุจ ๐',
|
| 39 |
+
'Butterfly': 'ูุฑุงุดุฉ ๐ฆ', 'Star': 'ูุฌู
ุฉ โญ', 'Galaxy': 'ู
ุฌุฑุฉ ๐',
|
| 40 |
+
'Universe': 'ููู ๐', 'Lion': 'ุฃุณุฏ ๐ฆ', 'Interstellar': 'ุจูู ุงููุฌูู
โจ',
|
| 41 |
+
'Concert': 'ุญููุฉ ๐ต', 'Garland': 'ุฅูููู ๐', 'Superstar': 'ุณูุจุฑ ุณุชุงุฑ โญ',
|
| 42 |
+
'Drama Queen': 'ุฏุฑุงู
ุง ูููู ๐', 'Cap': 'ูุจุนุฉ ๐งข', 'Perfume': 'ุนุทุฑ ๐ซ',
|
| 43 |
+
'Mic': 'ู
ุงูู ๐ค', 'Paper Crane': 'ุทุงุฆุฑ ูุฑูู ๐ฆข', 'Little Crown': 'ุชุงุฌ ุตุบูุฑ ๐',
|
| 44 |
+
'Lollipop': 'ู
ุตุงุตุฉ ๐ญ', 'Lucky Cat': 'ูุทุฉ ุงูุญุธ ๐ฑ', 'Love': 'ุญุจ โค๏ธ',
|
| 45 |
+
'Horseshoe': 'ุญุฏูุฉ ุญุตุงู ๐ด', 'Gift Box': 'ุตูุฏูู ูุฏูุฉ ๐', 'Roses': 'ูุฑูุฏ ๐น',
|
| 46 |
+
'Bear': 'ุฏุจ ๐ป', 'Teddy Bear': 'ุฏุจุฏูุจ ๐งธ', 'Wish': 'ุฃู
ููุฉ ๐ ',
|
| 47 |
+
'Finger': 'ุฅุตุจุน โ๏ธ', 'Sending Strength': 'ููุฉ ๐ช', 'Hot Air Balloon': 'ู
ูุทุงุฏ ๐',
|
| 48 |
+
'Gold Mine': 'ู
ูุฌู
ุฐูุจ โ๏ธ', 'Thumbs Up': 'ุฅุนุฌุงุจ ๐', 'Applause': 'ุชุตููู ๐',
|
| 49 |
+
'Disco Ball': 'ูุฑุฉ ุฏูุณูู ๐ชฉ', 'Money Gun': 'ู
ุณุฏุณ ูููุณ ๐ฐ', 'Gem Gun': 'ู
ุณุฏุณ ู
ุงุณุงุช ๐',
|
| 50 |
+
'Race Car': 'ุณูุงุฑุฉ ุณุจุงู ๐๏ธ', 'Sports Car': 'ุณูุงุฑุฉ ุฑูุงุถูุฉ ๐', 'Gaming Chair': 'ูุฑุณู ููู
ูู ๐ช',
|
| 51 |
+
'Jet': 'ุทุงุฆุฑุฉ โ๏ธ', 'Private Jet': 'ุทุงุฆุฑุฉ ุฎุงุตุฉ โ๏ธ', 'Yacht': 'ูุฎุช ๐ฅ๏ธ',
|
| 52 |
+
'Castle': 'ููุนุฉ ๐ฐ', 'Kingdom': 'ู
ู
ููุฉ ๐', 'Crown': 'ุชุงุฌ ๐',
|
| 53 |
+
'Diamond': 'ู
ุงุณุฉ ๐', 'Lightning Bolt': 'ุตุงุนูุฉ โก', 'Phoenix': 'ุทุงุฆุฑ ุงูููููู ๐ฅ',
|
| 54 |
+
'Dragon': 'ุชููู ๐', 'Elephant': 'ููู ๐', 'Corgi': 'ููุจ ููุฑุฌู ๐',
|
| 55 |
+
'Duck': 'ุจุทุฉ ๐ฆ', 'Cat': 'ูุทุฉ ๐ฑ', 'Panda': 'ุจุงูุฏุง ๐ผ',
|
| 56 |
+
'Penguin': 'ุจุทุฑูู ๐ง', 'Whale': 'ุญูุช ๐', 'Dolphin': 'ุฏูููู ๐ฌ',
|
| 57 |
+
'Shark': 'ูุฑุด ๐ฆ', 'Unicorn': 'ููููููุฑู ๐ฆ', 'Pearl Necklace': 'ุนูุฏ ูุคูุค ๐ฟ',
|
| 58 |
+
'Ring': 'ุฎุงุชู
๐', 'Couple Ring': 'ุฎุงุชู
ุฒูุฌูู ๐', 'Wedding Ring': 'ุฎุงุชู
ุฒูุงุฌ ๐',
|
| 59 |
+
'Bracelet': 'ุณูุงุฑ โ', 'Watch': 'ุณุงุน๏ฟฝ๏ฟฝ โ', 'Flower': 'ุฒูุฑุฉ ๐ธ',
|
| 60 |
+
'Bouquet': 'ุจุงูุฉ ูุฑุฏ ๐', 'Cake': 'ูููุฉ ๐', 'Pizza': 'ุจูุชุฒุง ๐',
|
| 61 |
+
'Popcorn': 'ูุดุงุฑ ๐ฟ', 'Coffee': 'ูููุฉ โ', 'Boba Tea': 'ุดุงู ุจูุจุง ๐ง',
|
| 62 |
+
'Champagne': 'ุดุงู
ุจุงููุง ๐ฅ', 'Cocktail': 'ูููุชูู ๐น', 'Fireworks': 'ุฃูุนุงุจ ูุงุฑูุฉ ๐',
|
| 63 |
+
'Rocket': 'ุตุงุฑูุฎ ๐', 'UFO': 'ุทุจู ุทุงุฆุฑ ๐ธ', 'Moon': 'ูู
ุฑ ๐',
|
| 64 |
+
'Sun': 'ุดู
ุณ โ๏ธ', 'Rainbow': 'ููุณ ูุฒุญ ๐', 'Snowman': 'ุฑุฌู ุซูุฌ โ',
|
| 65 |
+
'Cherry Blossom': 'ุฒูุฑ ุงููุฑุฒ ๐ธ', 'Lock & Key': 'ููู ูู
ูุชุงุญ ๐',
|
| 66 |
+
'Money Tree': 'ุดุฌุฑุฉ ูููุณ ๐ณ', 'Lucky Box': 'ุตูุฏูู ุงูุญุธ ๐',
|
| 67 |
+
'Treasure Chest': 'ุตูุฏูู ููุฒ ๐ฆ', 'Gold Coin': 'ุนู
ูุฉ ุฐูุจูุฉ ๐ช',
|
| 68 |
+
'Coin Bag': 'ุญููุจุฉ ุนู
ูุงุช ๐ฐ', 'Scepter': 'ุตููุฌุงู ๐', 'Magic Wand': 'ุนุตุง ุณุญุฑูุฉ ๐ช',
|
| 69 |
+
'Trophy': 'ูุฃุณ ๐', 'Medal': 'ู
ูุฏุงููุฉ ๐
', 'Champion': 'ุจุทู ๐',
|
| 70 |
+
'First Place': 'ุงูู
ุฑูุฒ ุงูุฃูู ๐ฅ', 'Second Place': 'ุงูู
ุฑูุฒ ุงูุซุงูู ๐ฅ',
|
| 71 |
+
'Third Place': 'ุงูู
ุฑูุฒ ุงูุซุงูุซ ๐ฅ', 'Goat': 'ุงูุฃูุถู ๐',
|
| 72 |
+
'Guitar': 'ุฌูุชุงุฑ ๐ธ', 'Piano': 'ุจูุงูู ๐น', 'Drum': 'ุทุจู ๐ฅ',
|
| 73 |
+
'Headphones': 'ุณู
ุงุนุงุช ๐ง', 'Microphone': 'ู
ุงููุฑูููู ๐ค',
|
| 74 |
+
'Camera': 'ูุงู
ูุฑุง ๐ท', 'Movie': 'ููู
๐ฌ', 'Ticket': 'ุชุฐูุฑุฉ ๐๏ธ',
|
| 75 |
+
'Balloon': 'ุจุงููู ๐', 'Party': 'ุญููุฉ ๐ฅณ', 'Birthday': 'ุนูุฏ ู
ููุงุฏ ๐',
|
| 76 |
+
'Graduation': 'ุชุฎุฑุฌ ๐', 'Coin': 'ุนู
ูุฉ ๐ช', 'Money Bag': 'ููุณ ูููุฏ ๐ฐ',
|
| 77 |
+
'Dollar': 'ุฏููุงุฑ ๐ต', 'Credit Card': 'ุจุทุงูุฉ ๐ณ', 'Gem Stone': 'ุญุฌุฑ ูุฑูู
๐',
|
| 78 |
+
'Pearl': 'ูุคูุคุฉ ๐ซง', 'Leaf': 'ูุฑูุฉ ุดุฌุฑ ๐', 'Clover': 'ุจุฑุณูู
๐',
|
| 79 |
+
'Sunflower': 'ุนุจุงุฏ ุงูุดู
ุณ ๐ป', 'Lotus': 'ููุชุณ ๐ชท', 'Hug': 'ุญุถู ๐ค',
|
| 80 |
+
'Kiss': 'ูุจูุฉ ๐', 'Clap': 'ุชุตููู ๐', 'Pray': 'ุฏุนุงุก ๐',
|
| 81 |
+
'Flex': 'ุนุถูุงุช ๐ช', 'Peace': 'ุณูุงู
โ๏ธ', 'OK': 'ุฃููู ๐',
|
| 82 |
+
'Fist': 'ูุจุถุฉ ๐', 'Handshake': 'ู
ุตุงูุญุฉ ๐ค', 'Heart Eyes': 'ุนููู ููุจ ๐',
|
| 83 |
+
};
|
| 84 |
+
|
| 85 |
+
function getArabicGiftName(en) {
|
| 86 |
+
if (!en) return 'ูุฏูุฉ ๐';
|
| 87 |
+
if (GIFT_NAMES_AR[en]) return GIFT_NAMES_AR[en];
|
| 88 |
+
const lower = en.toLowerCase();
|
| 89 |
+
for (const [k, v] of Object.entries(GIFT_NAMES_AR)) {
|
| 90 |
+
if (k.toLowerCase() === lower) return v;
|
| 91 |
+
if (lower.includes(k.toLowerCase()) || k.toLowerCase().includes(lower)) return v;
|
| 92 |
+
}
|
| 93 |
+
return `${en} ๐`;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
// โโโโโโโโโโโโโโโโโโโโโโโ STATE โโโโโโโโโโโโโโโโโโโโโโโ
|
| 97 |
+
let isConnected = false, tiktokConnection = null;
|
| 98 |
+
let totalGifts = 0, totalDiamonds = 0, totalLikes = 0, totalComments = 0;
|
| 99 |
+
let totalFollows = 0, totalShares = 0, totalSuperFans = 0, totalQuestions = 0;
|
| 100 |
+
let totalEnvelopes = 0, totalEmotes = 0;
|
| 101 |
+
let maxViewers = 0, currentViewers = 0;
|
| 102 |
+
let startTime = null;
|
| 103 |
+
|
| 104 |
+
// Maps - ุงูุขู ู
ุน ุชุฎุฒูู ุงูุฑุณุงุฆู ูุงููุฏุงูุง
|
| 105 |
+
let giftersMap = {}; // { uid: { name, username, coins, count, gifts: [] } }
|
| 106 |
+
let followersMap = {}; // { uid: { name, username, time } }
|
| 107 |
+
let chattersMap = {}; // { uid: { name, username, count, messages: [] } }
|
| 108 |
+
let sharersMap = {}; // { uid: { name, username, count } }
|
| 109 |
+
let likersMap = {}; // { uid: { name, username, count } }
|
| 110 |
+
|
| 111 |
+
// ุงูุตูุงุฏูู ูุงูุญูุงุฆุจ ู
ุน ุงููุงุฆุฒูู
|
| 112 |
+
let envelopeWinners = []; // { type, sender, senderUsername, diamonds, peopleCount, winners: [{name, username, coins}], time }
|
| 113 |
+
|
| 114 |
+
let questionsArr = [], pinnedMessages = [];
|
| 115 |
+
let reconnectTimer = null, reportInterval = null, flushInterval = null;
|
| 116 |
+
let roomTitle = '';
|
| 117 |
+
|
| 118 |
+
// ุฑุณุงุฆู ู
ุฑุณูุฉ ููุญุฐู
|
| 119 |
+
let lastMenuMsgId = null;
|
| 120 |
+
let lastReportMsgId = null;
|
| 121 |
+
let lastDetailMsgIds = [];
|
| 122 |
+
|
| 123 |
+
// PK
|
| 124 |
+
let pkActive = false, pkInfo = {
|
| 125 |
+
battleId: '', participantDetails: [], ourScore: 0, theirScore: 0,
|
| 126 |
+
startTime: null, pkGifts: {},
|
| 127 |
+
};
|
| 128 |
+
|
| 129 |
+
// โโโโโโโโโโโโโโโโโโโโโโโ UTILS โโโโโโโโโโโโโโโโโโโโโโโ
|
| 130 |
+
function esc(t) { return t ? String(t).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>') : ''; }
|
| 131 |
+
function formatK(n) { n = Number(n) || 0; return n >= 1e6 ? (n / 1e6).toFixed(1) + 'M' : n >= 1e3 ? (n / 1e3).toFixed(1) + 'K' : n.toString(); }
|
| 132 |
+
function dur(s) { if (!s) return '00:00:00'; const d = Math.floor((Date.now() - s.getTime()) / 1000); return `${String(Math.floor(d / 3600)).padStart(2, '0')}:${String(Math.floor((d % 3600) / 60)).padStart(2, '0')}:${String(d % 60).padStart(2, '0')}`; }
|
| 133 |
+
function getTime() { return new Date().toLocaleString('ar-IQ', { timeZone: 'Asia/Baghdad', hour: '2-digit', minute: '2-digit', hour12: true }); }
|
| 134 |
+
function getDate() { return new Date().toLocaleString('ar-IQ', { timeZone: 'Asia/Baghdad', year: 'numeric', month: '2-digit', day: '2-digit' }); }
|
| 135 |
+
const LIVE = () => `https://www.tiktok.com/@${CONFIG.TIKTOK_USERNAME}/live`;
|
| 136 |
+
|
| 137 |
+
const medals = ['๐ฅ', '๐ฅ', '๐ฅ', '๐
', '๐๏ธ', 'โญ', 'โจ', '๐ซ', '๐', 'โก'];
|
| 138 |
+
const ranks = ['ุงูุฃูู', 'ุงูุซุงูู', 'ุงูุซุงูุซ', 'ุงูุฑุงุจุน', 'ุงูุฎุงู
ุณ', 'ุงูุณุงุฏุณ', 'ุงูุณุงุจุน', 'ุงูุซุงู
ู', 'ุงูุชุงุณุน', 'ุงูุนุงุดุฑ'];
|
| 139 |
+
|
| 140 |
+
// โโโโโโโโโโโโโโโโโโโโโโโ ENVELOPE HELPERS โโโโโโโโโโโโโโโโโโโโโโโ
|
| 141 |
+
function extractWinners(data) {
|
| 142 |
+
const winners = [];
|
| 143 |
+
if (!data) return winners;
|
| 144 |
+
|
| 145 |
+
// ุงูุจุญุซ ูู ูู ุงูู
ูุงูุน ุงูู
ู
ููุฉ ูููุงุฆุฒูู
|
| 146 |
+
const possibleLists = [
|
| 147 |
+
data.envelopeGrabUserList,
|
| 148 |
+
data.grabUserList,
|
| 149 |
+
data.winnerList,
|
| 150 |
+
data.winners,
|
| 151 |
+
data.envelopeGrabRecordList,
|
| 152 |
+
data.grabRecordList,
|
| 153 |
+
data.userList,
|
| 154 |
+
data.envelopeInfo?.envelopeGrabUserList,
|
| 155 |
+
data.envelopeInfo?.grabUserList,
|
| 156 |
+
data.envelopeInfo?.winners,
|
| 157 |
+
data.treasureBoxData?.winners,
|
| 158 |
+
data.goodyBagData?.winners,
|
| 159 |
+
];
|
| 160 |
+
|
| 161 |
+
for (const list of possibleLists) {
|
| 162 |
+
if (Array.isArray(list) && list.length > 0) {
|
| 163 |
+
for (const w of list) {
|
| 164 |
+
if (w) {
|
| 165 |
+
winners.push({
|
| 166 |
+
name: w.nickname || w.nickName || w.userName || w.name || w.uniqueId || w.unique_id || '?',
|
| 167 |
+
username: w.uniqueId || w.unique_id || w.userId || '',
|
| 168 |
+
coins: w.diamondCount || w.coinCount || w.coins || w.grabDiamond || w.amount || w.value || 0,
|
| 169 |
+
});
|
| 170 |
+
}
|
| 171 |
+
}
|
| 172 |
+
break; // ุชููู ุนูุฏ ุฅูุฌุงุฏ ูุงุฆู
ุฉ
|
| 173 |
+
}
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
return winners;
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
function updateLastEnvelopeWithWinners(winners) {
|
| 180 |
+
if (winners.length === 0) return;
|
| 181 |
+
|
| 182 |
+
console.log(`[๐ฆ WINNERS FOUND!] ${winners.length} winners:`, winners.map(w => `${w.name}(${w.coins})`).join(', '));
|
| 183 |
+
|
| 184 |
+
// ุชุญุฏูุซ ุขุฎุฑ ุตูุฏูู ุจุงููุงุฆุฒูู
|
| 185 |
+
if (envelopeWinners.length > 0) {
|
| 186 |
+
const lastEnv = envelopeWinners[envelopeWinners.length - 1];
|
| 187 |
+
// ููุท ุฅุฐุง ูู
ููู ูุฏูู ูุงุฆุฒูู ุจุงููุนู
|
| 188 |
+
if (!lastEnv.winners || lastEnv.winners.length === 0) {
|
| 189 |
+
lastEnv.winners = winners;
|
| 190 |
+
|
| 191 |
+
// ุฅุฑุณุงู ุชุญุฏูุซ ุจุงููุงุฆุฒูู
|
| 192 |
+
const typeIcon = lastEnv.type === 'coinbag' ? '๐ฐ' : '๐ฆ';
|
| 193 |
+
const typeName = lastEnv.type === 'coinbag' ? 'ุญููุจุฉ ุงูุนู
ูุงุช' : 'ุตูุฏูู ุงูููุฒ';
|
| 194 |
+
|
| 195 |
+
const winnerText = winners.map((w, i) =>
|
| 196 |
+
` ${i + 1}. ๐ค <b>${esc(w.name)}</b> ${w.username ? `<code>@${w.username}</code>` : ''}\n ๐ช ุญุตู ุนูู: <b>${formatK(w.coins)}</b> ุนู
ูุฉ`
|
| 197 |
+
).join('\n');
|
| 198 |
+
|
| 199 |
+
sendBoth(
|
| 200 |
+
`๐โจ <b>ูุงุฆุฒูู ${typeName}!</b>\n` +
|
| 201 |
+
`โโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 202 |
+
`๐ค ุงูู
ุฑุณู: <b>${esc(lastEnv.sender)}</b>\n\n` +
|
| 203 |
+
winnerText
|
| 204 |
+
);
|
| 205 |
+
}
|
| 206 |
+
}
|
| 207 |
+
}
|
| 208 |
+
|
| 209 |
+
// โโโโโโโโโโโโโโโโโโโโโโโ FORMATTERS โโโโโโโโโโโโโโโโโโโโโโโ
|
| 210 |
+
function fmtList(map, sortKey, emoji, unit, n = 10) {
|
| 211 |
+
const items = Object.values(map).sort((a, b) => (b[sortKey] || 0) - (a[sortKey] || 0)).slice(0, n);
|
| 212 |
+
if (!items.length) return ' โณ ูุง ููุฌุฏ ุจูุงูุงุช ุจุนุฏ';
|
| 213 |
+
return items.map((x, i) => {
|
| 214 |
+
const m = medals[i] || `${i + 1}.`;
|
| 215 |
+
const rank = ranks[i] || `#${i + 1}`;
|
| 216 |
+
const u = x.username ? `\n โ <code>@${x.username}</code>` : '';
|
| 217 |
+
const val = formatK(x[sortKey] || 0);
|
| 218 |
+
return `${m} <b>ุงูู
ุฑูุฒ ${rank}</b>\n โ ๐ค <b>${esc(x.name)}</b>: ${val} ${unit}${u}`;
|
| 219 |
+
}).join('\n\n');
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
// ุชูุณูู ุงูู
ุนูููู ู
ุน ุนุฑุถ ุชุนูููุงุชูู
|
| 223 |
+
function fmtChatters(n = 10) {
|
| 224 |
+
const items = Object.values(chattersMap).sort((a, b) => (b.count || 0) - (a.count || 0)).slice(0, n);
|
| 225 |
+
if (!items.length) return ' โณ ูุง ููุฌุฏ ุจูุงูุงุช ุจุนุฏ';
|
| 226 |
+
return items.map((x, i) => {
|
| 227 |
+
const m = medals[i] || `${i + 1}.`;
|
| 228 |
+
const rank = ranks[i] || `#${i + 1}`;
|
| 229 |
+
const u = x.username ? `\n โ <code>@${x.username}</code>` : '';
|
| 230 |
+
const lastMsgs = (x.messages || []).slice(-3).map(msg => ` ๐ฌ <i>"${esc(msg.substring(0, 50))}${msg.length > 50 ? '...' : ''}"</i>`).join('\n');
|
| 231 |
+
return `${m} <b>ุงูู
ุฑูุฒ ${rank}</b>\n โ ๐ค <b>${esc(x.name)}</b>: ${x.count} ุชุนููู${u}\n${lastMsgs || ' ๐ฌ <i>ูุง ุชุนูููุงุช ู
ุญููุธุฉ</i>'}`;
|
| 232 |
+
}).join('\n\n');
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
// ุชูุณูู ุงููุฏุงูุง ู
ุน ุฃุณู
ุงุก ุนุฑุจูุฉ
|
| 236 |
+
function fmtGifters(n = 10) {
|
| 237 |
+
const items = Object.values(giftersMap).sort((a, b) => (b.coins || 0) - (a.coins || 0)).slice(0, n);
|
| 238 |
+
if (!items.length) return ' โณ ูุง ููุฌุฏ ุจูุงูุงุช ุจุนุฏ';
|
| 239 |
+
return items.map((x, i) => {
|
| 240 |
+
const m = medals[i] || `${i + 1}.`;
|
| 241 |
+
const rank = ranks[i] || `#${i + 1}`;
|
| 242 |
+
const u = x.username ? `\n โ <code>@${x.username}</code>` : '';
|
| 243 |
+
const giftNames = (x.gifts || []).slice(-3).map(g => getArabicGiftName(g)).join(' โข ');
|
| 244 |
+
return `${m} <b>ุงูู
ุฑูุฒ ${rank}</b>\n โ ๐ค <b>${esc(x.name)}</b>: ${formatK(x.coins)} ๐ (${x.count} ูุฏูุฉ)${u}\n โ ุขุฎุฑ ุงููุฏุงูุง: ${giftNames || 'ุบูุฑ ู
ุญุฏุฏ'}`;
|
| 245 |
+
}).join('\n\n');
|
| 246 |
+
}
|
| 247 |
+
|
| 248 |
+
// ุชูุณูู ุงูุตูุงุฏูู ูุงูุญูุงุฆุจ
|
| 249 |
+
function fmtEnvelopes(n = 10) {
|
| 250 |
+
if (!envelopeWinners.length) return ' โณ ูุง ููุฌุฏ ุตูุงุฏูู ุฃู ุญูุงุฆุจ ุจุนุฏ';
|
| 251 |
+
return envelopeWinners.slice(-n).reverse().map((env, i) => {
|
| 252 |
+
const typeIcon = env.type === 'coinbag' ? '๐ฐ' : '๐ฆ';
|
| 253 |
+
const typeName = env.type === 'coinbag' ? 'ุญููุจุฉ ุนู
ูุงุช' : 'ุตูุฏูู ููุฒ';
|
| 254 |
+
const winList = (env.winners || []).map((w, wi) =>
|
| 255 |
+
` ${wi + 1}. ๐ค <b>${esc(w.name)}</b> ${w.username ? `<code>@${w.username}</code>` : ''} โ ๐ช ${formatK(w.coins)} ุนู
ูุฉ`
|
| 256 |
+
).join('\n') || ' โณ ูู
ูุธูุฑ ุงููุงุฆุฒูู ุจุนุฏ';
|
| 257 |
+
return `${typeIcon} <b>${typeName}</b> #${envelopeWinners.length - i}\n โ ุงูู
ุฑุณู: <b>${esc(env.sender)}</b> ${env.senderUsername ? `<code>@${env.senderUsername}</code>` : ''}\n โ ๐ ${formatK(env.diamonds)} ู
ุงุณุฉ โข ๐ฅ ${env.peopleCount || '?'} ุดุฎุต\n โ ๐ ุงููุงุฆุฒูู:\n${winList}`;
|
| 258 |
+
}).join('\n\n');
|
| 259 |
+
}
|
| 260 |
+
|
| 261 |
+
// โโโโโโโโโโโโโโโโโโโโโโโ TELEGRAM โโโโโโโโโโโโโโโโโโโโโโโ
|
| 262 |
+
async function sendTg(text, silent = false, buttons = null, chatId = null) {
|
| 263 |
+
const targetChatId = chatId || CONFIG.TELEGRAM_CHAT_ID;
|
| 264 |
+
if (!CONFIG.TELEGRAM_TOKEN || !targetChatId) return null;
|
| 265 |
+
const urls = [];
|
| 266 |
+
if (CONFIG.PROXY_URL) urls.push(`${CONFIG.PROXY_URL}/bot${CONFIG.TELEGRAM_TOKEN}`);
|
| 267 |
+
urls.push(`https://api.telegram.org/bot${CONFIG.TELEGRAM_TOKEN}`);
|
| 268 |
+
for (const base of urls) {
|
| 269 |
+
try {
|
| 270 |
+
const p = { chat_id: targetChatId, text, parse_mode: 'HTML', disable_notification: silent, disable_web_page_preview: true };
|
| 271 |
+
if (buttons) p.reply_markup = { inline_keyboard: buttons };
|
| 272 |
+
const r = await axios.post(`${base}/sendMessage`, p, { timeout: 15000 });
|
| 273 |
+
if (r.data?.ok) return r.data;
|
| 274 |
+
} catch (e) {}
|
| 275 |
+
}
|
| 276 |
+
return null;
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
async function deleteTgMsg(chatId, msgId) {
|
| 280 |
+
if (!CONFIG.TELEGRAM_TOKEN || !chatId || !msgId) return;
|
| 281 |
+
const urls = [];
|
| 282 |
+
if (CONFIG.PROXY_URL) urls.push(`${CONFIG.PROXY_URL}/bot${CONFIG.TELEGRAM_TOKEN}`);
|
| 283 |
+
urls.push(`https://api.telegram.org/bot${CONFIG.TELEGRAM_TOKEN}`);
|
| 284 |
+
for (const base of urls) {
|
| 285 |
+
try {
|
| 286 |
+
await axios.post(`${base}/deleteMessage`, { chat_id: chatId, message_id: msgId }, { timeout: 10000 });
|
| 287 |
+
return;
|
| 288 |
+
} catch (e) {}
|
| 289 |
+
}
|
| 290 |
+
}
|
| 291 |
+
|
| 292 |
+
async function answerCallback(callbackId, text = '') {
|
| 293 |
+
const urls = [];
|
| 294 |
+
if (CONFIG.PROXY_URL) urls.push(`${CONFIG.PROXY_URL}/bot${CONFIG.TELEGRAM_TOKEN}`);
|
| 295 |
+
urls.push(`https://api.telegram.org/bot${CONFIG.TELEGRAM_TOKEN}`);
|
| 296 |
+
for (const base of urls) {
|
| 297 |
+
try {
|
| 298 |
+
await axios.post(`${base}/answerCallbackQuery`, { callback_query_id: callbackId, text, show_alert: !!text }, { timeout: 10000 });
|
| 299 |
+
return;
|
| 300 |
+
} catch (e) {}
|
| 301 |
+
}
|
| 302 |
+
}
|
| 303 |
+
|
| 304 |
+
// ุฅุฑุณุงู ููููุงุชูู
|
| 305 |
+
async function sendBoth(text, silent = false, buttons = null) {
|
| 306 |
+
const result = await sendTg(text, silent, buttons);
|
| 307 |
+
if (CONFIG.TELEGRAM_CHAT_ID_2) {
|
| 308 |
+
sendTg(text, silent, buttons, CONFIG.TELEGRAM_CHAT_ID_2).catch(() => {});
|
| 309 |
+
}
|
| 310 |
+
return result;
|
| 311 |
+
}
|
| 312 |
+
|
| 313 |
+
// ุฅุฑุณุงู ู
ุน ุญุฐู ุงูุณุงุจู
|
| 314 |
+
async function sendAndReplace(text, silent, buttons, type) {
|
| 315 |
+
// ุญุฐู ุงูุฑุณุงูุฉ ุงูุณุงุจูุฉ ู
ู ููุณ ุงูููุน
|
| 316 |
+
if (type === 'menu' && lastMenuMsgId) {
|
| 317 |
+
await deleteTgMsg(CONFIG.TELEGRAM_CHAT_ID, lastMenuMsgId);
|
| 318 |
+
lastMenuMsgId = null;
|
| 319 |
+
} else if (type === 'report' && lastReportMsgId) {
|
| 320 |
+
await deleteTgMsg(CONFIG.TELEGRAM_CHAT_ID, lastReportMsgId);
|
| 321 |
+
lastReportMsgId = null;
|
| 322 |
+
} else if (type === 'detail') {
|
| 323 |
+
for (const mid of lastDetailMsgIds) {
|
| 324 |
+
await deleteTgMsg(CONFIG.TELEGRAM_CHAT_ID, mid);
|
| 325 |
+
}
|
| 326 |
+
lastDetailMsgIds = [];
|
| 327 |
+
}
|
| 328 |
+
|
| 329 |
+
const result = await sendTg(text, silent, buttons);
|
| 330 |
+
if (result?.result?.message_id) {
|
| 331 |
+
if (type === 'menu') lastMenuMsgId = result.result.message_id;
|
| 332 |
+
else if (type === 'report') lastReportMsgId = result.result.message_id;
|
| 333 |
+
else if (type === 'detail') lastDetailMsgIds.push(result.result.message_id);
|
| 334 |
+
}
|
| 335 |
+
|
| 336 |
+
// ุฅุฑุณุงู ููููุงุฉ ุงูุซุงููุฉ
|
| 337 |
+
if (CONFIG.TELEGRAM_CHAT_ID_2) {
|
| 338 |
+
sendTg(text, silent, buttons, CONFIG.TELEGRAM_CHAT_ID_2).catch(() => {});
|
| 339 |
+
}
|
| 340 |
+
return result;
|
| 341 |
+
}
|
| 342 |
+
|
| 343 |
+
// โโโโโโโโโโโโโโโโโโโโโโโ TEXT COMMANDS โโโโโโโโโโโโโโโโโโโโโโโ
|
| 344 |
+
async function handleTextCommand(msg) {
|
| 345 |
+
const text = (msg.text || '').trim();
|
| 346 |
+
const chatId = String(msg.chat?.id || '');
|
| 347 |
+
|
| 348 |
+
// ููุท ุงูู
ุดุฑู
|
| 349 |
+
if (chatId !== CONFIG.TELEGRAM_CHAT_ID) return;
|
| 350 |
+
|
| 351 |
+
// ุชุบููุฑ ุงูู
ุฐูุน: /change username ุฃู /ุบูุฑ username
|
| 352 |
+
if (text.startsWith('/change') || text.startsWith('/ุบูุฑ')) {
|
| 353 |
+
const parts = text.split(/\s+/);
|
| 354 |
+
const newUser = parts[1]?.replace('@', '').trim();
|
| 355 |
+
if (newUser) {
|
| 356 |
+
const oldUser = CONFIG.TIKTOK_USERNAME;
|
| 357 |
+
CONFIG.TIKTOK_USERNAME = newUser;
|
| 358 |
+
|
| 359 |
+
// ูุตู ุงูุงุชุตุงู ุงูุญุงูู
|
| 360 |
+
if (tiktokConnection) {
|
| 361 |
+
try { tiktokConnection.disconnect(); } catch (e) {}
|
| 362 |
+
}
|
| 363 |
+
isConnected = false;
|
| 364 |
+
|
| 365 |
+
await sendTg(
|
| 366 |
+
`๐ <b>ุชู
ุชุบููุฑ ุงูู
ุฐูุน!</b>\n` +
|
| 367 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 368 |
+
`โ ุงูุณุงุจู: <code>@${oldUser}</code>\n` +
|
| 369 |
+
`โ
ุงูุฌุฏูุฏ: <code>@${newUser}</code>\n\n` +
|
| 370 |
+
`โณ ุฌุงุฑู ุงูุงุชุตุงู ุจุงูุจุซ ุงูุฌุฏูุฏ...`
|
| 371 |
+
);
|
| 372 |
+
|
| 373 |
+
setTimeout(startBot, 3000);
|
| 374 |
+
} else {
|
| 375 |
+
await sendTg(`โ ุงุณุชุฎุฏู
: <code>/change username</code>\nุฃู: <code>/ุบูุฑ username</code>`);
|
| 376 |
+
}
|
| 377 |
+
return;
|
| 378 |
+
}
|
| 379 |
+
|
| 380 |
+
// ุชุนููู ููุงุฉ ุซุงููุฉ: /channel2 CHAT_ID ุฃู /ููุงุฉ CHAT_ID
|
| 381 |
+
if (text.startsWith('/channel2') || text.startsWith('/ููุงุฉ')) {
|
| 382 |
+
const parts = text.split(/\s+/);
|
| 383 |
+
const newChannelId = parts[1]?.trim();
|
| 384 |
+
if (newChannelId) {
|
| 385 |
+
CONFIG.TELEGRAM_CHAT_ID_2 = newChannelId;
|
| 386 |
+
await sendTg(
|
| 387 |
+
`๐ข <b>ุชู
ุชุนููู ุงูููุงุฉ ุงูุซุงููุฉ!</b>\n` +
|
| 388 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 389 |
+
`โ
ู
ุนุฑู ุงูููุงุฉ: <code>${newChannelId}</code>\n` +
|
| 390 |
+
`๐ค ุณูุชู
ุฅุฑุณุงู ุฌู
ูุน ุงูุชูุงุฑูุฑ ููุฐู ุงูููุงุฉ ุฃูุถุงู`
|
| 391 |
+
);
|
| 392 |
+
} else {
|
| 393 |
+
await sendTg(`โ ุงุณุชุฎุฏู
: <code>/channel2 CHAT_ID</code>\nุฃู: <code>/ููุงุฉ CHAT_ID</code>`);
|
| 394 |
+
}
|
| 395 |
+
return;
|
| 396 |
+
}
|
| 397 |
+
|
| 398 |
+
// ุงูุญุงูุฉ: /status ุฃู /ุญุงูุฉ
|
| 399 |
+
if (text === '/status' || text === '/ุญุงูุฉ') {
|
| 400 |
+
await sendTg(
|
| 401 |
+
`๐ก <b>ุญุงูุฉ ุงูุจูุช</b>\n` +
|
| 402 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 403 |
+
`๐ค ุงูู
ุฐูุน: <code>@${CONFIG.TIKTOK_USERNAME}</code>\n` +
|
| 404 |
+
`${isConnected ? '๐ข ู
ุชุตู' : '๐ด ุบูุฑ ู
ุชุตู'}\n` +
|
| 405 |
+
`โฑ ุงูู
ุฏุฉ: ${dur(startTime)}\n` +
|
| 406 |
+
`๐ข ุงูููุงุฉ ุงูุซุงููุฉ: ${CONFIG.TELEGRAM_CHAT_ID_2 ? `<code>${CONFIG.TELEGRAM_CHAT_ID_2}</code>` : 'ุบูุฑ ู
ุนูููุฉ'}\n\n` +
|
| 407 |
+
`<b>ุงูุฃูุงู
ุฑ ุงูู
ุชุงุญุฉ:</b>\n` +
|
| 408 |
+
`โข <code>/change username</code> - ุชุบููุฑ ุงูู
ุฐูุน\n` +
|
| 409 |
+
`โข <code>/channel2 CHAT_ID</code> - ุชุนููู ููุงุฉ ุซุงููุฉ\n` +
|
| 410 |
+
`โข <code>/status</code> - ุญุงูุฉ ุงูุจูุช\n` +
|
| 411 |
+
`โข <code>/clear</code> - ู
ุณุญ ุงูุฅุญุตุงุฆูุงุช`
|
| 412 |
+
);
|
| 413 |
+
return;
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
// ู
ุณุญ ุงูุฅุญุตุงุฆูุงุช: /clear ุฃู /ู
ุณุญ
|
| 417 |
+
if (text === '/clear' || text === '/ู
ุณุญ') {
|
| 418 |
+
clearStats();
|
| 419 |
+
await sendTg(`โ
ุชู
ู
ุณุญ ุฌู
ูุน ุงูุฅุญุตุงุฆูุงุช`);
|
| 420 |
+
return;
|
| 421 |
+
}
|
| 422 |
+
}
|
| 423 |
+
|
| 424 |
+
// โโโโโโโโโโโโโโโโโโโโโโโ CALLBACK HANDLER โโโโโโโโโโโโโโโโโโโโโโโ
|
| 425 |
+
async function handleCallback(data) {
|
| 426 |
+
const cb = data.data;
|
| 427 |
+
const cbId = data.id;
|
| 428 |
+
|
| 429 |
+
switch (cb) {
|
| 430 |
+
case 'gifts':
|
| 431 |
+
await sendAndReplace(
|
| 432 |
+
`๐ <b>โโโโ ููุญุฉ ุงููุฏุงูุง โโโโ</b>\n` +
|
| 433 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 434 |
+
`๐ ุฅุฌู
ุงูู ุงูู
ุงุณุงุช: <b>${formatK(totalDiamonds)}</b>\n` +
|
| 435 |
+
`๐ ุนุฏุฏ ุงููุฏุงูุง: <b>${totalGifts}</b>\n\n` +
|
| 436 |
+
`โโโ ๐ ุชุฑุชูุจ ุงูุฏุงุนู
ูู โโโ\n\n${fmtGifters(10)}`,
|
| 437 |
+
true, [[{ text: '๐ ุงููุงุฆู
ุฉ ุงูุฑุฆูุณูุฉ', callback_data: 'menu' }]], 'detail'
|
| 438 |
+
);
|
| 439 |
+
break;
|
| 440 |
+
|
| 441 |
+
case 'followers':
|
| 442 |
+
await sendAndReplace(
|
| 443 |
+
`โ <b>โโโโ ุงูู
ุชุงุจุนูู ุงูุฌุฏุฏ โโโโ</b>\n` +
|
| 444 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 445 |
+
`๐ ุงูุฅุฌู
ุงูู: <b>${totalFollows}</b> ู
ุชุงุจุน ุฌุฏูุฏ\n\n` +
|
| 446 |
+
`โโโ ๐ฅ ุขุฎุฑ ุงูู
ุชุงุจุนูู โโโ\n\n${fmtList(followersMap, 'time', 'โ', '')}`,
|
| 447 |
+
true, [[{ text: '๐ ุงููุงุฆู
ุฉ ุงูุฑุฆูุณูุฉ', callback_data: 'menu' }]], 'detail'
|
| 448 |
+
);
|
| 449 |
+
break;
|
| 450 |
+
|
| 451 |
+
case 'likes':
|
| 452 |
+
await sendAndReplace(
|
| 453 |
+
`โค๏ธ <b>โโโโ ุงูุฅุนุฌุงุจุงุช โโโโ</b>\n` +
|
| 454 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 455 |
+
`๐ ุงูุฅุฌู
ุงูู: <b>${formatK(totalLikes)}</b> ุฅุนุฌุงุจ\n\n` +
|
| 456 |
+
`โโโ ๐ฅ ุฃูุซุฑ ุงูู
ุนุฌุจูู โโโ\n\n${fmtList(likersMap, 'count', 'โค๏ธ', 'โค๏ธ')}`,
|
| 457 |
+
true, [[{ text: '๐ ุงููุงุฆู
ุฉ ุงูุฑุฆูุณูุฉ', callback_data: 'menu' }]], 'detail'
|
| 458 |
+
);
|
| 459 |
+
break;
|
| 460 |
+
|
| 461 |
+
case 'chatters':
|
| 462 |
+
await sendAndReplace(
|
| 463 |
+
`๐ฌ <b>โโโโ ุงูุชุนูููุงุช โโโโ</b>\n` +
|
| 464 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 465 |
+
`๐ ุงูุฅุฌู
ุงูู: <b>${formatK(totalComments)}</b> ุชุนููู\n\n` +
|
| 466 |
+
`โโโ ๐ฃ๏ธ ุฃูุดุท ุงูู
ุนูููู โโโ\n\n${fmtChatters(10)}`,
|
| 467 |
+
true, [[{ text: '๐ ุงููุงุฆู
ุฉ ุงูุฑุฆูุณูุฉ', callback_data: 'menu' }]], 'detail'
|
| 468 |
+
);
|
| 469 |
+
break;
|
| 470 |
+
|
| 471 |
+
case 'shares':
|
| 472 |
+
await sendAndReplace(
|
| 473 |
+
`โช๏ธ <b>โโโโ ุงูู
ุดุงุฑูุงุช โโโโ</b>\n` +
|
| 474 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 475 |
+
`๐ ุงูุฅุฌู
ุงูู: <b>${totalShares}</b> ู
ุดุงุฑูุฉ\n\n` +
|
| 476 |
+
`โโโ ๐ ุฃูุซุฑ ุงูู
ุดุงุฑููู โโโ\n\n${fmtList(sharersMap, 'count', 'โช๏ธ', 'โช๏ธ')}`,
|
| 477 |
+
true, [[{ text: '๐ ุงููุงุฆู
ุฉ ุงูุฑุฆูุณูุฉ', callback_data: 'menu' }]], 'detail'
|
| 478 |
+
);
|
| 479 |
+
break;
|
| 480 |
+
|
| 481 |
+
case 'envelopes':
|
| 482 |
+
await sendAndReplace(
|
| 483 |
+
`๐ฆ๐ฐ <b>โโโโ ุงูุตูุงุฏูู ูุงูุญูุงุฆุจ โโโโ</b>\n` +
|
| 484 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 485 |
+
`๐ฆ ุฅุฌู
ุงูู ุงูุตูุงุฏูู: <b>${totalEnvelopes}</b>\n\n` +
|
| 486 |
+
`โโโ ๐ ุขุฎุฑ ุงูุตูุงุฏูู ูุงูุญูุงุฆุจ โโโ\n\n${fmtEnvelopes(10)}`,
|
| 487 |
+
true, [[{ text: '๐ ุงููุงุฆู
ุฉ ุงูุฑุฆูุณูุฉ', callback_data: 'menu' }]], 'detail'
|
| 488 |
+
);
|
| 489 |
+
break;
|
| 490 |
+
|
| 491 |
+
case 'questions':
|
| 492 |
+
const qList = questionsArr.slice(-10).reverse().map((q, i) =>
|
| 493 |
+
`${i + 1}. <b>${esc(q.name)}</b>\n โ <i>"${esc(q.text)}"</i>`
|
| 494 |
+
).join('\n\n') || ' ูุง ููุฌุฏ ุฃุณุฆูุฉ';
|
| 495 |
+
await sendAndReplace(
|
| 496 |
+
`โ <b>โโโโ ุงูุฃุณุฆูุฉ โโโโ</b>\n` +
|
| 497 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 498 |
+
`๐ ุงูุฅุฌู
ุงูู: <b>${totalQuestions}</b> ุณุคุงู\n\n${qList}`,
|
| 499 |
+
true, [[{ text: '๐ ุงููุงุฆู
ุฉ ุงูุฑุฆูุณูุฉ', callback_data: 'menu' }]], 'detail'
|
| 500 |
+
);
|
| 501 |
+
break;
|
| 502 |
+
|
| 503 |
+
case 'top_active':
|
| 504 |
+
const activeMap = {};
|
| 505 |
+
for (const [uid, g] of Object.entries(giftersMap)) {
|
| 506 |
+
if (!activeMap[uid]) activeMap[uid] = { name: g.name, username: g.username, score: 0 };
|
| 507 |
+
activeMap[uid].score += (g.coins || 0);
|
| 508 |
+
}
|
| 509 |
+
for (const [uid, c] of Object.entries(chattersMap)) {
|
| 510 |
+
if (!activeMap[uid]) activeMap[uid] = { name: c.name, username: c.username, score: 0 };
|
| 511 |
+
activeMap[uid].score += (c.count || 0) * 5;
|
| 512 |
+
}
|
| 513 |
+
for (const [uid, l] of Object.entries(likersMap)) {
|
| 514 |
+
if (!activeMap[uid]) activeMap[uid] = { name: l.name, username: l.username, score: 0 };
|
| 515 |
+
activeMap[uid].score += (l.count || 0);
|
| 516 |
+
}
|
| 517 |
+
for (const [uid, s] of Object.entries(sharersMap)) {
|
| 518 |
+
if (!activeMap[uid]) activeMap[uid] = { name: s.name, username: s.username, score: 0 };
|
| 519 |
+
activeMap[uid].score += (s.count || 0) * 20;
|
| 520 |
+
}
|
| 521 |
+
await sendAndReplace(
|
| 522 |
+
`๐ <b>โโโโ ุฃูุซุฑ ุงูู
ุชูุงุนููู โโโโ</b>\n` +
|
| 523 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 524 |
+
`<i>๐งฎ ุงูููุงุท = ู
ุงุณุงุช + (ุชุนูููุงุชร5) + (ูุงููุงุช) + (ู
ุดุงุฑูุงุชร20)</i>\n\n` +
|
| 525 |
+
`${fmtList(activeMap, 'score', '๐', 'ููุทุฉ')}`,
|
| 526 |
+
true, [[{ text: '๐ ุงููุงุฆู
ุฉ ุงูุฑุฆูุณูุฉ', callback_data: 'menu' }]], 'detail'
|
| 527 |
+
);
|
| 528 |
+
break;
|
| 529 |
+
|
| 530 |
+
case 'stats':
|
| 531 |
+
const avgV = maxViewers > 0 ? Math.round((currentViewers + maxViewers) / 2) : currentViewers;
|
| 532 |
+
await sendAndReplace(
|
| 533 |
+
`๐ <b>โโโโ ุฅุญุตุงุฆูุงุช ู
ูุตูุฉ โโโโ</b>\n` +
|
| 534 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 535 |
+
`โฑ ุงูู
ุฏุฉ: <b>${dur(startTime)}</b>\n` +
|
| 536 |
+
`๐
${getDate()}\n\n` +
|
| 537 |
+
`โโโ ๐ ุงูู
ุดุงูุฏูู โโโ\n` +
|
| 538 |
+
`ุงูุญุงูููู: <b>${formatK(currentViewers)}</b>\n` +
|
| 539 |
+
`ุงูุฃุนูู: <b>${formatK(maxViewers)}</b>\n` +
|
| 540 |
+
`ุงูู
ุชูุณุท: ~<b>${formatK(avgV)}</b>\n\n` +
|
| 541 |
+
`โโโ ๐ ุงูุฃุฑูุงู
โโโ\n` +
|
| 542 |
+
`๐ ุงูู
ุงุณุงุช: <b>${formatK(totalDiamonds)}</b>\n` +
|
| 543 |
+
`๐ ุงููุฏุงูุง: <b>${totalGifts}</b>\n` +
|
| 544 |
+
`โค๏ธ ุงูุฅุนุฌุงุจุงุช: <b>${formatK(totalLikes)}</b>\n` +
|
| 545 |
+
`๐ฌ ุงูุชุนูููุงุช: <b>${totalComments}</b>\n` +
|
| 546 |
+
`โ ุงูู
ุชุงุจุนูู: <b>${totalFollows}</b>\n` +
|
| 547 |
+
`โช๏ธ ุงูู
ุดุงุฑูุงุช: <b>${totalShares}</b>\n` +
|
| 548 |
+
`โญ ุณูุจุฑ ูุงู: <b>${totalSuperFans}</b>\n` +
|
| 549 |
+
`๐ฆ ุงูุตูุงุฏูู: <b>${totalEnvelopes}</b>\n` +
|
| 550 |
+
`โ ุงูุฃุณุฆูุฉ: <b>${totalQuestions}</b>\n` +
|
| 551 |
+
`๐ ุงูุฅูู
ูุช: <b>${totalEmotes}</b>`,
|
| 552 |
+
true, [[{ text: '๐ ุงููุงุฆู
ุฉ ุงูุฑุฆูุณูุฉ', callback_data: 'menu' }]], 'detail'
|
| 553 |
+
);
|
| 554 |
+
break;
|
| 555 |
+
|
| 556 |
+
case 'pk_status':
|
| 557 |
+
if (pkActive) {
|
| 558 |
+
const pkG = Object.values(pkInfo.pkGifts).sort((a, b) => b.coins - a.coins).slice(0, 5)
|
| 559 |
+
.map((g, i) => `${medals[i]} <b>${esc(g.name)}</b>: ${formatK(g.coins)} ๐`).join('\n') || 'ูุง ููุฌุฏ';
|
| 560 |
+
await sendAndReplace(
|
| 561 |
+
`โ๏ธ <b>โโโโ ุญุงูุฉ PK โโโโ</b>\n` +
|
| 562 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 563 |
+
`๐ ุงููุชูุฌุฉ: <b>${formatK(pkInfo.ourScore)}</b>\n` +
|
| 564 |
+
`โฑ ุงูู
ุฏุฉ: ${dur(pkInfo.startTime)}\n\n` +
|
| 565 |
+
`๐ ุงูุฏุงุนู
ูู:\n${pkG}`,
|
| 566 |
+
true, [[{ text: '๐ ุงููุงุฆู
ุฉ ุงูุฑุฆูุณูุฉ', callback_data: 'menu' }]], 'detail'
|
| 567 |
+
);
|
| 568 |
+
} else {
|
| 569 |
+
await answerCallback(cbId, 'โ๏ธ ูุง ููุฌุฏ ุฌููุฉ PK ูุดุทุฉ');
|
| 570 |
+
return;
|
| 571 |
+
}
|
| 572 |
+
break;
|
| 573 |
+
|
| 574 |
+
case 'menu':
|
| 575 |
+
await sendAndReplace(
|
| 576 |
+
`๐ก <b>โโโโ ููุญุฉ ุงูุชุญูู
โโโโ</b>\n` +
|
| 577 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 578 |
+
`๐ค @${CONFIG.TIKTOK_USERNAME}\n` +
|
| 579 |
+
`${isConnected ? `๐ข ู
ุชุตู โข โฑ ${dur(startTime)}` : '๐ด ุบูุฑ ู
ุชุตู'}\n` +
|
| 580 |
+
`๐ ${formatK(currentViewers)} ู
ุดุงูุฏ โข ๐ ${formatK(totalDiamonds)} ู
ุงุณุฉ\n\n` +
|
| 581 |
+
`<i>๐ ุงุถุบุท ุฒุฑ ูุนุฑุถ ุงูุชูุงุตูู (ุงูุฑุณุงูุฉ ุงูุณุงุจูุฉ ุชูุญุฐู ุชููุงุฆูุงู)</i>`,
|
| 582 |
+
true,
|
| 583 |
+
[
|
| 584 |
+
[{ text: `๐ ุงููุฏุงูุง (${totalGifts})`, callback_data: 'gifts' }, { text: `โค๏ธ ุงูุฅุนุฌุงุจุงุช (${formatK(totalLikes)})`, callback_data: 'likes' }],
|
| 585 |
+
[{ text: `๐ฌ ุงูุชุนูููุงุช (${totalComments})`, callback_data: 'chatters' }, { text: `โ ุงูู
ุชุงุจุนูู (${totalFollows})`, callback_data: 'followers' }],
|
| 586 |
+
[{ text: `โช๏ธ ุงูู
ุดุงุฑูุงุช (${totalShares})`, callback_data: 'shares' }, { text: `โ ุงูุฃุณุฆูุฉ (${totalQuestions})`, callback_data: 'questions' }],
|
| 587 |
+
[{ text: `๐ฆ๐ฐ ุงูุตูุงุฏูู (${totalEnvelopes})`, callback_data: 'envelopes' }],
|
| 588 |
+
[{ text: '๐ ุฃูุซุฑ ุงูู
ุชูุงุนููู', callback_data: 'top_active' }],
|
| 589 |
+
[{ text: '๐ ุฅุญุตุงุฆูุงุช ู
ูุตูุฉ', callback_data: 'stats' }, { text: 'โ๏ธ ุญุงูุฉ PK', callback_data: 'pk_status' }],
|
| 590 |
+
[{ text: '๐ด ุฏุฎูู ุงูุจุซ', url: LIVE() }],
|
| 591 |
+
],
|
| 592 |
+
'menu'
|
| 593 |
+
);
|
| 594 |
+
break;
|
| 595 |
+
}
|
| 596 |
+
await answerCallback(cbId);
|
| 597 |
+
}
|
| 598 |
+
|
| 599 |
+
// โโโโโโโโโโโโโโโโโโโโโโโ CALLBACK POLLING โโโโโโโโโโโโโโโโโโโโโโโ
|
| 600 |
+
async function pollCallbacks() {
|
| 601 |
+
let offset = 0;
|
| 602 |
+
const urls = [];
|
| 603 |
+
if (CONFIG.PROXY_URL) urls.push(`${CONFIG.PROXY_URL}/bot${CONFIG.TELEGRAM_TOKEN}`);
|
| 604 |
+
urls.push(`https://api.telegram.org/bot${CONFIG.TELEGRAM_TOKEN}`);
|
| 605 |
+
let idx = 0;
|
| 606 |
+
|
| 607 |
+
while (true) {
|
| 608 |
+
try {
|
| 609 |
+
const base = urls[idx];
|
| 610 |
+
const res = await axios.get(`${base}/getUpdates`, {
|
| 611 |
+
params: { offset, limit: 10, timeout: 30 }, timeout: 35000
|
| 612 |
+
});
|
| 613 |
+
const updates = res.data?.result || [];
|
| 614 |
+
for (const u of updates) {
|
| 615 |
+
offset = u.update_id + 1;
|
| 616 |
+
if (u.callback_query) await handleCallback(u.callback_query);
|
| 617 |
+
if (u.message?.text) await handleTextCommand(u.message);
|
| 618 |
+
}
|
| 619 |
+
idx = 0;
|
| 620 |
+
} catch (e) {
|
| 621 |
+
idx = (idx + 1) % urls.length;
|
| 622 |
+
await new Promise(r => setTimeout(r, idx === 0 ? 5000 : 2000));
|
| 623 |
+
}
|
| 624 |
+
}
|
| 625 |
+
}
|
| 626 |
+
|
| 627 |
+
// โโโโโโโโโโโโโโโโโโโโโโโ FLUSH & CLEAR โโโโโโโโโโโโโโโโโโโโโโโ
|
| 628 |
+
function clearStats() {
|
| 629 |
+
// ุชูุธูู ุงูุฐุงูุฑุฉ
|
| 630 |
+
for (const uid of Object.keys(chattersMap)) {
|
| 631 |
+
if (chattersMap[uid].messages?.length > 30) {
|
| 632 |
+
chattersMap[uid].messages = chattersMap[uid].messages.slice(-30);
|
| 633 |
+
}
|
| 634 |
+
}
|
| 635 |
+
for (const uid of Object.keys(giftersMap)) {
|
| 636 |
+
if (giftersMap[uid].gifts?.length > 10) {
|
| 637 |
+
giftersMap[uid].gifts = giftersMap[uid].gifts.slice(-10);
|
| 638 |
+
}
|
| 639 |
+
}
|
| 640 |
+
if (envelopeWinners.length > 50) {
|
| 641 |
+
envelopeWinners = envelopeWinners.slice(-50);
|
| 642 |
+
}
|
| 643 |
+
if (questionsArr.length > 50) {
|
| 644 |
+
questionsArr = questionsArr.slice(-50);
|
| 645 |
+
}
|
| 646 |
+
}
|
| 647 |
+
|
| 648 |
+
// ุฅุฑุณุงู ุชูุฑูุฑ ุดุงู
ู
|
| 649 |
+
async function sendFullStats() {
|
| 650 |
+
if (!isConnected) return;
|
| 651 |
+
|
| 652 |
+
const avgV = maxViewers > 0 ? Math.round((currentViewers + maxViewers) / 2) : currentViewers;
|
| 653 |
+
|
| 654 |
+
let statsMsg = `๐๐ฅ <b>โโโ ุชูุฑูุฑ ุดุงู
ู โโโ</b>\n`;
|
| 655 |
+
statsMsg += `โโโโโโโโโโโโโโโโโโโโโโโ\n\n`;
|
| 656 |
+
statsMsg += `๐ค <b>${CONFIG.TIKTOK_USERNAME}</b> โข <code>@${CONFIG.TIKTOK_USERNAME}</code>\n`;
|
| 657 |
+
statsMsg += `โฑ <b>${dur(startTime)}</b> โข ๐
${getDate()}\n\n`;
|
| 658 |
+
|
| 659 |
+
statsMsg += `โโโ ๐ ุงูู
ุดุงูุฏูู โโโ\n`;
|
| 660 |
+
statsMsg += `ุงูุญุงูููู: <b>${formatK(currentViewers)}</b> | ุงูุฃุนูู: <b>${formatK(maxViewers)}</b> | ุงูู
ุชูุณุท: ~<b>${formatK(avgV)}</b>\n\n`;
|
| 661 |
+
|
| 662 |
+
statsMsg += `โโโ ๐ ุงูุฃุฑูุงู
โโโ\n`;
|
| 663 |
+
statsMsg += `๐ ุงูู
ุงุณุงุช: <b>${formatK(totalDiamonds)}</b>\n`;
|
| 664 |
+
statsMsg += `๐ ุงููุฏุงูุง: <b>${totalGifts}</b>\n`;
|
| 665 |
+
statsMsg += `โค๏ธ ุงูุฅุนุฌุงุจุงุช: <b>${formatK(totalLikes)}</b>\n`;
|
| 666 |
+
statsMsg += `๐ฌ ุงูุชุนูููุงุช: <b>${totalComments}</b>\n`;
|
| 667 |
+
statsMsg += `โ ุงูู
ุชุงุจุนูู: <b>${totalFollows}</b>\n`;
|
| 668 |
+
statsMsg += `โช๏ธ ุงูู
ุดุงุฑูุงุช: <b>${totalShares}</b>\n`;
|
| 669 |
+
statsMsg += `๐ฆ ุงูุตูุงุฏูู: <b>${totalEnvelopes}</b>\n\n`;
|
| 670 |
+
|
| 671 |
+
statsMsg += `โโโ ๐ ุฃูุถู ุงูุฏุงุนู
ูู โโโ\n\n${fmtGifters(5)}\n\n`;
|
| 672 |
+
statsMsg += `โโโ ๐ฌ ุฃูุดุท ุงูู
ุนูููู โโโ\n\n${fmtChatters(5)}`;
|
| 673 |
+
|
| 674 |
+
await sendAndReplace(statsMsg, false, [
|
| 675 |
+
[{ text: `๐ ุงููุฏุงูุง (${totalGifts})`, callback_data: 'gifts' }, { text: `โค๏ธ ุงููุงููุงุช (${formatK(totalLikes)})`, callback_data: 'likes' }],
|
| 676 |
+
[{ text: `๐ฌ ุงูู
ุนูููู (${totalComments})`, callback_data: 'chatters' }, { text: `๐ ุงูู
ุชูุงุนููู`, callback_data: 'top_active' }],
|
| 677 |
+
[{ text: '๐ฆ๐ฐ ุงูุตูุงุฏูู ูุงูุญูุงุฆุจ', callback_data: 'envelopes' }],
|
| 678 |
+
[{ text: '๐ ุชูุงุตูู ูุงู
ูุฉ', callback_data: 'stats' }],
|
| 679 |
+
[{ text: '๐ด ุฏุฎูู ุงูุจุซ', url: LIVE() }],
|
| 680 |
+
], 'report');
|
| 681 |
+
}
|
| 682 |
+
|
| 683 |
+
// โโโโโโโโโโโโโโโโโโโโโโโ REPORTS โโโโโโโโโโโโโโโโโโโโโโโ
|
| 684 |
+
function startReports() {
|
| 685 |
+
if (reportInterval) clearInterval(reportInterval);
|
| 686 |
+
reportInterval = setInterval(() => {
|
| 687 |
+
if (!isConnected) return;
|
| 688 |
+
sendFullStats();
|
| 689 |
+
}, CONFIG.REPORT_INTERVAL * 60000);
|
| 690 |
+
}
|
| 691 |
+
|
| 692 |
+
// ุชูุธูู ูู 50 ุฏูููุฉ
|
| 693 |
+
function startFlushTimer() {
|
| 694 |
+
if (flushInterval) clearInterval(flushInterval);
|
| 695 |
+
flushInterval = setInterval(() => {
|
| 696 |
+
clearStats();
|
| 697 |
+
console.log('[Flush] โ
Memory cleaned');
|
| 698 |
+
// ุฅุฑุณุงู ุชูุฑูุฑ ุญุชู ูู ูู
ููุถุบุท ุฒุฑ
|
| 699 |
+
if (isConnected) {
|
| 700 |
+
sendFullStats();
|
| 701 |
+
}
|
| 702 |
+
}, 50 * 60000);
|
| 703 |
+
}
|
| 704 |
+
|
| 705 |
+
// โโโโโโโโโโโโโโโโโโโโโโโ HTTP SERVER โโโโโโโโโโโโโโโโโโโโโโโ
|
| 706 |
+
const server = http.createServer((req, res) => {
|
| 707 |
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
| 708 |
+
res.end(`<!DOCTYPE html><html dir="rtl"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Radar v11</title>
|
| 709 |
+
<style>*{margin:0;padding:0;box-sizing:border-box}body{background:#050510;color:#e2e8f0;font-family:system-ui,sans-serif;min-height:100vh;padding:16px}.w{max-width:600px;margin:0 auto}.h{text-align:center;padding:30px;background:linear-gradient(135deg,#4f46e5,#7c3aed);border-radius:20px;margin-bottom:16px}.s{text-align:center;padding:14px;border-radius:14px;margin-bottom:14px;font-weight:700;background:${isConnected?'linear-gradient(135deg,#059669,#10b981)':'linear-gradient(135deg,#dc2626,#ef4444)'}}.g{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:14px}.g>div{background:#1e1b4b;padding:12px;border-radius:12px;text-align:center;border:1px solid #3730a3}.v{font-size:18px;font-weight:800;color:#a78bfa}.l{font-size:10px;color:#64748b;margin-top:3px}.env{background:#1a1040;border-radius:12px;padding:12px;margin-top:10px;border:1px solid #3730a3}</style></head>
|
| 710 |
+
<body><div class="w"><div class="h"><h1>๐ก TikTok Radar</h1><p style="opacity:.7">v11.0 - ุงููุณุฎุฉ ุงูู
ุญุณููุฉ</p></div>
|
| 711 |
+
<div class="s">${isConnected?'๐ข ู
ุชุตู':'๐ด ู
ูุชุธุฑ'} โข @${CONFIG.TIKTOK_USERNAME}</div>
|
| 712 |
+
${isConnected?`<div class="g"><div><div class="v">${formatK(currentViewers)}</div><div class="l">๐ ุงูู
ุดุงูุฏูู</div></div><div><div class="v">${formatK(totalDiamonds)}</div><div class="l">๐ ุงูู
ุงุณุงุช</div></div><div><div class="v">${totalGifts}</div><div class="l">๐ ุงููุฏุงูุง</div></div><div><div class="v">${formatK(totalLikes)}</div><div class="l">โค๏ธ ูุงููุงุช</div></div><div><div class="v">${totalComments}</div><div class="l">๐ฌ ุชุนูููุงุช</div></div><div><div class="v">${totalFollows}</div><div class="l">โ ู
ุชุงุจุนูู</div></div></div>
|
| 713 |
+
<div class="env"><b>๐ฆ ุงูุตูุงุฏูู ูุงูุญูุงุฆุจ:</b> ${totalEnvelopes}<br><b>โฑ ุงูู
ุฏุฉ:</b> ${dur(startTime)}</div>`:''}
|
| 714 |
+
<div style="margin-top:20px;text-align:center;font-size:12px;color:#666">
|
| 715 |
+
<b>ุงูุฃูุงู
ุฑ:</b><br>
|
| 716 |
+
/change username - ุชุบููุฑ ุงูู
ุฐูุน<br>
|
| 717 |
+
/channel2 CHAT_ID - ููุงุฉ ุซุงููุฉ<br>
|
| 718 |
+
/status - ุงูุญุงูุฉ
|
| 719 |
+
</div>
|
| 720 |
+
</div></body></html>`);
|
| 721 |
+
});
|
| 722 |
+
|
| 723 |
+
server.listen(PORT, '0.0.0.0', () => {
|
| 724 |
+
console.log(`\n๐ฏ TikTok Radar v11.0 | Port ${PORT} | @${CONFIG.TIKTOK_USERNAME}\n`);
|
| 725 |
+
pollCallbacks();
|
| 726 |
+
setTimeout(startBot, 2000);
|
| 727 |
+
});
|
| 728 |
+
|
| 729 |
+
// โโโโโโโโโโโโโโโโโโโโโโโ MAIN BOT โโโโโโโโโโโโโโโโโโโโโโโ
|
| 730 |
+
async function startBot() {
|
| 731 |
+
console.log(`[Bot] ๐ @${CONFIG.TIKTOK_USERNAME}...`);
|
| 732 |
+
let TikTokLiveConnection, WebcastEvent, ControlEvent;
|
| 733 |
+
try {
|
| 734 |
+
const lib = require('tiktok-live-connector');
|
| 735 |
+
TikTokLiveConnection = lib.TikTokLiveConnection;
|
| 736 |
+
WebcastEvent = lib.WebcastEvent;
|
| 737 |
+
ControlEvent = lib.ControlEvent;
|
| 738 |
+
} catch (e) { console.error('[Bot] โ', e.message); setTimeout(startBot, 30000); return; }
|
| 739 |
+
|
| 740 |
+
try {
|
| 741 |
+
const opts = {
|
| 742 |
+
processInitialData: true,
|
| 743 |
+
enableExtendedGiftInfo: true,
|
| 744 |
+
fetchRoomInfoOnConnect: true
|
| 745 |
+
};
|
| 746 |
+
|
| 747 |
+
// Sign API Key
|
| 748 |
+
if (CONFIG.SIGN_API_KEY) {
|
| 749 |
+
opts.signApiKey = CONFIG.SIGN_API_KEY;
|
| 750 |
+
console.log('[Bot] โ
Sign API Key configured');
|
| 751 |
+
}
|
| 752 |
+
|
| 753 |
+
// Session ููู
ุตุงุฏูุฉ ุงููุงู
ูุฉ
|
| 754 |
+
if (CONFIG.SESSION_ID && CONFIG.SESSION_ID.length > 10) {
|
| 755 |
+
opts.session = {
|
| 756 |
+
cookie: {
|
| 757 |
+
type: 'cookie',
|
| 758 |
+
value: {
|
| 759 |
+
sessionId: CONFIG.SESSION_ID,
|
| 760 |
+
ttTargetIdc: CONFIG.TT_TARGET_IDC
|
| 761 |
+
}
|
| 762 |
+
}
|
| 763 |
+
};
|
| 764 |
+
opts.authenticateWs = true; // ู
ูู
! ููุญุตูู ุนูู ุจูุงูุงุช ูุงู
ูุฉ
|
| 765 |
+
console.log('[Bot] โ
Authenticated session configured (authenticateWs: true)');
|
| 766 |
+
}
|
| 767 |
+
|
| 768 |
+
tiktokConnection = new TikTokLiveConnection(CONFIG.TIKTOK_USERNAME, opts);
|
| 769 |
+
|
| 770 |
+
console.log('[Bot] ๐ Connection options:', JSON.stringify({
|
| 771 |
+
hasSignApiKey: !!CONFIG.SIGN_API_KEY,
|
| 772 |
+
hasSession: !!(CONFIG.SESSION_ID && CONFIG.SESSION_ID.length > 10),
|
| 773 |
+
authenticateWs: opts.authenticateWs || false,
|
| 774 |
+
ttTargetIdc: CONFIG.TT_TARGET_IDC || 'not set'
|
| 775 |
+
}));
|
| 776 |
+
|
| 777 |
+
// โโโโโโโโโโ โ
CONNECTED โโโโโโโโโโ
|
| 778 |
+
tiktokConnection.on(ControlEvent.CONNECTED, (state) => {
|
| 779 |
+
isConnected = true; startTime = new Date();
|
| 780 |
+
totalGifts=0;totalDiamonds=0;totalLikes=0;totalComments=0;totalFollows=0;
|
| 781 |
+
totalShares=0;totalSuperFans=0;totalQuestions=0;totalEnvelopes=0;totalEmotes=0;
|
| 782 |
+
maxViewers=0;currentViewers=0;
|
| 783 |
+
giftersMap={};followersMap={};chattersMap={};sharersMap={};likersMap={};
|
| 784 |
+
envelopeWinners=[];
|
| 785 |
+
questionsArr=[];pinnedMessages=[];pkActive=false;
|
| 786 |
+
roomTitle = state.roomInfo?.title || '';
|
| 787 |
+
|
| 788 |
+
console.log(`[Bot] โ
Room: ${state.roomId}`);
|
| 789 |
+
sendBoth(
|
| 790 |
+
`๐กโจ <b>ุงูุจุซ ุงูู
ุจุงุดุฑ ุจุฏุฃ!</b>\n` +
|
| 791 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 792 |
+
`๐ค <b>${CONFIG.TIKTOK_USERNAME}</b>\n` +
|
| 793 |
+
`๐ <code>@${CONFIG.TIKTOK_USERNAME}</code>\n` +
|
| 794 |
+
(roomTitle ? `๐ ${esc(roomTitle)}\n` : '') +
|
| 795 |
+
`โฐ ${getTime()} โข ๐
${getDate()}\n\n` +
|
| 796 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n` +
|
| 797 |
+
`๐ <b>ุงูุจุซ ุจุฏุฃ! ุงูุถู
ุงูุขู!</b>`,
|
| 798 |
+
false,
|
| 799 |
+
[
|
| 800 |
+
[{ text: '๐ด ุฏุฎูู ุงูุจุซ ุงูู
ุจุงุดุฑ', url: LIVE() }],
|
| 801 |
+
[{ text: '๐ ููุญุฉ ุงูุชุญูู
', callback_data: 'menu' }]
|
| 802 |
+
]
|
| 803 |
+
);
|
| 804 |
+
startReports();
|
| 805 |
+
startFlushTimer();
|
| 806 |
+
});
|
| 807 |
+
|
| 808 |
+
tiktokConnection.on(ControlEvent.DISCONNECTED, () => {
|
| 809 |
+
isConnected = false;
|
| 810 |
+
if (reportInterval) clearInterval(reportInterval);
|
| 811 |
+
if (flushInterval) clearInterval(flushInterval);
|
| 812 |
+
scheduleReconnect(30000);
|
| 813 |
+
});
|
| 814 |
+
|
| 815 |
+
tiktokConnection.on(ControlEvent.ERROR, (err) => console.error('[Bot] โ ๏ธ', err?.info || err?.message || err));
|
| 816 |
+
|
| 817 |
+
// โโโโโโโโโโ ๐ด STREAM END โโโโโโโโโโ
|
| 818 |
+
tiktokConnection.on(WebcastEvent.STREAM_END, () => {
|
| 819 |
+
isConnected = false;
|
| 820 |
+
if (reportInterval) clearInterval(reportInterval);
|
| 821 |
+
if (flushInterval) clearInterval(flushInterval);
|
| 822 |
+
sendBoth(
|
| 823 |
+
`๐ด <b>ุงูุชูู ุงูุจุซ!</b>\n` +
|
| 824 |
+
`โโโโโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 825 |
+
`๐ค <b>${CONFIG.TIKTOK_USERNAME}</b>\n` +
|
| 826 |
+
`โฑ ุงูู
ุฏุฉ: <b>${dur(startTime)}</b>\n` +
|
| 827 |
+
`๐
${getDate()}\n\n` +
|
| 828 |
+
`โโโ ๐ ุงูู
ูุฎุต ุงูููุงุฆู โโโ\n` +
|
| 829 |
+
`๐ ุงูู
ุงุณุงุช: <b>${formatK(totalDiamonds)}</b>\n` +
|
| 830 |
+
`๐ ุงููุฏุงูุง: <b>${totalGifts}</b>\n` +
|
| 831 |
+
`โค๏ธ ุงูุฅุนุฌุงุจุงุช: <b>${formatK(totalLikes)}</b>\n` +
|
| 832 |
+
`๐ฌ ุงูุชุนูููุงุช: <b>${totalComments}</b>\n` +
|
| 833 |
+
`โ ุงูู
ุชุงุจุนูู: <b>${totalFollows}</b>\n` +
|
| 834 |
+
`โช๏ธ ุงูู
ุดุงุฑูุงุช: <b>${totalShares}</b>\n` +
|
| 835 |
+
`๐ฆ ุงูุตูุงุฏูู: <b>${totalEnvelopes}</b>\n\n` +
|
| 836 |
+
`โโโ ๐ ุฃูุถู ุงูุฏุงุนู
ูู โโโ\n\n${fmtGifters(5)}\n\n` +
|
| 837 |
+
`โโโ ๐ฌ ุฃูุดุท ุงูู
ุนูููู โโโ\n\n${fmtChatters(5)}\n\n` +
|
| 838 |
+
`โจ <b>ุดูุฑุงู ููุฌู
ูุน!</b>`
|
| 839 |
+
);
|
| 840 |
+
scheduleReconnect(60000);
|
| 841 |
+
});
|
| 842 |
+
|
| 843 |
+
// โโโโโโโโโโ ๐ฌ CHAT โโโโโโโโโโ
|
| 844 |
+
tiktokConnection.on(WebcastEvent.CHAT, (data) => {
|
| 845 |
+
totalComments++;
|
| 846 |
+
const uid = data.user?.userId || data.user?.uniqueId || 'x';
|
| 847 |
+
const name = data.user?.nickname || data.user?.uniqueId || '?';
|
| 848 |
+
const uname = data.user?.uniqueId || '';
|
| 849 |
+
const comment = data.comment || '';
|
| 850 |
+
if (!chattersMap[uid]) chattersMap[uid] = { name, username: uname, count: 0, messages: [] };
|
| 851 |
+
chattersMap[uid].count++;
|
| 852 |
+
if (comment) {
|
| 853 |
+
chattersMap[uid].messages.push(comment);
|
| 854 |
+
if (chattersMap[uid].messages.length > 20) {
|
| 855 |
+
chattersMap[uid].messages = chattersMap[uid].messages.slice(-20);
|
| 856 |
+
}
|
| 857 |
+
}
|
| 858 |
+
});
|
| 859 |
+
|
| 860 |
+
// โโโโโโโโโโ ๐ GIFT โโโโโโโโโโ
|
| 861 |
+
tiktokConnection.on(WebcastEvent.GIFT, (data) => {
|
| 862 |
+
const uid = data.user?.userId || data.user?.uniqueId || 'x';
|
| 863 |
+
const name = data.user?.nickname || data.user?.uniqueId || '?';
|
| 864 |
+
const uname = data.user?.uniqueId || '';
|
| 865 |
+
const gn = data.giftName || data.extendedGiftInfo?.name || 'Gift';
|
| 866 |
+
const gnAr = getArabicGiftName(gn);
|
| 867 |
+
const gt = data.giftType ?? 0;
|
| 868 |
+
const rc = data.repeatCount ?? 1;
|
| 869 |
+
const re = data.repeatEnd ?? true;
|
| 870 |
+
let dc = data.diamondCount || data.extendedGiftInfo?.diamondCount || data.extendedGiftInfo?.diamond_count || data.gift?.diamond_count || data.giftDetails?.diamondCount || 0;
|
| 871 |
+
if (gt === 1 && re === false) return;
|
| 872 |
+
const cost = dc * rc;
|
| 873 |
+
totalGifts++; totalDiamonds += cost;
|
| 874 |
+
if (!giftersMap[uid]) giftersMap[uid] = { name, username: uname, coins: 0, count: 0, gifts: [] };
|
| 875 |
+
giftersMap[uid].coins += cost; giftersMap[uid].count++;
|
| 876 |
+
giftersMap[uid].gifts.push(gn);
|
| 877 |
+
if (giftersMap[uid].gifts.length > 10) {
|
| 878 |
+
giftersMap[uid].gifts = giftersMap[uid].gifts.slice(-10);
|
| 879 |
+
}
|
| 880 |
+
if (pkActive) {
|
| 881 |
+
if (!pkInfo.pkGifts[uid]) pkInfo.pkGifts[uid] = { name, username: uname, coins: 0 };
|
| 882 |
+
pkInfo.pkGifts[uid].coins += cost;
|
| 883 |
+
}
|
| 884 |
+
console.log(`[๐] ${name}: ${gnAr} = ${cost}๐`);
|
| 885 |
+
});
|
| 886 |
+
|
| 887 |
+
// โโโโโโโโโโ โค๏ธ LIKE โโโโโโโโโโ
|
| 888 |
+
tiktokConnection.on(WebcastEvent.LIKE, (data) => {
|
| 889 |
+
const likes = data.likeCount || 1;
|
| 890 |
+
totalLikes += likes;
|
| 891 |
+
const uid = data.user?.userId || data.user?.uniqueId || 'x';
|
| 892 |
+
const name = data.user?.nickname || data.user?.uniqueId || '?';
|
| 893 |
+
const uname = data.user?.uniqueId || '';
|
| 894 |
+
if (!likersMap[uid]) likersMap[uid] = { name, username: uname, count: 0 };
|
| 895 |
+
likersMap[uid].count += likes;
|
| 896 |
+
});
|
| 897 |
+
|
| 898 |
+
// โโโโโโโโโโ โ FOLLOW โโโโโโโโโโ
|
| 899 |
+
tiktokConnection.on(WebcastEvent.FOLLOW, (data) => {
|
| 900 |
+
totalFollows++;
|
| 901 |
+
const uid = data.user?.userId || data.user?.uniqueId || Date.now();
|
| 902 |
+
const name = data.user?.nickname || data.user?.uniqueId || '?';
|
| 903 |
+
const uname = data.user?.uniqueId || '';
|
| 904 |
+
followersMap[uid] = { name, username: uname, time: Date.now() };
|
| 905 |
+
});
|
| 906 |
+
|
| 907 |
+
// โโโโโโโโโโ โช๏ธ SHARE โโโโโโโโโโ
|
| 908 |
+
tiktokConnection.on(WebcastEvent.SHARE, (data) => {
|
| 909 |
+
totalShares++;
|
| 910 |
+
const uid = data.user?.uniqueId || 'x';
|
| 911 |
+
const name = data.user?.nickname || data.user?.uniqueId || '?';
|
| 912 |
+
if (!sharersMap[uid]) sharersMap[uid] = { name, username: uid, count: 0 };
|
| 913 |
+
sharersMap[uid].count++;
|
| 914 |
+
});
|
| 915 |
+
|
| 916 |
+
// โโโโโโโโโโ ๐ VIEWERS โโโโโโโโโโ
|
| 917 |
+
tiktokConnection.on(WebcastEvent.ROOM_USER, (data) => {
|
| 918 |
+
currentViewers = data.viewerCount || 0;
|
| 919 |
+
if (currentViewers > maxViewers) maxViewers = currentViewers;
|
| 920 |
+
});
|
| 921 |
+
|
| 922 |
+
tiktokConnection.on(WebcastEvent.MEMBER, () => {});
|
| 923 |
+
tiktokConnection.on(WebcastEvent.EMOTE, () => { totalEmotes++; });
|
| 924 |
+
|
| 925 |
+
// โโโโโโโโโโ ๐ฆ ENVELOPE - ุตูุฏูู / ุญููุจุฉ ุนู
ูุงุช โโโโโโโโโโ
|
| 926 |
+
tiktokConnection.on(WebcastEvent.ENVELOPE, (data) => {
|
| 927 |
+
totalEnvelopes++;
|
| 928 |
+
|
| 929 |
+
// ุทุจุงุนุฉ ูู ุงูุจูุงูุงุช ููุญุตูุง
|
| 930 |
+
console.log('[๐ฆ ENVELOPE RAW]', JSON.stringify(data, null, 2));
|
| 931 |
+
|
| 932 |
+
const env = data.envelopeInfo || data;
|
| 933 |
+
if (env) {
|
| 934 |
+
// ู
ุญุงููุฉ ุงุณุชุฎุฑุงุฌ ุงูุจูุงูุงุช ู
ู ู
ุฎุชูู ุงูู
ูุงูุน ุงูู
ู
ููุฉ
|
| 935 |
+
const senderName = env.sendUserName || env.senderNickname || data.user?.nickname || '?';
|
| 936 |
+
const senderUsername = env.sendUserUniqueId || env.senderUniqueId || data.user?.uniqueId || '';
|
| 937 |
+
const diamonds = env.diamondCount || env.coins || data.diamonds || 0;
|
| 938 |
+
const peopleCount = env.peopleCount || env.maxUserCount || 0;
|
| 939 |
+
const envelopeId = env.envelopeId || env.id || '';
|
| 940 |
+
|
| 941 |
+
// ุชุญุฏูุฏ ุงูููุน ุจุดูู ุฃูุถู
|
| 942 |
+
let envType = 'chest';
|
| 943 |
+
if (env.envelopeType === 2 || env.envelopeBusinessType === 2) {
|
| 944 |
+
envType = 'coinbag';
|
| 945 |
+
} else if (String(env.description || '').toLowerCase().includes('coin') ||
|
| 946 |
+
String(env.description || '').toLowerCase().includes('ุญููุจุฉ') ||
|
| 947 |
+
String(env.title || '').toLowerCase().includes('coin') ||
|
| 948 |
+
String(data.common?.describe || '').toLowerCase().includes('coin')) {
|
| 949 |
+
envType = 'coinbag';
|
| 950 |
+
}
|
| 951 |
+
|
| 952 |
+
const typeIcon = envType === 'coinbag' ? '๐ฐ' : '๐ฆ';
|
| 953 |
+
const typeName = envType === 'coinbag' ? 'ุญููุจุฉ ุนู
ูุงุช' : 'ุตูุฏูู ููุฒ';
|
| 954 |
+
|
| 955 |
+
// ุงุณุชุฎุฑุงุฌ ุงููุงุฆุฒูู ู
ู ู
ุฎุชูู ุงูู
ุตุงุฏุฑ ุงูู
ู
ููุฉ
|
| 956 |
+
const winners = [];
|
| 957 |
+
|
| 958 |
+
// ุงูู
ุตุฏุฑ 1: envelopeGrabUserList
|
| 959 |
+
const grabList = env.envelopeGrabUserList || env.grabUserList || env.winnerList || env.winners || [];
|
| 960 |
+
for (const w of grabList) {
|
| 961 |
+
winners.push({
|
| 962 |
+
name: w.nickname || w.nickName || w.uniqueId || w.userName || '?',
|
| 963 |
+
username: w.uniqueId || w.unique_id || '',
|
| 964 |
+
coins: w.diamondCount || w.coinCount || w.coins || w.amount || 0,
|
| 965 |
+
});
|
| 966 |
+
}
|
| 967 |
+
|
| 968 |
+
// ุงูู
ุตุฏุฑ 2: envelopeGrabRecordList
|
| 969 |
+
const recordList = env.envelopeGrabRecordList || [];
|
| 970 |
+
for (const r of recordList) {
|
| 971 |
+
const user = r.user || r;
|
| 972 |
+
winners.push({
|
| 973 |
+
name: user.nickname || user.nickName || user.uniqueId || '?',
|
| 974 |
+
username: user.uniqueId || '',
|
| 975 |
+
coins: r.diamondCount || r.coinCount || r.grabDiamond || 0,
|
| 976 |
+
});
|
| 977 |
+
}
|
| 978 |
+
|
| 979 |
+
console.log(`[๐ฆ] ${typeName} ู
ู ${senderName}: ${diamonds}๐ ููู ${peopleCount} ุดุฎุต | ุงููุงุฆุฒูู: ${winners.length}`);
|
| 980 |
+
|
| 981 |
+
envelopeWinners.push({
|
| 982 |
+
type: envType,
|
| 983 |
+
sender: senderName,
|
| 984 |
+
senderUsername,
|
| 985 |
+
diamonds,
|
| 986 |
+
peopleCount,
|
| 987 |
+
winners,
|
| 988 |
+
envelopeId,
|
| 989 |
+
time: new Date()
|
| 990 |
+
});
|
| 991 |
+
|
| 992 |
+
let winnerText = '';
|
| 993 |
+
if (winners.length) {
|
| 994 |
+
winnerText = `\n\n๐ <b>ุงููุงุฆุฒูู:</b>\n` + winners.map((w, i) =>
|
| 995 |
+
` ${i + 1}. ๐ค <b>${esc(w.name)}</b> ${w.username ? `<code>@${w.username}</code>` : ''}\n ๐ช ุญุตู ุนูู: <b>${formatK(w.coins)}</b> ุนู
ูุฉ`
|
| 996 |
+
).join('\n');
|
| 997 |
+
} else {
|
| 998 |
+
winnerText = `\n\nโณ <i>ุงููุงุฆุฒูู ุณูุธูุฑูู ุจุนุฏ ุงูุชูุงุก ุงูุตูุฏูู...</i>`;
|
| 999 |
+
}
|
| 1000 |
+
|
| 1001 |
+
sendBoth(
|
| 1002 |
+
`${typeIcon}โจ <b>${typeName}!</b>\n` +
|
| 1003 |
+
`โโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 1004 |
+
`๐ ุฑูู
: <code>${envelopeId}</code>\n` +
|
| 1005 |
+
`๐ค ุงูู
ุฑุณู: <b>${esc(senderName)}</b> ${senderUsername ? `<code>@${senderUsername}</code>` : ''}\n` +
|
| 1006 |
+
`๐ <b>${formatK(diamonds)}</b> ู
ุงุณุฉ โข ๐ฅ <b>${peopleCount}</b> ุดุฎุต` +
|
| 1007 |
+
winnerText
|
| 1008 |
+
);
|
| 1009 |
+
}
|
| 1010 |
+
});
|
| 1011 |
+
|
| 1012 |
+
// โโโโโโโโโโ ๐ฆ ู
ุญุงููุฉ ุงูุชูุงุท ุฃุญุฏุงุซ ุฃุฎุฑู ููุตูุงุฏูู โโโโโโโโโโ
|
| 1013 |
+
const envelopeEvents = [
|
| 1014 |
+
'envelopeGrab', 'envelopeResult', 'envelopeOpen', 'envelopePortal',
|
| 1015 |
+
'treasureBox', 'treasureChest', 'goodyBag', 'goody_bag',
|
| 1016 |
+
'coinBag', 'coin_bag', 'luckyBag', 'lucky_bag'
|
| 1017 |
+
];
|
| 1018 |
+
|
| 1019 |
+
for (const evtName of envelopeEvents) {
|
| 1020 |
+
try {
|
| 1021 |
+
tiktokConnection.on(evtName, (data) => {
|
| 1022 |
+
console.log(`[๐ฆ ${evtName.toUpperCase()}]`, JSON.stringify(data, null, 2));
|
| 1023 |
+
|
| 1024 |
+
// ู
ุญุงููุฉ ุงุณุชุฎุฑุงุฌ ุงููุงุฆุฒูู
|
| 1025 |
+
const winners = extractWinners(data);
|
| 1026 |
+
if (winners.length > 0) {
|
| 1027 |
+
updateLastEnvelopeWithWinners(winners);
|
| 1028 |
+
}
|
| 1029 |
+
});
|
| 1030 |
+
} catch (e) {}
|
| 1031 |
+
}
|
| 1032 |
+
|
| 1033 |
+
// ุงูุงุณุชู
ุงุน ูู BARRAGE ูุฏ ูุญุชูู ุนูู ู
ุนููู
ุงุช ุงูุตูุงุฏูู
|
| 1034 |
+
try {
|
| 1035 |
+
tiktokConnection.on(WebcastEvent.BARRAGE, (data) => {
|
| 1036 |
+
const content = JSON.stringify(data).toLowerCase();
|
| 1037 |
+
if (content.includes('envelope') || content.includes('treasure') ||
|
| 1038 |
+
content.includes('chest') || content.includes('grab') ||
|
| 1039 |
+
content.includes('coin') || content.includes('winner')) {
|
| 1040 |
+
console.log('[๐ฆ BARRAGE - Envelope Related]', JSON.stringify(data, null, 2));
|
| 1041 |
+
|
| 1042 |
+
const winners = extractWinners(data);
|
| 1043 |
+
if (winners.length > 0) {
|
| 1044 |
+
updateLastEnvelopeWithWinners(winners);
|
| 1045 |
+
}
|
| 1046 |
+
}
|
| 1047 |
+
});
|
| 1048 |
+
} catch (e) {}
|
| 1049 |
+
|
| 1050 |
+
// โโโโโโโโโโ โ QUESTION โโโโโโโโโโ
|
| 1051 |
+
try { tiktokConnection.on(WebcastEvent.QUESTION_NEW, (data) => {
|
| 1052 |
+
totalQuestions++;
|
| 1053 |
+
const q = data.details?.questionText || '';
|
| 1054 |
+
const name = data.details?.user?.nickname || '?';
|
| 1055 |
+
if (q) questionsArr.push({ name, text: q, time: Date.now() });
|
| 1056 |
+
}); } catch (e) {}
|
| 1057 |
+
|
| 1058 |
+
// โโโโโโโโโโ โญ SUPER FAN โโโโโโโโโโ
|
| 1059 |
+
try { tiktokConnection.on(WebcastEvent.SUPER_FAN, (data) => {
|
| 1060 |
+
totalSuperFans++;
|
| 1061 |
+
const msg = data.content?.defaultPattern || data.commonBarrageContent?.defaultPattern || '';
|
| 1062 |
+
sendBoth(`โญ๐ <b>ุณูุจุฑ ูุงู ุฌุฏูุฏ!</b>\nโโโโโโโโโโโโโโโโโโโ\n\n${esc(msg) || '๐ ู
ุณุชุฎุฏู
ุฃุตุจุญ ุณูุจุฑ ูุงู!'}`);
|
| 1063 |
+
}); } catch (e) {}
|
| 1064 |
+
|
| 1065 |
+
try { tiktokConnection.on(WebcastEvent.SUPER_FAN_JOIN, () => {}); } catch (e) {}
|
| 1066 |
+
try { tiktokConnection.on(WebcastEvent.SUPER_FAN_BOX, (data) => {
|
| 1067 |
+
if (data.envelopeInfo) sendBoth(`โญ๐ฆ <b>ุตูุฏูู ุณูุจุฑ ูุงู!</b>`);
|
| 1068 |
+
}); } catch (e) {}
|
| 1069 |
+
|
| 1070 |
+
// โโโโโโโโโโ ๐ PIN โโโโโโโโโโ
|
| 1071 |
+
try { tiktokConnection.on(WebcastEvent.ROOM_PIN, (data) => {
|
| 1072 |
+
const by = data.operator?.nickname || '?';
|
| 1073 |
+
const chat = data.chatMessage?.comment || '';
|
| 1074 |
+
if (chat) sendBoth(`๐ <b>ุฑุณุงูุฉ ู
ุซุจุชุฉ</b>\nโโโโโโโโโโโโโโโโโโโ\n\n๐ค <b>${esc(by)}</b>\n๐ฌ <i>"${esc(chat)}"</i>`, true);
|
| 1075 |
+
}); } catch (e) {}
|
| 1076 |
+
|
| 1077 |
+
// โโโโโโโโโโ โ๏ธ PK โโโโโโโโโโ
|
| 1078 |
+
tiktokConnection.on(WebcastEvent.LINK_MIC_BATTLE, (data) => {
|
| 1079 |
+
pkActive = true;
|
| 1080 |
+
pkInfo = { battleId: data.battleId || '', participantDetails: [], ourScore: 0, theirScore: 0, startTime: new Date(), pkGifts: {} };
|
| 1081 |
+
const details = [];
|
| 1082 |
+
for (const [k, info] of Object.entries(data.anchorInfo || {})) {
|
| 1083 |
+
const u = info.user || info || {};
|
| 1084 |
+
const did = u.displayId || u.uniqueId || '';
|
| 1085 |
+
const nn = u.nickName || u.nickname || did || 'ู
ุฌููู';
|
| 1086 |
+
if (did || nn !== 'ู
ุฌููู') details.push({ name: nn, username: did });
|
| 1087 |
+
}
|
| 1088 |
+
pkInfo.participantDetails = details;
|
| 1089 |
+
const opp = details.find(p => p.username !== CONFIG.TIKTOK_USERNAME && p.name !== CONFIG.TIKTOK_USERNAME) || details[1] || null;
|
| 1090 |
+
|
| 1091 |
+
let msg = `โ๏ธ๐ฅ <b>ุฌููุฉ PK ุฌุฏูุฏุฉ!</b>\nโโโโโโโโโโโโโโโโโโโโโโโ\n\n`;
|
| 1092 |
+
msg += `๐ <b>${esc(CONFIG.TIKTOK_USERNAME)}</b>\n <code>@${CONFIG.TIKTOK_USERNAME}</code>\n\n ๐\n\n`;
|
| 1093 |
+
if (opp) msg += `๐ฅ <b>${esc(opp.name)}</b>\n <code>@${opp.username || '?'}</code>\n\n`;
|
| 1094 |
+
else msg += `๐ฅ โณ ุฌุงุฑู ุงูุชุญู
ูู...\n\n`;
|
| 1095 |
+
msg += `โโโโโโโโโโโโโโโโโโโโโโโ\n๐ <b>ุงุฏุนู
ูุง ุงูุจุซ!</b>`;
|
| 1096 |
+
sendBoth(msg, false, [
|
| 1097 |
+
[{ text: '๐ด ุงุฏุฎู ูุงุฏุนู
!', url: LIVE() }],
|
| 1098 |
+
[{ text: 'โ๏ธ ูุชูุฌุฉ PK', callback_data: 'pk_status' }]
|
| 1099 |
+
]);
|
| 1100 |
+
});
|
| 1101 |
+
|
| 1102 |
+
tiktokConnection.on(WebcastEvent.LINK_MIC_ARMIES, (data) => {
|
| 1103 |
+
if (pkActive && data.totalDiamondCount) pkInfo.ourScore = data.totalDiamondCount;
|
| 1104 |
+
});
|
| 1105 |
+
|
| 1106 |
+
try { tiktokConnection.on(WebcastEvent.LINK_MIC_BATTLE_PUNISH_FINISH, () => {
|
| 1107 |
+
pkActive = false;
|
| 1108 |
+
const pkG = Object.values(pkInfo.pkGifts).sort((a, b) => b.coins - a.coins).slice(0, 5)
|
| 1109 |
+
.map((g, i) => `${medals[i]} <b>${esc(g.name)}</b>: ${formatK(g.coins)} ๐`).join('\n') || 'ูุง ููุฌุฏ';
|
| 1110 |
+
sendBoth(`๐ <b>ุงูุชูุช PK!</b>\nโโโโโโโโโโโโโโโโโโโโโโโ\n\n๐ <b>${formatK(pkInfo.ourScore)}</b> โข โฑ ${dur(pkInfo.startTime)}\n\n๐ ุงูุฏุงุนู
ูู:\n${pkG}\n\nโจ <b>ุดูุฑุงู ููุฌู
ูุน!</b>`);
|
| 1111 |
+
}); } catch (e) {}
|
| 1112 |
+
|
| 1113 |
+
// โโโโโโโโโโ ๐ฏ GOAL โโโโโโโโโโ
|
| 1114 |
+
try { tiktokConnection.on(WebcastEvent.GOAL_UPDATE, (data) => {
|
| 1115 |
+
const d = data.goal?.description || '';
|
| 1116 |
+
if (d) sendBoth(`๐ฏ <b>ุชุญุฏูุซ ุงููุฏู!</b>\nโโโโโโโโโโโโโโโ\n๐ ${esc(d)}`, true);
|
| 1117 |
+
}); } catch (e) {}
|
| 1118 |
+
|
| 1119 |
+
// โโโโโโโโโโ ๐ณ๏ธ POLL โโโโโโโโโโ
|
| 1120 |
+
try { tiktokConnection.on(WebcastEvent.POLL_MESSAGE, (data) => {
|
| 1121 |
+
const t = data.pollBasicInfo?.title || '';
|
| 1122 |
+
if (t) sendBoth(`๐ณ๏ธ <b>ุชุตููุช!</b>\nโโโโโโโโโโโโโโโ\n๐ <b>${esc(t)}</b>`, true);
|
| 1123 |
+
}); } catch (e) {}
|
| 1124 |
+
|
| 1125 |
+
// โโโโโโโโโโ ๐ SHOPPING โโโโโโโโโโ
|
| 1126 |
+
try { tiktokConnection.on(WebcastEvent.OEC_LIVE_SHOPPING, (data) => {
|
| 1127 |
+
const s = data.shopData;
|
| 1128 |
+
if (s?.title) sendBoth(`๐ <b>ู
ูุชุฌ!</b>\n๐ฆ ${esc(s.title)}${s.priceString ? `\n๐ฐ ${esc(s.priceString)}` : ''}`, true);
|
| 1129 |
+
}); } catch (e) {}
|
| 1130 |
+
|
| 1131 |
+
try { tiktokConnection.on(WebcastEvent.RANK_UPDATE, () => {}); } catch (e) {}
|
| 1132 |
+
try { tiktokConnection.on(WebcastEvent.RANK_TEXT, (data) => {
|
| 1133 |
+
if (data.ownerIdxAfterUpdate && data.ownerIdxBeforeUpdate && data.ownerIdxAfterUpdate < data.ownerIdxBeforeUpdate)
|
| 1134 |
+
sendBoth(`๐๐ ุงุฑุชูุน ุงูุชุฑุชูุจ! #${data.ownerIdxBeforeUpdate} โ #${data.ownerIdxAfterUpdate} ๐ฅ`, true);
|
| 1135 |
+
}); } catch (e) {}
|
| 1136 |
+
tiktokConnection.on(WebcastEvent.LIVE_INTRO, () => {});
|
| 1137 |
+
try { tiktokConnection.on(WebcastEvent.ROOM_MESSAGE, () => {}); } catch (e) {}
|
| 1138 |
+
try { tiktokConnection.on(WebcastEvent.CAPTION_MESSAGE, () => {}); } catch (e) {}
|
| 1139 |
+
|
| 1140 |
+
// โโโโโโโโโโ ๐ ุชุณุฌูู ูู ุงูุฃุญุฏุงุซ ุจุฏูู ุงุณุชุซูุงุก โโโโโโโโโโ
|
| 1141 |
+
// ูุง ูุชุฌุงูู ุฃู ุดู - ูุณุฌู ูู ุญุฏุซ ุจุฃูู 200 ุญุฑู
|
| 1142 |
+
const knownSkipEvents = new Set([
|
| 1143 |
+
// ููุท ุงูุฃุญุฏุงุซ ุงููุซูุฑุฉ ุฌุฏุงู ุงููู ุชู
ูุฃ ุงูู Logs
|
| 1144 |
+
'WebcastChatMessage', 'WebcastLikeMessage',
|
| 1145 |
+
'WebcastRoomUserSeqMessage',
|
| 1146 |
+
]);
|
| 1147 |
+
|
| 1148 |
+
// ุนุฏุงุฏ ูุชุณุฌูู ูู ุฃููุงุน ุงูุฃุญุฏุงุซ ุงููู ุฌุช
|
| 1149 |
+
const seenEventTypes = new Set();
|
| 1150 |
+
|
| 1151 |
+
tiktokConnection.on(ControlEvent.DECODED_DATA, (eventType, decodedData, binary) => {
|
| 1152 |
+
const lowerType = (eventType || '').toLowerCase();
|
| 1153 |
+
|
| 1154 |
+
// โ
ุชุณุฌูู ูู ููุน ุญุฏุซ ูู
ุฑ ู
ุฑุฉ ูุญุฏุฉ
|
| 1155 |
+
if (!seenEventTypes.has(eventType)) {
|
| 1156 |
+
seenEventTypes.add(eventType);
|
| 1157 |
+
console.log(`[๐ NEW EVENT TYPE SEEN: ${eventType}] โ ุฃูู ู
ุฑุฉ ูุธูุฑ ูุงูููุน!`);
|
| 1158 |
+
}
|
| 1159 |
+
|
| 1160 |
+
// โ
ุชุณุฌูู ูู ุญุฏุซ ุบูุฑ ู
ุนุฑูู
|
| 1161 |
+
if (!knownSkipEvents.has(eventType)) {
|
| 1162 |
+
const dataStr = JSON.stringify(decodedData || {});
|
| 1163 |
+
// ุณุฌ๏ฟฝ๏ฟฝ ุงุณู
ุงูุญุฏุซ + ุฃูู 300 ุญุฑู ุจุณ
|
| 1164 |
+
console.log(`[๐ก ${eventType}] ${dataStr.substring(0, 300)}`);
|
| 1165 |
+
|
| 1166 |
+
// ุฅุฐุง ู
ุชุนูู ุจุตูุฏูู ุณุฌู ูุงู
ู
|
| 1167 |
+
if (lowerType.includes('envelope') || lowerType.includes('treasure') ||
|
| 1168 |
+
lowerType.includes('chest') || lowerType.includes('grab') ||
|
| 1169 |
+
lowerType.includes('goody') || lowerType.includes('portal') ||
|
| 1170 |
+
lowerType.includes('lucky') || lowerType.includes('coin') ||
|
| 1171 |
+
lowerType.includes('bag') || lowerType.includes('box')) {
|
| 1172 |
+
console.log(`[๐ฆ FULL ${eventType}]`, JSON.stringify(decodedData, null, 2));
|
| 1173 |
+
|
| 1174 |
+
const winners = extractWinners(decodedData);
|
| 1175 |
+
if (winners.length > 0) {
|
| 1176 |
+
updateLastEnvelopeWithWinners(winners);
|
| 1177 |
+
}
|
| 1178 |
+
}
|
| 1179 |
+
|
| 1180 |
+
// ุญุชู ูู ู
ุง ูุนุฑู ุงุณู
ุงูุญุฏุซุ ููุญุต ุงูู
ุญุชูู
|
| 1181 |
+
if (dataStr.toLowerCase().includes('envelope') ||
|
| 1182 |
+
dataStr.toLowerCase().includes('diamond') ||
|
| 1183 |
+
dataStr.toLowerCase().includes('grab')) {
|
| 1184 |
+
console.log(`[๐ฆ DATA-MATCH ${eventType}]`, JSON.stringify(decodedData, null, 2));
|
| 1185 |
+
|
| 1186 |
+
// ู
ุญุงููุฉ ู
ุนุงูุฌุฉ ูุฃูู ุตูุฏูู
|
| 1187 |
+
try {
|
| 1188 |
+
const env = decodedData?.envelopeInfo || decodedData;
|
| 1189 |
+
if (env && (env.diamondCount || env.sendUserName || env.envelopeId)) {
|
| 1190 |
+
totalEnvelopes++;
|
| 1191 |
+
const senderName = env.sendUserName || env.senderNickname || '?';
|
| 1192 |
+
const senderUsername = env.sendUserUniqueId || env.senderUniqueId || '';
|
| 1193 |
+
const diamonds = env.diamondCount || env.coins || 0;
|
| 1194 |
+
const peopleCount = env.peopleCount || env.maxUserCount || 0;
|
| 1195 |
+
const envelopeId = env.envelopeId || env.id || '';
|
| 1196 |
+
|
| 1197 |
+
let envType = 'chest';
|
| 1198 |
+
if (env.envelopeType === 2 || env.envelopeBusinessType === 2) envType = 'coinbag';
|
| 1199 |
+
|
| 1200 |
+
const typeIcon = envType === 'coinbag' ? '๐ฐ' : '๐ฆ';
|
| 1201 |
+
const typeName = envType === 'coinbag' ? 'ุญููุจุฉ ุนู
ูุงุช' : 'ุตูุฏูู ููุฒ';
|
| 1202 |
+
|
| 1203 |
+
const winners = extractWinners(decodedData);
|
| 1204 |
+
|
| 1205 |
+
envelopeWinners.push({
|
| 1206 |
+
type: envType, sender: senderName, senderUsername,
|
| 1207 |
+
diamonds, peopleCount, winners, envelopeId, time: new Date()
|
| 1208 |
+
});
|
| 1209 |
+
|
| 1210 |
+
let winnerText = '';
|
| 1211 |
+
if (winners.length) {
|
| 1212 |
+
winnerText = `\n\n๐ <b>ุงููุงุฆุฒูู:</b>\n` + winners.map((w, i) =>
|
| 1213 |
+
` ${i + 1}. ๐ค <b>${esc(w.name)}</b> ${w.username ? `<code>@${w.username}</code>` : ''}\n ๐ช ุญุตู ุนูู: <b>${formatK(w.coins)}</b> ุนู
ูุฉ`
|
| 1214 |
+
).join('\n');
|
| 1215 |
+
} else {
|
| 1216 |
+
winnerText = `\n\nโณ <i>ุงููุงุฆุฒูู ุณูุธูุฑูู ูุงุญูุงู...</i>`;
|
| 1217 |
+
}
|
| 1218 |
+
|
| 1219 |
+
sendBoth(
|
| 1220 |
+
`${typeIcon}โจ <b>${typeName}!</b>\n` +
|
| 1221 |
+
`โโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 1222 |
+
`๐ ุฑูู
: <code>${envelopeId}</code>\n` +
|
| 1223 |
+
`๐ค ุงูู
ุฑุณู: <b>${esc(senderName)}</b> ${senderUsername ? `<code>@${senderUsername}</code>` : ''}\n` +
|
| 1224 |
+
`๐ <b>${formatK(diamonds)}</b> ู
ุงุณุฉ โข ๐ฅ <b>${peopleCount}</b> ุดุฎุต` +
|
| 1225 |
+
winnerText
|
| 1226 |
+
);
|
| 1227 |
+
|
| 1228 |
+
console.log(`[๐ฆ โ
CAUGHT FROM DECODED] ${typeName} ู
ู ${senderName}: ${diamonds}๐`);
|
| 1229 |
+
}
|
| 1230 |
+
} catch (e) {
|
| 1231 |
+
console.log('[๐ฆ Parse Error]', e.message);
|
| 1232 |
+
}
|
| 1233 |
+
}
|
| 1234 |
+
}
|
| 1235 |
+
});
|
| 1236 |
+
|
| 1237 |
+
// โโโโโโโโโโ ๐ ุนุฑุถ ูู ุงูุฃุญุฏุงุซ ุงูู
ุชููุฑุฉ โโโโโโโโโโ
|
| 1238 |
+
console.log('[Bot] ๐ Available WebcastEvents:', Object.keys(WebcastEvent).join(', '));
|
| 1239 |
+
console.log('[Bot] ๐ Available ControlEvents:', Object.keys(ControlEvent).join(', '));
|
| 1240 |
+
|
| 1241 |
+
// โโโโโโโโโโ ๐ก RAW DATA - ุงูุชูุงุท ุงูุจูุงูุงุช ุงูุฎุงู
ุบูุฑ ุงูู
๏ฟฝ๏ฟฝุฑููุฉ โโโโโโโโโโ
|
| 1242 |
+
tiktokConnection.on(ControlEvent.RAW_DATA, (messageTypeName, binary) => {
|
| 1243 |
+
const lowerName = (messageTypeName || '').toLowerCase();
|
| 1244 |
+
// ูุณุฌู ููุท ุงูุฑุณุงุฆู ุงูุบูุฑ ู
ุนุฑููุฉ ุฃู ุงูู
ุชุนููุฉ ุจุงูุจูุงุจุฉ
|
| 1245 |
+
if (lowerName.includes('envelope') || lowerName.includes('portal') ||
|
| 1246 |
+
lowerName.includes('goody') || lowerName.includes('treasure') ||
|
| 1247 |
+
lowerName.includes('bag') || lowerName.includes('box') ||
|
| 1248 |
+
lowerName.includes('grab') || lowerName.includes('lucky') ||
|
| 1249 |
+
lowerName.includes('reward') || lowerName.includes('coin') ||
|
| 1250 |
+
lowerName.includes('asset')) {
|
| 1251 |
+
console.log(`[๐ด RAW_DATA: ${messageTypeName}] binary size: ${binary?.length || 0} bytes`);
|
| 1252 |
+
}
|
| 1253 |
+
});
|
| 1254 |
+
|
| 1255 |
+
// ู
ุญุงููุฉ ุงูุงุณุชู
ุงุน ููู ุงูุฃุญุฏุงุซ ุงูู
ุชููุฑุฉ ูู ุงูู
ูุชุจุฉ
|
| 1256 |
+
const allWebcastEvents = Object.values(WebcastEvent);
|
| 1257 |
+
for (const evt of allWebcastEvents) {
|
| 1258 |
+
const evtLower = (evt || '').toLowerCase();
|
| 1259 |
+
// ุงูุฃุญุฏุงุซ ุงููู ู
ุง ุณุฌููุงูุง ูุฏููุงู
|
| 1260 |
+
if (evtLower.includes('envelope') || evtLower.includes('treasure') ||
|
| 1261 |
+
evtLower.includes('goody') || evtLower.includes('portal') ||
|
| 1262 |
+
evtLower.includes('bag') || evtLower.includes('box') ||
|
| 1263 |
+
evtLower.includes('capsule') || evtLower.includes('boost') ||
|
| 1264 |
+
evtLower.includes('toast') || evtLower.includes('notice') ||
|
| 1265 |
+
evtLower.includes('bottom') || evtLower.includes('gift_broadcast')) {
|
| 1266 |
+
try {
|
| 1267 |
+
tiktokConnection.on(evt, (data) => {
|
| 1268 |
+
console.log(`[๐ฏ AUTO-LISTEN ${evt}]`, JSON.stringify(data, null, 2));
|
| 1269 |
+
|
| 1270 |
+
// ู
ุญุงููุฉ ู
ุนุงูุฌุฉ ูุตูุฏูู
|
| 1271 |
+
const winners = extractWinners(data);
|
| 1272 |
+
if (data?.envelopeInfo || data?.diamondCount || data?.sendUserName) {
|
| 1273 |
+
totalEnvelopes++;
|
| 1274 |
+
const env = data.envelopeInfo || data;
|
| 1275 |
+
const senderName = env.sendUserName || '?';
|
| 1276 |
+
const diamonds = env.diamondCount || 0;
|
| 1277 |
+
const peopleCount = env.peopleCount || 0;
|
| 1278 |
+
|
| 1279 |
+
envelopeWinners.push({
|
| 1280 |
+
type: 'chest', sender: senderName, senderUsername: '',
|
| 1281 |
+
diamonds, peopleCount, winners, envelopeId: '', time: new Date()
|
| 1282 |
+
});
|
| 1283 |
+
|
| 1284 |
+
sendBoth(
|
| 1285 |
+
`๐ฆโจ <b>ุตูุฏูู/ุจูุงุจุฉ!</b> (via ${evt})\nโโโโโโโโโโโโโโโโโโโ\n\n` +
|
| 1286 |
+
`๐ค <b>${esc(senderName)}</b>\n๐ <b>${formatK(diamonds)}</b> ู
ุงุณุฉ`
|
| 1287 |
+
);
|
| 1288 |
+
}
|
| 1289 |
+
if (winners.length > 0) {
|
| 1290 |
+
updateLastEnvelopeWithWinners(winners);
|
| 1291 |
+
}
|
| 1292 |
+
});
|
| 1293 |
+
console.log(`[Bot] ๐ Auto-listening: ${evt}`);
|
| 1294 |
+
} catch (e) {}
|
| 1295 |
+
}
|
| 1296 |
+
}
|
| 1297 |
+
|
| 1298 |
+
console.log('[Bot] ๐ Connecting...');
|
| 1299 |
+
await tiktokConnection.connect();
|
| 1300 |
+
} catch (err) {
|
| 1301 |
+
console.error('[Bot] โ', err.message || err);
|
| 1302 |
+
isConnected = false;
|
| 1303 |
+
scheduleReconnect(60000);
|
| 1304 |
+
}
|
| 1305 |
+
}
|
| 1306 |
+
|
| 1307 |
+
function scheduleReconnect(d) {
|
| 1308 |
+
if (reconnectTimer) clearTimeout(reconnectTimer);
|
| 1309 |
+
console.log(`[Bot] ๐ ${d / 1000}s...`);
|
| 1310 |
+
reconnectTimer = setTimeout(() => { reconnectTimer = null; if (!isConnected) startBot(); }, d);
|
| 1311 |
+
}
|
| 1312 |
+
|
| 1313 |
+
process.on('uncaughtException', e => console.error('[!]', e.message));
|
| 1314 |
+
process.on('unhandledRejection', r => console.error('[!]', r));
|
| 1315 |
+
setInterval(() => { http.get(`http://localhost:${PORT}`, r => r.resume()).on('error', () => {}); }, 60000);
|
package.json
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "tiktok-radar-v11",
|
| 3 |
+
"version": "11.0.0",
|
| 4 |
+
"main": "bot.js",
|
| 5 |
+
"dependencies": {
|
| 6 |
+
"axios": "^1.7.0",
|
| 7 |
+
"tiktok-live-connector": "2.1.0"
|
| 8 |
+
}
|
| 9 |
+
}
|