Skip to content
This repository was archived by the owner on Mar 12, 2025. It is now read-only.

Commit 6c8eb1b

Browse files
committed
refactor: factor out Zoom, Jitsi, and w2g code into a package
1 parent 930d069 commit 6c8eb1b

File tree

2 files changed

+65
-43
lines changed

2 files changed

+65
-43
lines changed

bot.py

+15-43
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import asyncio
2-
import base64
32
import datetime as dt
43
import difflib
54
import logging
65
import random
76
import re
8-
import uuid
97
from contextlib import suppress
108
from typing import Optional
119
from urllib.parse import quote_plus
@@ -22,6 +20,7 @@
2220
import handshapes
2321
import cuteid
2422
import catchphrase
23+
import meetings
2524

2625
# -----------------------------------------------------------------------------
2726

@@ -370,26 +369,6 @@ async def idiom_command(ctx, spoiler: Optional[str]):
370369
# -----------------------------------------------------------------------------
371370

372371

373-
async def create_meeting():
374-
async with aiohttp.ClientSession() as client:
375-
resp = await client.post(
376-
f"https://api.zoom.us/v2/users/{ZOOM_USER_ID}/meetings",
377-
json={
378-
"type": 1,
379-
"topic": "PRACTICE",
380-
"settings": {
381-
"host_video": False,
382-
"participant_video": False,
383-
"mute_upon_entry": True,
384-
"waiting_room": False,
385-
},
386-
},
387-
headers={"Authorization": f"Bearer {ZOOM_JWT}"},
388-
)
389-
resp.raise_for_status()
390-
return await resp.json()
391-
392-
393372
ZOOM_TEMPLATE = """**Join URL**: {join_url}
394373
**Passcode**: {passcode}
395374
🚀 This meeting is happening now. Go practice!
@@ -406,15 +385,25 @@ async def zoom_command(ctx: Context):
406385
message = await ctx.send("Creating meeting...")
407386
logger.info("creating zoom meeting")
408387
try:
409-
data = await create_meeting()
388+
meeting = await meetings.create_zoom(
389+
token=ZOOM_JWT,
390+
user_id=ZOOM_USER_ID,
391+
topic="PRACTICE",
392+
settings={
393+
"host_video": False,
394+
"participant_video": False,
395+
"mute_upon_entry": True,
396+
"waiting_room": False,
397+
},
398+
)
410399
except Exception:
411400
logger.exception("could not create Zoom meeting")
412401
await message.edit(
413402
content="🚨 _Could not create Zoom meeting. That's embarrassing._"
414403
)
415404
else:
416405
content = ZOOM_TEMPLATE.format(
417-
join_url=data["join_url"], passcode=data["password"]
406+
join_url=meeting.join_url, passcode=meeting.passcode
418407
)
419408
await message.edit(content=content, suppress=True)
420409

@@ -441,13 +430,9 @@ async def zoom_error(ctx, error):
441430
MEET_CLOSED_MESSAGE = "✨ _Jitsi Meet ended_"
442431

443432

444-
def pretty_uuid() -> str:
445-
return base64.urlsafe_b64encode(uuid.uuid4().bytes).decode().replace("=", "")
446-
447-
448433
@bot.command(name="meet", aliases=("jitsi",), help="Start a Jitsi Meet meeting")
449434
async def meet_command(ctx: Context):
450-
join_url = f"https://meet.jit.si/{pretty_uuid()}"
435+
join_url = meetings.create_jitsi_meet()
451436
content = MEET_TEMPLATE.format(join_url=join_url)
452437
logger.info("sending jitsi meet info")
453438
message = await ctx.send(content=content)
@@ -458,19 +443,6 @@ async def meet_command(ctx: Context):
458443
# -----------------------------------------------------------------------------
459444

460445

461-
async def create_watch2gether(video_url: Optional[str]) -> str:
462-
async with aiohttp.ClientSession() as client:
463-
payload = {"api_key": WATCH2GETHER_API_KEY}
464-
if payload:
465-
payload["share"] = video_url
466-
resp = await client.post("https://w2g.tv/rooms/create.json", json=payload)
467-
resp.raise_for_status()
468-
data = await resp.json()
469-
stream_key = data["streamkey"]
470-
url = f"https://w2g.tv/rooms/{stream_key}"
471-
return url
472-
473-
474446
WATCH2GETHER_HELP = """Create a new watch2gether room
475447
476448
You can optionally pass a URL to use for the first video.
@@ -506,7 +478,7 @@ async def watch2gether_command(ctx: Context, video_url: str = None):
506478
message = await ctx.send("Creating watch2gether room...")
507479
logger.info("creating watch2gether meeting")
508480
try:
509-
url = await create_watch2gether(video_url)
481+
url = await meetings.create_watch2gether(WATCH2GETHER_API_KEY, video_url)
510482
except Exception:
511483
logger.exception("could not create watch2gether room")
512484
await message.edit(

lib/meetings/__init__.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import base64
2+
import uuid
3+
from typing import NamedTuple
4+
5+
import aiohttp
6+
7+
8+
class ZoomMeeting(NamedTuple):
9+
join_url: str
10+
passcode: str
11+
12+
13+
async def create_zoom(
14+
*, token: str, user_id: str, topic: str, settings: dict
15+
) -> ZoomMeeting:
16+
"""Create and return a Zoom meeting via the Zoom API."""
17+
async with aiohttp.ClientSession() as client:
18+
resp = await client.post(
19+
f"https://api.zoom.us/v2/users/{user_id}/meetings",
20+
json={
21+
"type": 1,
22+
"topic": topic,
23+
"settings": settings,
24+
},
25+
headers={"Authorization": f"Bearer {token}"},
26+
)
27+
resp.raise_for_status()
28+
data = await resp.json()
29+
return ZoomMeeting(join_url=data["join_url"], passcode=data["password"])
30+
31+
32+
def _pretty_uuid() -> str:
33+
return base64.urlsafe_b64encode(uuid.uuid4().bytes).decode().replace("=", "")
34+
35+
36+
def create_jitsi_meet() -> str:
37+
"""Return a Jitsi Meet URL with a unique ID."""
38+
return f"https://meet.jit.si/{_pretty_uuid()}"
39+
40+
41+
async def create_watch2gether(api_key: str, video_url: str = None) -> str:
42+
"""Create and return a watch2gether URL via the watch2gether API."""
43+
async with aiohttp.ClientSession() as client:
44+
payload = {"api_key": api_key, "video_url": video_url}
45+
resp = await client.post("https://w2g.tv/rooms/create.json", json=payload)
46+
resp.raise_for_status()
47+
data = await resp.json()
48+
stream_key = data["streamkey"]
49+
url = f"https://w2g.tv/rooms/{stream_key}"
50+
return url

0 commit comments

Comments
 (0)