Skip to content

Commit 72f41b9

Browse files
authored
Merge pull request #79 from joshsoftware/feature/bot-frontend
Bot frontend
2 parents 97c2051 + 663d5d0 commit 72f41b9

File tree

21 files changed

+9113
-181
lines changed

21 files changed

+9113
-181
lines changed

Bot/app.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from fastapi.security import OAuth2AuthorizationCodeBearer
2626
from google.auth.transport.requests import Request as GoogleRequest
2727
from google.oauth2.credentials import Credentials
28+
from starlette.middleware.cors import CORSMiddleware
2829
from google_auth_oauthlib.flow import Flow
2930
from googleapiclient.discovery import build
3031
import datetime
@@ -81,6 +82,14 @@ class ScheduleBotRequest(BaseModel):
8182
meeting_end_time: str
8283

8384
app = FastAPI()
85+
app.add_middleware(
86+
CORSMiddleware,
87+
allow_origins=["*"], # Allows all origins
88+
allow_credentials=True,
89+
allow_methods=["*"], # Allows all HTTP methods
90+
allow_headers=["*"], # Allows all headers
91+
)
92+
8493
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
8594
CLIENT_SECRETS_FILE = 'credentials.json'
8695
REDIRECT_URI = "http://localhost:8000/auth/google/callback"

Bot/app/api/meetings.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@
3232
class LingoRequest(BaseModel):
3333
key: str
3434

35+
class ScheduleMeeting(BaseModel):
36+
refresh_token: str
37+
bot_name: str
38+
3539

3640
@router.get("/")
37-
def get_meetings(token: str = Depends(OAUTH2_SCHEME), refresh_token: str = Body(..., embed=True)):
41+
def get_meetings(body: ScheduleMeeting, token: str = Depends(OAUTH2_SCHEME)):
3842
logger.info("Received request to fetch and schedule meetings")
3943
creds = Credentials(
4044
token=token,
41-
refresh_token=refresh_token,
45+
refresh_token=body.refresh_token,
4246
token_uri=token_uri,
4347
client_id=client_id,
4448
client_secret=client_secret
@@ -86,7 +90,7 @@ def get_meetings(token: str = Depends(OAUTH2_SCHEME), refresh_token: str = Body(
8690
headers={"Content-Type": "application/json"},
8791
json={
8892
"meeting_url": meeting_url,
89-
"bot_name": "My Bot",
93+
"bot_name": body.bot_name,
9094
"meeting_time": meeting_time,
9195
"meeting_end_time": meeting_end_time
9296
}

Bot/app/main.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
from fastapi import FastAPI
22
from app.api import auth, meetings, scheduler
33
from app.core.scheduler import scheduler as apscheduler
4+
from starlette.middleware.cors import CORSMiddleware
45

56
app = FastAPI()
7+
app.add_middleware(
8+
CORSMiddleware,
9+
allow_origins=["*"], # Allows all origins
10+
allow_credentials=True,
11+
allow_methods=["*"], # Allows all HTTP methods
12+
allow_headers=["*"], # Allows all headers
13+
)
614

715
@app.on_event("startup")
816
def startup_event():

Bot/meeting_scheduler.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env python3
2+
3+
import asyncio
4+
import asyncpg
5+
import aiohttp
6+
7+
# --- Configuration ---
8+
PG_USER = "postgres"
9+
PG_PASS = "postgres"
10+
PG_HOST = "localhost"
11+
PG_PORT = "5432"
12+
DB_NAME = "lingo_ai"
13+
API_URL = "http://localhost:8001/meetings/"
14+
SQL_QUERY = 'SELECT "accessToken", "refreshToken", "botName" FROM bot;'
15+
PG_CONN_STRING = f"postgresql://{PG_USER}:{PG_PASS}@{PG_HOST}:{PG_PORT}/{DB_NAME}"
16+
17+
18+
# Fetch access tokens asynchronously
19+
async def fetch_data():
20+
try:
21+
conn = await asyncpg.connect(PG_CONN_STRING)
22+
rows = await conn.fetch(SQL_QUERY)
23+
await conn.close()
24+
return [
25+
{
26+
"access_token": row["accessToken"],
27+
"refresh_token": row["refreshToken"],
28+
"bot_name": row["botName"],
29+
}
30+
for row in rows
31+
]
32+
except Exception as e:
33+
print(f"[ERROR] Database error: {e}")
34+
return []
35+
36+
37+
# Make one request
38+
async def make_request(session, data):
39+
headers = {
40+
"Authorization": f"Bearer {data["access_token"]}",
41+
"Content-Type": "application/json",
42+
}
43+
body = {"refresh_token": data["refresh_token"], "bot_name": data["bot_name"]}
44+
try:
45+
async with session.get(
46+
API_URL, headers=headers, json=body, timeout=10
47+
) as response:
48+
status = response.status
49+
# text = await response.text()
50+
print(f"[INFO] Token: {data['bot_name']}: -> Status: {status}")
51+
except Exception as e:
52+
print(f"[ERROR] Token {data['bot_name']}: failed: {e}")
53+
54+
55+
# Main async workflow
56+
async def main():
57+
tokens = await fetch_data()
58+
async with aiohttp.ClientSession() as session:
59+
tasks = [make_request(session, token) for token in tokens]
60+
await asyncio.gather(*tasks)
61+
62+
63+
# Entry point
64+
if __name__ == "__main__":
65+
asyncio.run(main())
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CREATE TABLE IF NOT EXISTS "bot" (
2+
"id" text PRIMARY KEY NOT NULL,
3+
"user_id" text NOT NULL,
4+
"botName" text,
5+
"botEmail" text,
6+
"botHd" text,
7+
"botPicture" text,
8+
"accessToken" text,
9+
"refreshToken" text,
10+
"createdAt" timestamp DEFAULT now(),
11+
"updatedAt" timestamp DEFAULT now()
12+
);
13+
--> statement-breakpoint
14+
DO $$ BEGIN
15+
ALTER TABLE "bot" ADD CONSTRAINT "bot_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;
16+
EXCEPTION
17+
WHEN duplicate_object THEN null;
18+
END $$;

0 commit comments

Comments
 (0)