-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathbot.py
More file actions
381 lines (348 loc) · 19 KB
/
bot.py
File metadata and controls
381 lines (348 loc) · 19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
import shareithub
import json
import threading
import time
import os
import random
import re
import requests
from shareithub import shareithub
from dotenv import load_dotenv
from datetime import datetime
from colorama import init, Fore, Style
init(autoreset=True)
load_dotenv()
discord_tokens_env = os.getenv('DISCORD_TOKENS', '')
if discord_tokens_env:
discord_tokens = [token.strip() for token in discord_tokens_env.split(',') if token.strip()]
else:
discord_token = os.getenv('DISCORD_TOKEN')
if not discord_token:
raise ValueError("Tidak ada Discord token yang ditemukan! Harap atur DISCORD_TOKENS atau DISCORD_TOKEN di .env.")
discord_tokens = [discord_token]
google_api_keys = os.getenv('GOOGLE_API_KEYS', '').split(',')
google_api_keys = [key.strip() for key in google_api_keys if key.strip()]
if not google_api_keys:
raise ValueError("Tidak ada Google API Key yang ditemukan! Harap atur GOOGLE_API_KEYS di .env.")
processed_message_ids = set()
used_api_keys = set()
last_generated_text = None
cooldown_time = 86400
def log_message(message, level="INFO"):
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
if level.upper() == "SUCCESS":
color, icon = Fore.GREEN, "✅"
elif level.upper() == "ERROR":
color, icon = Fore.RED, "🚨"
elif level.upper() == "WARNING":
color, icon = Fore.YELLOW, "⚠️"
elif level.upper() == "WAIT":
color, icon = Fore.CYAN, "⌛"
else:
color, icon = Fore.WHITE, "ℹ️"
border = f"{Fore.MAGENTA}{'=' * 80}{Style.RESET_ALL}"
formatted_message = f"{color}[{timestamp}] {icon} {message}{Style.RESET_ALL}"
print(border)
print(formatted_message)
print(border)
def get_random_api_key():
available_keys = [key for key in google_api_keys if key not in used_api_keys]
if not available_keys:
log_message("Semua API key terkena error 429. Menunggu 24 jam sebelum mencoba lagi...", "ERROR")
time.sleep(cooldown_time)
used_api_keys.clear()
return get_random_api_key()
return random.choice(available_keys)
def get_random_message_from_file():
try:
with open("pesan.txt", "r", encoding="utf-8") as file:
messages = [line.strip() for line in file.readlines() if line.strip()]
return random.choice(messages) if messages else "Tidak ada pesan tersedia di file."
except FileNotFoundError:
return "File pesan.txt tidak ditemukan!"
def generate_language_specific_prompt(user_message, prompt_language):
if prompt_language == 'id':
return f"Balas pesan berikut dalam bahasa Indonesia: {user_message}"
elif prompt_language == 'en':
return f"Reply to the following message in English: {user_message}"
else:
log_message(f"Bahasa prompt '{prompt_language}' tidak valid. Pesan dilewati.", "WARNING")
return None
def generate_reply(prompt, prompt_language, use_google_ai=True):
global last_generated_text
if use_google_ai:
google_api_key = get_random_api_key()
lang_prompt = generate_language_specific_prompt(prompt, prompt_language)
if lang_prompt is None:
return None
ai_prompt = f"{lang_prompt}\n\nBuatlah menjadi 1 kalimat menggunakan bahasa sehari hari manusia."
url = f'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key={google_api_key}'
headers = {'Content-Type': 'application/json'}
data = {'contents': [{'parts': [{'text': ai_prompt}]}]}
while True:
try:
response = requests.post(url, headers=headers, json=data)
if response.status_code == 429:
log_message(f"API key {google_api_key} terkena rate limit (429). Menggunakan API key lain...", "WARNING")
used_api_keys.add(google_api_key)
return generate_reply(prompt, prompt_language, use_google_ai)
response.raise_for_status()
result = response.json()
generated_text = result['candidates'][0]['content']['parts'][0]['text']
if generated_text == last_generated_text:
log_message("AI menghasilkan teks yang sama, meminta teks baru...", "WAIT")
continue
last_generated_text = generated_text
return generated_text
except requests.exceptions.RequestException as e:
log_message(f"Request failed: {e}", "ERROR")
time.sleep(2)
else:
return get_random_message_from_file()
def get_channel_info(channel_id, token):
headers = {'Authorization': token}
channel_url = f"https://discord.com/api/v9/channels/{channel_id}"
try:
channel_response = requests.get(channel_url, headers=headers)
channel_response.raise_for_status()
channel_data = channel_response.json()
channel_name = channel_data.get('name', 'Unknown Channel')
guild_id = channel_data.get('guild_id')
server_name = "Direct Message"
if guild_id:
guild_url = f"https://discord.com/api/v9/guilds/{guild_id}"
guild_response = requests.get(guild_url, headers=headers)
guild_response.raise_for_status()
guild_data = guild_response.json()
server_name = guild_data.get('name', 'Unknown Server')
return server_name, channel_name
except requests.exceptions.RequestException as e:
log_message(f"Error mengambil info channel: {e}", "ERROR")
return "Unknown Server", "Unknown Channel"
def get_bot_info(token):
headers = {'Authorization': token}
try:
response = requests.get("https://discord.com/api/v9/users/@me", headers=headers)
response.raise_for_status()
data = response.json()
username = data.get("username", "Unknown")
discriminator = data.get("discriminator", "")
bot_id = data.get("id", "Unknown")
return username, discriminator, bot_id
except requests.exceptions.RequestException as e:
log_message(f"Gagal mengambil info akun bot: {e}", "ERROR")
return "Unknown", "", "Unknown"
def auto_reply(channel_id, settings, token):
headers = {'Authorization': token}
if settings["use_google_ai"]:
try:
bot_info_response = requests.get('https://discord.com/api/v9/users/@me', headers=headers)
bot_info_response.raise_for_status()
bot_user_id = bot_info_response.json().get('id')
except requests.exceptions.RequestException as e:
log_message(f"[Channel {channel_id}] Gagal mengambil info bot: {e}", "ERROR")
return
while True:
prompt = None
reply_to_id = None
log_message(f"[Channel {channel_id}] Menunggu {settings['read_delay']} detik sebelum membaca pesan...", "WAIT")
time.sleep(settings["read_delay"])
try:
response = requests.get(f'https://discord.com/api/v9/channels/{channel_id}/messages', headers=headers)
response.raise_for_status()
messages = response.json()
if messages:
most_recent_message = messages[0]
message_id = most_recent_message.get('id')
author_id = most_recent_message.get('author', {}).get('id')
message_type = most_recent_message.get('type', '')
if author_id != bot_user_id and message_type != 8 and message_id not in processed_message_ids:
user_message = most_recent_message.get('content', '').strip()
attachments = most_recent_message.get('attachments', [])
if attachments or not re.search(r'\w', user_message):
log_message(f"[Channel {channel_id}] Pesan tidak diproses (bukan teks murni).", "WARNING")
else:
log_message(f"[Channel {channel_id}] Received: {user_message}", "INFO")
if settings["use_slow_mode"]:
slow_mode_delay = get_slow_mode_delay(channel_id, token)
log_message(f"[Channel {channel_id}] Slow mode aktif, menunggu {slow_mode_delay} detik...", "WAIT")
time.sleep(slow_mode_delay)
prompt = user_message
reply_to_id = message_id
processed_message_ids.add(message_id)
else:
prompt = None
except requests.exceptions.RequestException as e:
log_message(f"[Channel {channel_id}] Request error: {e}", "ERROR")
prompt = None
if prompt:
result = generate_reply(prompt, settings["prompt_language"], settings["use_google_ai"])
if result is None:
log_message(f"[Channel {channel_id}] Bahasa prompt tidak valid. Pesan dilewati.", "WARNING")
else:
response_text = result if result else "Maaf, tidak dapat membalas pesan."
if response_text.strip().lower() == prompt.strip().lower():
log_message(f"[Channel {channel_id}] Balasan sama dengan pesan yang diterima. Tidak mengirim balasan.", "WARNING")
else:
if settings["use_reply"]:
send_message(channel_id, response_text, token, reply_to=reply_to_id,
delete_after=settings["delete_bot_reply"], delete_immediately=settings["delete_immediately"])
else:
send_message(channel_id, response_text, token,
delete_after=settings["delete_bot_reply"], delete_immediately=settings["delete_immediately"])
else:
log_message(f"[Channel {channel_id}] Tidak ada pesan baru atau pesan tidak valid.", "INFO")
log_message(f"[Channel {channel_id}] Menunggu {settings['delay_interval']} detik sebelum iterasi berikutnya...", "WAIT")
time.sleep(settings["delay_interval"])
else:
while True:
delay = settings["delay_interval"]
log_message(f"[Channel {channel_id}] Menunggu {delay} detik sebelum mengirim pesan dari file...", "WAIT")
time.sleep(delay)
message_text = generate_reply("", settings["prompt_language"], use_google_ai=False)
if settings["use_reply"]:
send_message(channel_id, message_text, token, delete_after=settings["delete_bot_reply"], delete_immediately=settings["delete_immediately"])
else:
send_message(channel_id, message_text, token, delete_after=settings["delete_bot_reply"], delete_immediately=settings["delete_immediately"])
def send_message(channel_id, message_text, token, reply_to=None, delete_after=None, delete_immediately=False):
headers = {'Authorization': token, 'Content-Type': 'application/json'}
payload = {'content': message_text}
if reply_to:
payload["message_reference"] = {"message_id": reply_to}
url = f"https://discord.com/api/v9/channels/{channel_id}/messages"
try:
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
if response.status_code in [200, 201]:
data = response.json()
message_id = data.get("id")
log_message(f"[Channel {channel_id}] Pesan terkirim: \"{message_text}\" (ID: {message_id})", "SUCCESS")
if delete_after is not None:
if delete_immediately:
log_message(f"[Channel {channel_id}] Menghapus pesan segera tanpa delay...", "WAIT")
threading.Thread(target=delete_message, args=(channel_id, message_id, token), daemon=True).start()
elif delete_after > 0:
log_message(f"[Channel {channel_id}] Pesan akan dihapus dalam {delete_after} detik...", "WAIT")
threading.Thread(target=delayed_delete, args=(channel_id, message_id, delete_after, token), daemon=True).start()
else:
log_message(f"[Channel {channel_id}] Gagal mengirim pesan. Status: {response.status_code}", "ERROR")
log_message(f"[Channel {channel_id}] Respons API: {response.text}", "ERROR")
except requests.exceptions.RequestException as e:
log_message(f"[Channel {channel_id}] Kesalahan saat mengirim pesan: {e}", "ERROR")
def delayed_delete(channel_id, message_id, delay, token):
time.sleep(delay)
delete_message(channel_id, message_id, token)
def delete_message(channel_id, message_id, token):
headers = {'Authorization': token, 'Content-Type': 'application/json'}
url = f'https://discord.com/api/v9/channels/{channel_id}/messages/{message_id}'
try:
response = requests.delete(url, headers=headers)
if response.status_code == 204:
log_message(f"[Channel {channel_id}] Pesan dengan ID {message_id} berhasil dihapus.", "SUCCESS")
else:
log_message(f"[Channel {channel_id}] Gagal menghapus pesan. Status: {response.status_code}", "ERROR")
log_message(f"[Channel {channel_id}] Respons API: {response.text}", "ERROR")
except requests.exceptions.RequestException as e:
log_message(f"[Channel {channel_id}] Kesalahan saat menghapus pesan: {e}", "ERROR")
def get_slow_mode_delay(channel_id, token):
headers = {'Authorization': token, 'Accept': 'application/json'}
url = f"https://discord.com/api/v9/channels/{channel_id}"
try:
response = requests.get(url, headers=headers)
response.raise_for_status()
data = response.json()
slow_mode_delay = data.get("rate_limit_per_user", 0)
log_message(f"[Channel {channel_id}] Slow mode delay: {slow_mode_delay} detik", "INFO")
return slow_mode_delay
except requests.exceptions.RequestException as e:
log_message(f"[Channel {channel_id}] Gagal mengambil informasi slow mode: {e}", "ERROR")
return 5
def get_server_settings(channel_id, channel_name):
print(f"\nMasukkan pengaturan untuk channel {channel_id} (Nama Channel: {channel_name}):")
use_google_ai = input(" Gunakan Google Gemini AI? (y/n): ").strip().lower() == 'y'
if use_google_ai:
prompt_language = input(" Pilih bahasa prompt (en/id): ").strip().lower()
if prompt_language not in ["en", "id"]:
print(" Input tidak valid. Default ke 'id'.")
prompt_language = "id"
enable_read_message = True
read_delay = int(input(" Masukkan delay membaca pesan (detik): "))
delay_interval = int(input(" Masukkan interval (detik) untuk setiap iterasi auto reply: "))
use_slow_mode = input(" Gunakan slow mode? (y/n): ").strip().lower() == 'y'
else:
prompt_language = input(" Pilih bahasa pesan dari file (en/id): ").strip().lower()
if prompt_language not in ["en", "id"]:
print(" Input tidak valid. Default ke 'id'.")
prompt_language = "id"
enable_read_message = False
read_delay = 0
delay_interval = int(input(" Masukkan delay (detik) untuk mengirim pesan dari file: "))
use_slow_mode = False
use_reply = input(" Kirim pesan sebagai reply? (y/n): ").strip().lower() == 'y'
hapus_balasan = input(" Hapus balasan bot setelah beberapa detik? (y/n): ").strip().lower() == 'y'
if hapus_balasan:
delete_bot_reply = int(input(" Setelah berapa detik balasan dihapus? (0 untuk tidak, atau masukkan delay): "))
delete_immediately = input(" Hapus pesan langsung tanpa delay? (y/n): ").strip().lower() == 'y'
else:
delete_bot_reply = None
delete_immediately = False
return {
"prompt_language": prompt_language,
"use_google_ai": use_google_ai,
"enable_read_message": enable_read_message,
"read_delay": read_delay,
"delay_interval": delay_interval,
"use_slow_mode": use_slow_mode,
"use_reply": use_reply,
"delete_bot_reply": delete_bot_reply,
"delete_immediately": delete_immediately
}
if __name__ == "__main__":
bot_accounts = {}
for token in discord_tokens:
username, discriminator, bot_id = get_bot_info(token)
bot_accounts[token] = {"username": username, "discriminator": discriminator, "bot_id": bot_id}
log_message(f"Akun Bot: {username}#{discriminator} (ID: {bot_id})", "SUCCESS")
# Input channel IDs dari user
channel_ids = [cid.strip() for cid in input("Masukkan ID channel (pisahkan dengan koma jika lebih dari satu): ").split(",") if cid.strip()]
token = discord_tokens[0]
channel_infos = {}
for channel_id in channel_ids:
server_name, channel_name = get_channel_info(channel_id, token)
channel_infos[channel_id] = {"server_name": server_name, "channel_name": channel_name}
log_message(f"[Channel {channel_id}] Terhubung ke server: {server_name} | Nama Channel: {channel_name}", "SUCCESS")
server_settings = {}
for channel_id in channel_ids:
channel_name = channel_infos.get(channel_id, {}).get("channel_name", "Unknown Channel")
server_settings[channel_id] = get_server_settings(channel_id, channel_name)
for cid, settings in server_settings.items():
info = channel_infos.get(cid, {"server_name": "Unknown Server", "channel_name": "Unknown Channel"})
hapus_str = ("Langsung" if settings['delete_immediately'] else
(f"Dalam {settings['delete_bot_reply']} detik" if settings['delete_bot_reply'] and settings['delete_bot_reply'] > 0 else "Tidak"))
log_message(
f"[Channel {cid} | Server: {info['server_name']} | Channel: {info['channel_name']}] "
f"Pengaturan: Gemini AI = {'Aktif' if settings['use_google_ai'] else 'Tidak'}, "
f"Bahasa = {settings['prompt_language'].upper()}, "
f"Membaca Pesan = {'Aktif' if settings['enable_read_message'] else 'Tidak'}, "
f"Delay Membaca = {settings['read_delay']} detik, "
f"Interval = {settings['delay_interval']} detik, "
f"Slow Mode = {'Aktif' if settings['use_slow_mode'] else 'Tidak'}, "
f"Reply = {'Ya' if settings['use_reply'] else 'Tidak'}, "
f"Hapus Pesan = {hapus_str}",
"INFO"
)
token_index = 0
for channel_id in channel_ids:
token = discord_tokens[token_index % len(discord_tokens)]
token_index += 1
bot_info = bot_accounts.get(token, {"username": "Unknown", "discriminator": "", "bot_id": "Unknown"})
thread = threading.Thread(
target=auto_reply,
args=(channel_id, server_settings[channel_id], token)
)
thread.daemon = True
thread.start()
log_message(f"[Channel {channel_id}] Bot aktif: {bot_info['username']}#{bot_info['discriminator']} (Token: {token[:4]}{'...' if len(token) > 4 else token})", "SUCCESS")
log_message("Bot sedang berjalan di beberapa server... Tekan CTRL+C untuk menghentikan.", "INFO")
while True:
time.sleep(10)