forked from prpbio/OLDDiscord-Bot
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
206 lines (179 loc) · 8.04 KB
/
main.py
File metadata and controls
206 lines (179 loc) · 8.04 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
import os
import sys
import threading
import time
import json
import signal
import asyncio
import discord
import aiohttp
from discord import app_commands
import requests
from discord.ext import commands
from discord.gateway import DiscordWebSocket, _log
from discord.ext.commands import Bot
# === Discord Bot Setup ===
intents = discord.Intents.default()
intents.guilds = True
intents.message_content = True
owner = "sl.ip"
co_owner = 481295611417853982
MainURL = "https://spook.bio"
try:
with open('TOKEN.txt', 'r') as f:
token = f.read()
except FileNotFoundError:
print("Error: The file 'TOKEN' was not found.")
except Exception as e:
print(f"An error occurred: {e}")
class MyGateway(DiscordWebSocket):
async def identify(self):
payload = {
'op': self.IDENTIFY,
'd': {
'token': token,
'properties': {
'$os': sys.platform,
'$browser': 'Discord Android',
'$device': 'Discord Android',
'$referrer': '',
'$referring_domain': ''
},
'compress': True,
'large_threshold': 250,
'v': 3
}
}
if self.shard_id is not None and self.shard_count is not None:
payload['d']['shard'] = [self.shard_id, self.shard_count]
state = self._connection
if state._activity is not None or state._status is not None:
payload['d']['presence'] = {
'status': state._status,
'game': state._activity,
'since': 0,
'afk': False
}
if state._intents is not None:
payload['d']['intents'] = state._intents.value
await self.call_hooks('before_identify', self.shard_id, initial=self._initial_identify)
await self.send_as_json(payload)
_log.info('Shard ID %s has sent the IDENTIFY payload.', self.shard_id)
class MyBot(Bot):
async def connect(self, *, reconnect: bool = True) -> None:
"""|coro|
Creates a websocket connection and lets the websocket listen
to messages from Discord. This is a loop that runs the entire
event system and miscellaneous aspects of the library. Control
is not resumed until the WebSocket connection is terminated.
Parameters
-----------
reconnect: :class:`bool`
If we should attempt reconnecting, either due to internet
failure or a specific failure on Discord's part. Certain
disconnects that lead to bad state will not be handled (such as
invalid sharding payloads or bad tokens).
Raises
-------
:exc:`.GatewayNotFound`
If the gateway to connect to Discord is not found. Usually if this
is thrown then there is a Discord API outage.
:exc:`.ConnectionClosed`
The websocket connection has been terminated.
"""
backoff = discord.client.ExponentialBackoff()
ws_params = {
'initial': True,
'shard_id': self.shard_id,
}
while not self.is_closed():
try:
coro = MyGateway.from_client(self, **ws_params)
self.ws = await asyncio.wait_for(coro, timeout=60.0)
ws_params['initial'] = False
while True:
await self.ws.poll_event()
except discord.client.ReconnectWebSocket as e:
_log.info('Got a request to %s the websocket.', e.op)
self.dispatch('disconnect')
ws_params.update(sequence=self.ws.sequence, resume=e.resume, session=self.ws.session_id)
continue
except (OSError,
discord.HTTPException,
discord.GatewayNotFound,
discord.ConnectionClosed,
aiohttp.ClientError,
asyncio.TimeoutError) as exc:
self.dispatch('disconnect')
if not reconnect:
await self.close()
if isinstance(exc, discord.ConnectionClosed) and exc.code == 1000:
# clean close, don't re-raise this
return
raise
if self.is_closed():
return
# If we get connection reset by peer then try to RESUME
if isinstance(exc, OSError) and exc.errno in (54, 10054):
ws_params.update(sequence=self.ws.sequence, initial=False, resume=True, session=self.ws.session_id)
continue
# We should only get this when an unhandled close code happens,
# such as a clean disconnect (1000) or a bad state (bad token, no sharding, etc)
# sometimes, discord sends us 1000 for unknown reasons so we should reconnect
# regardless and rely on is_closed instead
if isinstance(exc, discord.ConnectionClosed):
if exc.code == 4014:
raise discord.PrivilegedIntentsRequired(exc.shard_id) from None
if exc.code != 1000:
await self.close()
raise
retry = backoff.delay()
_log.exception("Attempting a reconnect in %.2fs", retry)
await asyncio.sleep(retry)
# Always try to RESUME the connection
# If the connection is not RESUME-able then the gateway will invalidate the session.
# This is apparently what the official Discord client does.
ws_params.update(sequence=self.ws.sequence, resume=True, session=self.ws.session_id)
#bot = commands.Bot(command_prefix="/", intents=intents)
bot = MyBot(command_prefix="/", intents=intents)
# === Bot Events ===
@bot.event
async def on_ready():
print(f"Logged in as {bot.user}")
await bot.change_presence(activity=discord.CustomActivity(name=f"🔗 spook.bio/discord"))
await bot.tree.sync()
@bot.event
async def on_member_join(member):
role = discord.utils.get(member.guild.roles, name='Member')
await member.add_roles(role)
print(f"Gave {member.name} The Member Role!")
# === Commands ===
@bot.tree.command(name="status", description="Get the spook.bio status")
async def status(interaction: discord.Interaction):
await interaction.response.send_message("[spook.bio Status Page](https://spook.bio/status)")
@bot.tree.command(name="pfp", description="Get a pfp from a user's spook.bio profile.")
async def pfp(interaction: discord.Interaction, username: str):
url = f"https://spook.bio/u/{username}/pfp.jpg"
response = requests.get(url)
if response.status_code == 200:
await interaction.response.send_message(url, ephemeral=False)
print("Fetched data successfully!")
else:
await interaction.response.send_message(f":x: {response.status_code} Not Found :x:", ephemeral=True)
print(f"Error fetching data: {response.status_code}")
@bot.tree.command(name="discord2spook", description="Get a spook.bio profile from a discord user.")
async def discord2spook(interaction: discord.Interaction, user: discord.Member): # = <@481295611417853982>):
url = f"https://api.prp.bio/discord/{user.name}"
print(url)
response = requests.get(url)
print(response.text)
if response.status_code == 200:
await interaction.response.send_message(f"{user.mention}'s [Profile]({response.text})", ephemeral=False)
print("Fetched data successfully!")
else:
if interaction.user.name == user.name:
await interaction.response.send_message(f":x: You don't have a spook.bio profile linked to your account {user.mention}! :x: To link your profile to your account please DM {owner} or {co_owner}")
return
await interaction.response.send_message(f":x: {user.mention} doesn't have a spook.bio profile linked to their account! :x:", ephemeral=False)
print(f"Error fetching data: {response.status_code}")
bot.run(token)