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.
105 lines
3.6 KiB
Python
105 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Send a capacity check-in message to each team channel.
|
|
|
|
Posts a message asking whether the team feels able to complete their project
|
|
given their current member count, and invites them to request support if needed.
|
|
|
|
Data files (place in data/):
|
|
- team_message_ids.json Channel and role IDs per team (from send_team_messages.py)
|
|
- team_assignments.json Team rosters used to report current member counts
|
|
|
|
Env vars:
|
|
- DISCORD_BOT_TOKEN Bot token for the Discord API
|
|
"""
|
|
|
|
import asyncio
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
|
|
import aiohttp
|
|
|
|
DATA_DIR = Path(__file__).parent.parent.parent / "data"
|
|
|
|
DISCORD_BOT_TOKEN = os.environ["DISCORD_BOT_TOKEN"]
|
|
NAOMI_ID = "465650873650118659"
|
|
|
|
|
|
def build_checkin_message(team_name: str, team: dict, role_id: str) -> str:
|
|
"""Build the team check-in message."""
|
|
total_members = len(team["leaders"]) + len(team["participants"])
|
|
num_leaders = len(team["leaders"])
|
|
num_participants = len(team["participants"])
|
|
|
|
leader_text = "leader" if num_leaders == 1 else "leaders"
|
|
participant_text = "participant" if num_participants == 1 else "participants"
|
|
|
|
return f"""## Team Check-In
|
|
|
|
Your team currently has **{total_members} members** ({num_leaders} {leader_text} + {num_participants} {participant_text}).
|
|
|
|
Given the recent changes to team size, we want to make sure you feel confident moving forward with your project. Please discuss as a team and let us know:
|
|
|
|
**Do you feel you can still complete your project with your current team size?**
|
|
|
|
If you have concerns about capacity, need additional support, or would like to discuss options (such as combining with another team or adjusting project scope), please ping <@{NAOMI_ID}> and we'll work together to find a solution.
|
|
|
|
Your success is the priority here - we want to make sure every team has what they need to build something amazing! 💜
|
|
|
|
-# <@&{role_id}>"""
|
|
|
|
|
|
async def send_message(
|
|
session: aiohttp.ClientSession, channel_id: str, content: str
|
|
) -> dict | None:
|
|
"""Send a message to a Discord channel."""
|
|
url = f"https://discord.com/api/v10/channels/{channel_id}/messages"
|
|
headers = {
|
|
"Authorization": f"Bot {DISCORD_BOT_TOKEN}",
|
|
"Content-Type": "application/json",
|
|
}
|
|
payload = {"content": content}
|
|
|
|
async with session.post(url, headers=headers, json=payload) as resp:
|
|
if resp.status in [200, 201]:
|
|
return await resp.json()
|
|
error_text = await resp.text()
|
|
print(
|
|
f"❌ Failed to send message to channel {channel_id}: {resp.status} - {error_text}" # noqa: E501
|
|
)
|
|
return None
|
|
|
|
|
|
async def main() -> None:
|
|
"""Send check-in messages to all teams."""
|
|
with open(DATA_DIR / "team_message_ids.json") as f:
|
|
team_data = json.load(f)
|
|
|
|
with open(DATA_DIR / "team_assignments.json") as f:
|
|
teams = json.load(f)
|
|
|
|
async with aiohttp.ClientSession() as session:
|
|
print("📢 Sending team check-in messages...\n")
|
|
|
|
for team in teams:
|
|
team_name = team["name"]
|
|
channel_id = team_data[team_name]["channel_id"]
|
|
role_id = team_data[team_name]["role_id"]
|
|
|
|
print(f"Processing {team_name}...")
|
|
|
|
checkin_msg = build_checkin_message(team_name, team, role_id)
|
|
result = await send_message(session, channel_id, checkin_msg)
|
|
|
|
if result:
|
|
total = len(team["leaders"]) + len(team["participants"])
|
|
print(f" ✅ Sent check-in ({total} members)")
|
|
|
|
await asyncio.sleep(2)
|
|
|
|
print("\n✨ Done sending all team check-in messages!")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|