generated from nhcarrigan/template
a40188413a
All Python cohort scripts now use DATA_DIR = Path(__file__).parent.parent.parent / "data" to correctly resolve the repo-root data/ directory regardless of the working directory set by run.sh. All TypeScript scripts have expanded JSDoc headers documenting data file requirements and environment variables.
117 lines
3.2 KiB
Python
117 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Remove the Cohort and team-specific Discord roles from a list of members.
|
|
|
|
Update INACTIVE_MEMBERS and MEMBER_TO_TEAM before running to target the correct
|
|
members. Removes both the cohort-wide role and the member's team role.
|
|
|
|
Data files (place in data/):
|
|
- None (member IDs and team mappings are defined as constants in the script)
|
|
|
|
Env vars:
|
|
- DISCORD_BOT_TOKEN Bot token for the Discord API
|
|
"""
|
|
|
|
import asyncio
|
|
import os
|
|
|
|
import aiohttp
|
|
|
|
DISCORD_BOT_TOKEN = os.environ["DISCORD_BOT_TOKEN"]
|
|
GUILD_ID = "1354624415861833870"
|
|
BASE_URL = "https://discord.com/api/v10"
|
|
|
|
INACTIVE_MEMBERS = [
|
|
"1177481351490981889",
|
|
"899092786802987069",
|
|
"1318882254365397032",
|
|
"680429718511943770",
|
|
"1195902319976521748",
|
|
"1424001797072359576",
|
|
"1333378962289590365",
|
|
"799293680799711273",
|
|
"1183395404293869662",
|
|
"1325958873831440566",
|
|
"717028253633871965",
|
|
"847789364217905182",
|
|
"746703502369095700",
|
|
"192541018908786690",
|
|
"1017761694514163712",
|
|
]
|
|
|
|
COHORT_ROLE_ID = "1464314780935258112"
|
|
TEAM_ROLE_IDS = {
|
|
1: "1464314923780931677",
|
|
2: "1464315093402784015",
|
|
3: "1464315098452726106",
|
|
4: "1464315105264275600",
|
|
5: "1464315109873684593",
|
|
6: "1464315114378498152",
|
|
7: "1464315118904152107",
|
|
8: "1464315124251754559",
|
|
9: "1464315128437801177",
|
|
10: "1464315132896088168",
|
|
11: "1464315138428633241",
|
|
12: "1464315142710890520",
|
|
13: "1464315149203804405",
|
|
14: "1464315153599299803",
|
|
}
|
|
|
|
MEMBER_TO_TEAM = {
|
|
"1177481351490981889": 1,
|
|
"899092786802987069": 1,
|
|
"1318882254365397032": 2,
|
|
"680429718511943770": 2,
|
|
"1195902319976521748": 3,
|
|
"1424001797072359576": 4,
|
|
"1333378962289590365": 4,
|
|
"799293680799711273": 5,
|
|
"1183395404293869662": 7,
|
|
"1325958873831440566": 8,
|
|
"717028253633871965": 8,
|
|
"847789364217905182": 10,
|
|
"746703502369095700": 10,
|
|
"192541018908786690": 11,
|
|
"1017761694514163712": 13,
|
|
}
|
|
|
|
|
|
async def remove_role(
|
|
session: aiohttp.ClientSession, user_id: str, role_id: str
|
|
) -> bool:
|
|
"""Remove a role from a user."""
|
|
url = f"{BASE_URL}/guilds/{GUILD_ID}/members/{user_id}/roles/{role_id}"
|
|
headers = {"Authorization": f"Bot {DISCORD_BOT_TOKEN}"}
|
|
|
|
async with session.delete(url, headers=headers) as resp:
|
|
if resp.status == 204:
|
|
return True
|
|
text = await resp.text()
|
|
print(f" Error removing role {role_id} from {user_id}: {resp.status} - {text}")
|
|
return False
|
|
|
|
|
|
async def main() -> None:
|
|
"""Remove roles from all inactive members."""
|
|
async with aiohttp.ClientSession() as session:
|
|
print("Removing roles from inactive members...\n")
|
|
|
|
for member_id in INACTIVE_MEMBERS:
|
|
print(f"Processing {member_id}...")
|
|
|
|
if await remove_role(session, member_id, COHORT_ROLE_ID):
|
|
print(" ✓ Removed cohort role")
|
|
|
|
if member_id in MEMBER_TO_TEAM:
|
|
team_id = MEMBER_TO_TEAM[member_id]
|
|
team_role_id = TEAM_ROLE_IDS[team_id]
|
|
if await remove_role(session, member_id, team_role_id):
|
|
print(f" ✓ Removed Team {team_id} role")
|
|
|
|
await asyncio.sleep(1.5)
|
|
|
|
print("\nDone!")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|