# Fireflies Automatically (with cli util : webhook not working and no cron added) captures meeting notes with AI-generated summaries and insights from Fireflies.ai into your Twenty CRM. ## Current Status - Doesn't work with Fireflies webhook yet due to missing headers forwarding in twenty serverless func - Meeting ingestion utility script are available for individual meeting insertion and historical meetings with filters with yarn meeting:all - You have to push the secrets as application.config.ts values (despite env variables in .env in docker compose or container I couldn't push the secrets with the cli) ## Current Platform Limitation (Headers) - Twenty serverless route triggers currently do **not forward HTTP headers** to functions. Fireflies signatures sent in headers are stripped, so header-based verification does not work in production. - Workaround: the provided test script also includes the signature inside the payload; the handler falls back to that payload signature. Use this only for testing until header forwarding is supported. ## Utilities for meeting insertion (workarounds) - Ingest a specific Fireflies meeting into Twenty: `yarn meeting:ingest <meetingId>` or `MEETING_ID=... yarn meeting:ingest` - Fetch all/historical Fireflies meetings into Twenty: `yarn meeting:all [--from 2024-01-01] [--to 2024-02-01] [--organizer a@x.com] [--participant b@x.com] [--channel <channelId>] [--mine] [--dry-run]` - Filters (combine as needed): - `--from` / `--to`: ISO or date string range filter - `--organizer` / `--participant`: comma-separated emails - `--channel`: Fireflies channel id - `--mine`: only meetings for the current Fireflies user - Controls: - `--dry-run`: list and transform without writing to Twenty - `--page-size`: pagination size (default 50) - `--max-records`: stop after N transcripts (default 500) I am closing previous #16378 as this one includes it all
42 lines
1.6 KiB
TypeScript
42 lines
1.6 KiB
TypeScript
import { FIREFLIES_PLANS, type FirefliesPlan, type SummaryFetchConfig, type SummaryStrategy } from './types';
|
|
|
|
export const toBoolean = (value: string | undefined, defaultValue: boolean): boolean => {
|
|
if (value === undefined) return defaultValue;
|
|
const normalized = value.trim().toLowerCase();
|
|
return normalized === 'true' || normalized === '1' || normalized === 'yes';
|
|
};
|
|
|
|
export const getApiUrl = (): string => {
|
|
return process.env.SERVER_URL || 'http://localhost:3000';
|
|
};
|
|
|
|
export const getSummaryFetchConfig = (): SummaryFetchConfig => {
|
|
const strategy = (process.env.FIREFLIES_SUMMARY_STRATEGY as SummaryStrategy) || 'immediate_with_retry';
|
|
|
|
// Ultra-conservative defaults to respect 50 requests/day API limit
|
|
// With 3 attempts at 15-minute intervals, max 3 API calls per webhook (45 minutes total)
|
|
return {
|
|
strategy,
|
|
retryAttempts: parseInt(process.env.FIREFLIES_RETRY_ATTEMPTS || '3', 10),
|
|
retryDelay: parseInt(process.env.FIREFLIES_RETRY_DELAY || '120000', 10), // 2 minutes
|
|
pollInterval: parseInt(process.env.FIREFLIES_POLL_INTERVAL || '120000', 10), // 2 minutes
|
|
maxPolls: parseInt(process.env.FIREFLIES_MAX_POLLS || '3', 10),
|
|
};
|
|
};
|
|
|
|
export const shouldAutoCreateContacts = (): boolean => {
|
|
return toBoolean(process.env.AUTO_CREATE_CONTACTS, true);
|
|
};
|
|
|
|
export const getFirefliesPlan = (): FirefliesPlan => {
|
|
const plan = (process.env.FIREFLIES_PLAN || FIREFLIES_PLANS.FREE).toLowerCase();
|
|
if (plan === FIREFLIES_PLANS.BUSINESS || plan === FIREFLIES_PLANS.ENTERPRISE) {
|
|
return plan as FirefliesPlan;
|
|
}
|
|
if (plan === FIREFLIES_PLANS.PRO) {
|
|
return FIREFLIES_PLANS.PRO;
|
|
}
|
|
return FIREFLIES_PLANS.FREE;
|
|
};
|
|
|