Spaces:
Runtime error
Runtime error
refactor authentication flow by removing unused middleware and simplifying user sign-in response
d697ce3 | import os | |
| import json | |
| import aiohttp | |
| import pytz | |
| from datetime import datetime, timedelta | |
| from src.models import User | |
| from src.repositories import UserRepository | |
| from src.utils import MeetingUtils | |
| class MeetingService: | |
| def __init__(self): | |
| self.utils = MeetingUtils | |
| self.user_repository = UserRepository() | |
| async def __aenter__(self): | |
| return self | |
| async def __aexit__(self, *args): | |
| pass | |
| async def get_available_salesperson_meetings(self): | |
| request_url = ( | |
| os.getenv("HUBSPOT_BASE_URL") + "/scheduler/v3/meetings/meeting-links" | |
| ) | |
| headers = {"authorization": f"Bearer {os.getenv('HUBSPOT_API_KEY')}"} | |
| async with aiohttp.ClientSession() as session: | |
| async with session.get(request_url, headers=headers) as response: | |
| response_status = response.status | |
| response = json.loads(await response.text()) | |
| if response_status != 200: | |
| return f"status: {response_status}, message: {response['message']}" | |
| result = { | |
| "total": response["total"], | |
| "results": [ | |
| { | |
| "salesperson_id": result["slug"], | |
| # "link": result["link"], | |
| } | |
| for result in response["results"] | |
| ], | |
| } | |
| return result | |
| async def get_available_slots(self, salesperson_meeting_id: str, timezone: str): | |
| request_url = ( | |
| os.getenv("HUBSPOT_BASE_URL") | |
| + f"/scheduler/v3/meetings/meeting-links/book/availability-page/{salesperson_meeting_id}?timezone={timezone}" | |
| ) | |
| print(request_url) | |
| headers = {"authorization": f"Bearer {os.getenv('HUBSPOT_API_KEY')}"} | |
| async with aiohttp.ClientSession() as session: | |
| async with session.get(request_url, headers=headers) as response: | |
| availability_response = json.loads(await response.text()) | |
| if response.status != 200: | |
| return f"status: {response.status}, message: {availability_response['message']}" | |
| pytz_timezone = pytz.timezone(timezone) | |
| dt = datetime.now(pytz_timezone) | |
| offset_hours = dt.utcoffset().total_seconds() / 3600 | |
| current_time = dt.strftime("%Y-%m-%d %H:%M:%S") | |
| final_response = ( | |
| f"The Current Time is {current_time} as per the timezone {timezone} :\n" | |
| ) | |
| for duration_str, availability_info in availability_response[ | |
| "linkAvailability" | |
| ]["linkAvailabilityByDuration"].items(): | |
| duration_ms = int(duration_str) | |
| final_response += f"The following slots are available for {duration_ms / 60000} minutes:\nHere is the Start time for each available slot:\n" | |
| async with self.utils() as utils: | |
| available_slots = await utils.check_availability( | |
| response=availability_response, | |
| duration_ms=duration_ms, | |
| offset=offset_hours, | |
| ) | |
| if available_slots: | |
| final_response += "Please use the following table to present the data in a better way:\n" | |
| final_response += f"Timezone: {timezone}\n" | |
| final_response += "Available slots:\n" | |
| final_response += "-----------------------------\n" | |
| for slot in available_slots: | |
| final_response += f"{slot['start']}\n" | |
| final_response += "-----------------------------\n" | |
| else: | |
| final_response += "No availability found for this duration.\n" | |
| return final_response | |
| async def schedule_meeting( | |
| self, | |
| user_id: str, | |
| salesperson_meeting_id: str, | |
| preferred_start_time: datetime, | |
| duration: int, | |
| timezone: str, | |
| locale: str = "en-us", | |
| ): | |
| user_object: User = await self.user_repository.get_by_id(user_id) | |
| user_name = user_object.name | |
| user_email = user_object.email | |
| pytz_timezone = pytz.timezone(timezone) | |
| dt = datetime.now(pytz_timezone) | |
| offset_hours = dt.utcoffset().total_seconds() / 3600 | |
| if isinstance(preferred_start_time, str): | |
| preferred_start_time = datetime.strptime( | |
| preferred_start_time, "%Y-%m-%d %H:%M:%S" | |
| ) | |
| preferred_start_time = preferred_start_time - timedelta(hours=offset_hours) | |
| async with self.utils() as utils: | |
| preferred_start_time = await utils.get_millis_utc(preferred_start_time) | |
| duration_ms = duration * 60000 | |
| url = ( | |
| os.getenv("HUBSPOT_BASE_URL") + "/scheduler/v3/meetings/meeting-links/book" | |
| ) | |
| headers = { | |
| "authorization": f"Bearer {os.getenv('HUBSPOT_API_KEY')}", | |
| "content-type": "application/json", | |
| } | |
| data = { | |
| "slug": salesperson_meeting_id, | |
| "firstName": user_name, | |
| "lastName": "", | |
| "email": user_email, | |
| "startTime": preferred_start_time, | |
| "duration": duration_ms, | |
| "guestEmails": [], | |
| "timezone": timezone, | |
| "locale": locale, | |
| "likelyAvailableUserIds": [], | |
| } | |
| async with aiohttp.ClientSession() as session: | |
| async with session.post(url, headers=headers, json=data) as response: | |
| response_status = response.status | |
| response = await response.text() | |
| response = json.loads(response) | |
| if response_status != 200: | |
| return f"status: {response_status}, message: {response['message']}" | |
| return { | |
| "status": "success", | |
| "calendarEventId": response["calendarEventId"], | |
| "meeting title": response["subject"], | |
| "meeting url": response["webConferenceUrl"], | |
| "start": datetime.strptime(response["start"], "%Y-%m-%dT%H:%M:%SZ"), | |
| "end": datetime.strptime(response["end"], "%Y-%m-%dT%H:%M:%SZ"), | |
| "duration in minutes": response["duration"] / 60000, | |
| "contactId": response["contactId"], | |
| "timezone": response["bookingTimezone"], | |
| } | |