UNPKG

@lautmaler/crm-connectors

Version:

Provides connectors to various CRM systems and calendar services.

135 lines (120 loc) 4.23 kB
import axios from "axios"; import winston from "winston"; import { Appointment, CRMBackend } from "../crm.interfaces.js"; const CALENDLY_API_KEY = process.env.CALENDLY_API_KEY || ""; const CALENDLY_USER_URI = process.env.CALENDLY_USER_URI || ""; // Fetch this dynamically if needed export class CalendlyBackend implements CRMBackend { private logger: any; private apiClient: any; constructor() { this.logger = winston.createLogger({ level: "info", format: winston.format.json(), defaultMeta: { service: "crm-service" }, transports: [ new winston.transports.Console({ format: winston.format.simple(), }), ], }); if (!CALENDLY_API_KEY) { this.logger.warn("Calendly API key is missing"); } this.apiClient = axios.create({ baseURL: "https://api.calendly.com", headers: { Authorization: `Bearer ${CALENDLY_API_KEY}`, "Content-Type": "application/json", }, }); } fetchAppointmentTypes(): Promise<string[]> { throw new Error("Method not implemented."); } bookAppointment(appointment: Appointment): Promise<string> { try { return this.createEvent(appointment); } catch (error) { this.logger.error("Error booking appointment:", error); throw new Error("Failed to book appointment"); } } modifyAppointment( // eslint-disable-next-line @typescript-eslint/no-unused-vars id: string, // eslint-disable-next-line @typescript-eslint/no-unused-vars updatedInfo: Partial<Appointment>, ): Promise<Appointment> { throw new Error("Method not implemented."); } // eslint-disable-next-line @typescript-eslint/no-unused-vars findAppointmentByContactName(name: string): Promise<Appointment> { throw new Error("Method not implemented."); } // eslint-disable-next-line @typescript-eslint/no-unused-vars findAppointmentByTimestamp(timestamp: string): Promise<Appointment | null> { throw new Error("Method not implemented."); } // eslint-disable-next-line @typescript-eslint/no-unused-vars findAppointmentById(id: string): Promise<Appointment | null> { throw new Error("Method not implemented."); } async fetchAvailableSlots(): Promise<string[]> { try { const availableSlots = await this.calendalyGetAvailability( CALENDLY_USER_URI, new Date().toISOString(), new Date(Date.now() + 86400000).toISOString(), ); return availableSlots; } catch (error) { this.logger.error("Error fetching available slots:", error); throw new Error("Failed to fetch available slots"); } } async calendalyGetAvailability( userUri: string, startTime: string, endTime: string, ): Promise<string[]> { try { const response = await this.apiClient.get("/scheduling_links", { params: { user: userUri, start_time: startTime, end_time: endTime, }, }); this.logger.info("Available slots fetched successfully"); return response.data as string[]; } catch (error) { this.logger.error("Error fetching available slots:", error); throw new Error("Failed to fetch available slots"); } } async createEvent(appointment: Appointment): Promise<string> { const attendees = [ { email: appointment.contactEmail }, { email: appointment.employeeEmail }, ]; const startTime = appointment.timestamp; const duration = "60"; // 60 minutes try { const payload = { event_type: `${CALENDLY_USER_URI}/event_types`, start_time: startTime, invitees: attendees.map((attendee) => ({ email: attendee.email })), duration: duration, }; const response = await this.apiClient.post("/scheduled_events", payload); this.logger.info("Event scheduled successfully", response.data); return response.data.resource.uri; // Returns the event link } catch (error) { this.logger.error("Error scheduling event:", error); throw new Error("Failed to schedule event"); } } async createEventToSms(appointment: Appointment): Promise<string> { throw new Error("Method not implemented."); } }