-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpatreonfix.py
91 lines (71 loc) · 2.64 KB
/
patreonfix.py
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
from asyncio import sleep
from os import getenv
from typing import Dict, List, Final
from dotenv import load_dotenv
from disnake import (
Intents,
Activity,
Status,
AuditLogEntry,
AuditLogAction,
Role,
Client,
Member,
)
load_dotenv()
if getenv("PROXY_URL"):
from disnake.http import Route
Route.BASE = getenv("PROXY_URL")
ROLE_UPDATE: Dict[int, List[Role]] = {}
PATREON_DISCORD_BOT_ID: Final[int] = int(getenv("PATREON_DISCORD_BOT_ID"))
PATREON_ROLE_ID: Final[int] = int(getenv("PATREON_ROLE_ID"))
SLEEP_DURATION: Final[int] = int(getenv("SLEEP_DURATION"))
INTENTS: Final[Intents] = Intents(
members=True,
moderation=True,
)
client: Client = Client(
intents=INTENTS,
status=Status.dnd,
activity=Activity(name=f"Patreons bot make mistakes.", type=3),
)
async def wait_and_check(entry: AuditLogEntry) -> None:
# Wait for all roles to be removed by the Patreon bot.
await sleep(SLEEP_DURATION)
targeted_member: Member = (
entry.guild.get_member(entry.target.id) # Get member obj from cache.
or await entry.guild.fetch_member(entry.target.id) # Fetch new member obj if not in cache.
)
removed_roles: List[Role] = [role for role in ROLE_UPDATE[entry.target.id]]
removed_role_ids: List[int] = [role.id for role in removed_roles]
if PATREON_ROLE_ID in removed_role_ids:
# Patreon is removing roles from someone it should be removing roles from.
return
for role in removed_roles:
# Add roles back that patreon mistakenly removed.
await targeted_member.add_roles(
role,
reason="Adding role back that Patreon removed.",
)
# Remove member removed role information from cache.
del ROLE_UPDATE[entry.target.id]
@client.event
async def on_connect() -> None:
print("Bot has connected to the Discord gateway")
@client.event
async def on_audit_log_entry_create(entry: AuditLogEntry) -> None:
if (
entry.user.id == PATREON_DISCORD_BOT_ID
and entry.action == AuditLogAction.member_role_update
and len(entry.changes.before.roles) == 1 # Role was removed rather than added.
):
removed_role: Role = entry.changes.before.roles[0]
targeted_user: User = entry.target
if ROLE_UPDATE.get(targeted_user.id, None) is None:
# The Patreon bot hasn't removed any roles yet.
ROLE_UPDATE[targeted_user.id] = [removed_role]
return await wait_and_check(entry)
# Store addtional roles that the Patreon bot removes.
ROLE_UPDATE[targeted_user.id].append(removed_role)
# Run the bot
client.run(getenv("DISCORD_BOT_TOKEN"))