keepme-backend / src /services /_meeting_service.py
narinder1231's picture
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"],
}