UNPKG

@firefliesai/fireflies-node-sdk

Version:
393 lines (392 loc) 13.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.FirefliesSDK = void 0; const axios_1 = __importDefault(require("axios")); const helper_js_1 = require("./helper.js"); class FirefliesSDK { constructor(config) { this.client = axios_1.default.create({ baseURL: config.baseURL || FirefliesSDK.DEFAULT_BASE_URL, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${config.apiKey}` } }); } async executeGraphQL(query, variables = {}) { var _a, _b, _c; try { const response = await this.client.post('', { query, variables }); // GraphQL responses always have a data property containing the actual response return response.data.data; } catch (error) { if (axios_1.default.isAxiosError(error)) { console.log((_a = error.response) === null || _a === void 0 ? void 0 : _a.data); throw new Error(`Fireflies API Error: ${((_c = (_b = error.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.message) || error.message}`); } throw error; } } async getAIAppsOutputs(params = {}, filter) { const query = ` query GetAIAppsOutputs($app_id: String, $transcript_id: String, $skip: Float, $limit: Float) { apps(app_id: $app_id, transcript_id: $transcript_id, skip: $skip, limit: $limit) { outputs { ${(0, helper_js_1.generateGraphQLFilter)(filter)} } } } `; const response = await this.executeGraphQL(query, params); return response.apps.outputs; } async getUser(userId, filter = []) { const query = ` query User($userId: String) { user(id: $userId) { ${(0, helper_js_1.generateGraphQLFilter)(filter)} } } `; const response = await this.executeGraphQL(query, userId ? { userId } : {}); return response.user; } async getUsers(filter = []) { const query = ` query Users { users { ${(0, helper_js_1.generateGraphQLFilter)(filter)} } } `; const response = await this.executeGraphQL(query, {}); return response.users; } async getCurrentUser(filter = []) { return this.getUser('', filter); } async getTranscript(transcriptId, filter = []) { const query = ` query Transcript($transcriptId: String!) { transcript(id: $transcriptId) { ${(0, helper_js_1.generateGraphQLFilter)(filter)} } } `; const response = await this.executeGraphQL(query, { transcriptId }); return response.transcript; } async getTranscripts(params = {}, filter = []) { const query = ` query Transcripts( $title: String $date: Float $limit: Int $skip: Int $hostEmail: String $participantEmail: String $userId: String $mine: Boolean ) { transcripts( title: $title date: $date limit: $limit skip: $skip host_email: $hostEmail participant_email: $participantEmail user_id: $userId mine: $mine ) { ${(0, helper_js_1.generateGraphQLFilter)(filter)} } } `; const response = await this.executeGraphQL(query, { ...params, hostEmail: params.host_email, organizerEmail: params.organizer_email, participantEmail: params.participant_email, userId: params.user_id }); return response.transcripts; } async getBite(biteId, filter = []) { const query = ` query Bite($biteId: ID!) { bite(id: $biteId) { ${(0, helper_js_1.generateGraphQLFilter)(filter)} } } `; const response = await this.executeGraphQL(query, { biteId }); return response.bite; } async getBites(params = {}, filter = []) { const query = ` query Bites($mine: Boolean, $transcript_id: ID, $my_team: Boolean, $limit: Int) { bites(mine: $mine, transcript_id: $transcript_id, my_team: $my_team, limit: $limit) { ${(0, helper_js_1.generateGraphQLFilter)(filter)} } } `; const response = await this.executeGraphQL(query, params); return response.bites; } async setUserRole(userId, role) { const query = ` mutation SetUserRole($userId: String!, $role: Role!) { setUserRole(user_id: $userId, role: $role) { name is_admin } } `; const response = await this.executeGraphQL(query, { userId, role }); return response.setUserRole; } async deleteTranscript(transcriptId) { const query = ` mutation DeleteTranscript($transcriptId: String!) { deleteTranscript(id: $transcriptId) { title date duration organizer_email } } `; const response = await this.executeGraphQL(query, { transcriptId }); return response.deleteTranscript; } async uploadAudio(input) { const query = ` mutation UploadAudio($input: AudioUploadInput!) { uploadAudio(input: $input) { success title message } } `; const response = await this.executeGraphQL(query, { input }); return response.uploadAudio; } async createBite(input) { const query = ` mutation CreateBite( $transcript_id: ID!, $name: String, $start_time: Float!, $end_time: Float!, $media_type: String, $privacies: [String], $summary: String ) { createBite( transcript_id: $transcript_id, name: $name, start_time: $start_time, end_time: $end_time, media_type: $media_type, privacies: $privacies, summary: $summary ) { status name id } } `; const response = await this.executeGraphQL(query, input); return response.createBite; } async addToLiveMeeting(input) { const query = ` mutation AddToLiveMeeting( $meeting_link: String! $title: String $meeting_password: String $duration: Int $language: String $attendees: [Attendee] ) { addToLiveMeeting( meeting_link: $meeting_link title: $title meeting_password: $meeting_password duration: $duration language: $language attendees: $attendees ) { success } } `; const response = await this.executeGraphQL(query, input); return response.addToLiveMeeting; } /** * Get meetings/transcripts for multiple users by providing a list of API keys. * This implementation includes batch processing, rate limiting, and deduplication of meetings. * @param apiKeys - Array of API keys for different users * @param filter - Fields to include in the response * @param outputType - Type of output ('console' or 'json') * @returns Promise<{ [key: string]: BatchProcessResult }> */ static async getMeetingsForMultipleUsers(apiKeys, filter = [], outputType = 'console') { if (!apiKeys.length) { throw new Error('Please provide at least one API key'); } const deduplicatedObj = await helper_js_1.MeetingsHelper.getDedeuplicatedMeetingIds(apiKeys); const results = {}; for (const apiKey of Object.keys(deduplicatedObj)) { const tasks = deduplicatedObj[apiKey].map(item => async () => { const sdk = new FirefliesSDK({ apiKey }); return { data: { transcript: await sdk.getTranscript(item, filter) } }; }); try { const result = await helper_js_1.MeetingsHelper.batchProcess(tasks, apiKey); results[apiKey] = result; // Handle output await helper_js_1.MeetingsHelper.handleOutput(result, apiKey, outputType); } catch (error) { if (error instanceof Error) { console.error(`An error occurred while fetching meetings for apiKey: ${apiKey}`, error.message); } results[apiKey] = { meetings: [], errors: [error instanceof Error ? error.message : 'Unknown error'] }; } } return results; } /** * Find questions asked by external participants in meetings * @param companyEmailDomain - Your company email domain (e.g. '@company.com') * @returns Promise<{ externalParticipants: string[], questions: string[] }> */ async findExternalParticipantQuestions(companyEmailDomain) { if (!companyEmailDomain.startsWith('@')) { throw new Error('Company email domain must start with @'); } const query = ` query Transcripts { transcripts { participants sentences { ai_filters { question } speaker_name } } } `; const response = await this.executeGraphQL(query); const results = response.transcripts; // Find external participants by querying emails != companyEmailDomain const externalParticipants = [ ...new Set(results .map(transcript => transcript.participants .filter(participant => !participant.endsWith(companyEmailDomain)) .map(email => email.split('@')[0])) .flat()) ]; // Find questions from external participants by comparing speaker_name to email const questionsFromExternalParticipants = results .map(transcript => transcript.sentences .filter(sentence => { if (!sentence.speaker_name) { return false; } const regexPattern = new RegExp('^' + sentence.speaker_name.split(' ')[0], 'i'); return (externalParticipants.some(participant => regexPattern.test(participant)) && sentence.ai_filters.question && sentence.speaker_name); }) .map(sentence => `${sentence.speaker_name}: ${sentence.ai_filters.question}`)) .flat() .filter(Boolean); return { externalParticipants, questions: questionsFromExternalParticipants }; } /** * Get video URLs from meetings/transcripts * @returns Promise<Array<{ id: string, title: string, video_url: string | null }>> */ async getMeetingVideos() { const query = ` query Transcripts { transcripts { id title video_url } } `; const response = await this.executeGraphQL(query); return response.transcripts; } /** * Get summary of a specific transcript/meeting * @param transcriptId - ID of the transcript to get summary for * @returns Promise<Summary> */ async getTranscriptSummary(transcriptId) { const query = ` query Transcript($transcriptId: String!) { transcript(id: $transcriptId) { summary { keywords action_items outline shorthand_bullet overview bullet_gist gist short_summary short_overview meeting_type topics_discussed transcript_chapters } } } `; const response = await this.executeGraphQL(query, { transcriptId }); return response.transcript.summary; } } exports.FirefliesSDK = FirefliesSDK; FirefliesSDK.DEFAULT_BASE_URL = 'https://api.fireflies.ai/graphql'; // Re-export types for convenience __exportStar(require("./types"), exports);