import {z} from 'zod' export type GetApiConversationsListArgs = {fromDateTime?: string | undefined, toDateTime?: string | undefined, fromUpdatedAtDateTime?: string | undefined, toUpdatedAtDateTime?: string | undefined, cursor?: string | undefined, page?: number | undefined, size?: number | undefined, 'filter[owner.id]'?: Array | undefined, 'filter[owner.email]'?: Array | undefined, 'filter[title]'?: string | undefined, 'filter[participants.email]'?: Array | undefined, 'filter[external_opportunity.id]'?: Array | undefined, 'filter[crm_field.entity_code]'?: ('companies' | 'contacts' | 'deals' | 'owners' | 'pipelines' | 'users' | 'account' | 'contact' | 'lead' | 'opportunity' | 'user') | undefined, 'filter[crm_field.field_name]'?: string | undefined, 'filter[crm_field.values]'?: Array | undefined, 'filter[team.id]'?: Array | undefined, 'filter[hide_internal]'?: boolean | undefined, 'filter[hide_non_analyzed]'?: boolean | undefined, 'filter[analyzed]'?: boolean | undefined, 'filter[hide_pending]'?: boolean | undefined, 'filter[hide_transcript]'?: boolean | undefined, 'filter[include_private]'?: boolean | undefined, 'filter[hide_failed]'?: boolean | undefined, 'filter[include_internal_participants]'?: boolean | undefined, 'filter[include_zoom_metadata]'?: boolean | undefined, 'filter[include_import_metadata]'?: boolean | undefined, detailedTranscript?: boolean | undefined, withCrmRecords?: boolean | undefined, withIntelligenceItems?: boolean | undefined}; export type GetApiConversationsListOptions = {baseUrl?: string | undefined, APIKeyHeader?: string | undefined, fetch?: typeof fetch | undefined}; export const battlecard = z.object({uuid: z.string().optional(), keywords: z.array(z.string()).optional(), response: z.string().optional(), text: z.string().optional()}); export const column = z.object({id: z.string().optional(), title: z.string().optional(), children: z.array(battlecard).optional()}); export const slackTeamInfo = z.object({id: z.string().optional(), name: z.string().optional()}); export const slackConnection = z.object({id: z.string().optional(), info: slackTeamInfo.optional()}); export const team: z.ZodType = z.object({uuid: z.string().optional(), name: z.string().optional(), phrases: z.array(z.string()).optional(), slackConnection: slackConnection.optional(), domain: z.string().optional(), organizerJoinInternalMeetings: z.boolean().optional(), consentEmailEnabled: z.boolean().optional(), parentTeamUUID: z.string().optional(), organizationUUID: z.string().optional(), children: z.array(z.lazy(() => team)).optional()}); export const board = z.object({uuid: z.string().optional(), name: z.string().optional(), columns: z.array(column).optional(), team: team.optional(), teamUUID: z.string().optional()}); export const conversationBoardBattlecard = z.object({uuid: z.string().optional(), activatedBattlecardID: z.string().optional(), hidden: z.boolean().optional(), feedbackAction: z.string().optional()}); export const conversationBoard = z.object({uuid: z.string().optional(), board: board.optional(), battlecards: z.array(conversationBoardBattlecard).optional()}); export const conversationTalktrackItem = z.object({uuid: z.string().optional(), activatedItemId: z.string().optional(), done: z.boolean().optional()}); export const conversationTalktrack = z.object({uuid: z.string().optional(), items: z.array(conversationTalktrackItem).optional()}); export const userSettings = z.object({realTimeCapabilitiesOFF: z.boolean().optional(), autoCalculateCRMFields: z.boolean().optional(), joinWhenIAmHostAndAlone: z.boolean().optional(), joinWhenIAmHostWithPeers: z.boolean().optional(), joinWhenPeerIsHost: z.boolean().optional(), joinWhenUnlicensedPeerIsHost: z.boolean().optional(), dealsEnabled: z.boolean().optional()}); export const role = z.object({uuid: z.string().optional(), name: z.string().optional(), type: z.string().optional()}); export const user = z.object({uuid: z.string().optional(), email: z.string().optional(), firstName: z.string().optional(), lastName: z.string().optional(), createdAt: z.string().optional(), deletedAt: z.string().optional(), transcriptLang: z.string().optional(), joinOutsideHostMeetings: z.boolean().optional(), realTimeCapabilities: z.boolean().optional(), settings: userSettings.optional(), botName: z.string().optional(), botImageURL: z.string().optional(), primaryTeamUUID: z.string().optional(), organizationRoleUUID: z.string().optional(), roles: z.array(role).optional(), showReferralScreen: z.boolean().optional(), seatType: z.string().optional(), teams: z.array(team).optional()}); export const intelligenceItemOptionalValues = z.object({values: z.array(z.string()).optional(), maxValues: z.number().int().optional()}); export const extractedIntelligenceItem = z.object({id: z.string().optional(), key: z.string().optional(), value: z.string().optional(), title: z.string().optional(), category: z.string().optional(), refreshing: z.boolean().optional(), options: intelligenceItemOptionalValues.optional(), source: z.string().optional(), scope_insight: z.string().optional()}); export const crmExportStatus = z.enum(["PENDING", "EXPORTED", "DISMISSED"]); export const cRMExportOpportunity = z.object({uuid: z.string().optional(), title: z.string().optional()}); export const videoStatus = z.enum(["PENDING", "UNAVAILABLE", "IMPORTING", "READY"]); export const botStatus = z.object({code: z.string().optional(), message: z.string().optional(), createdAt: z.string().optional()}); export const conversationBot = z.object({uuid: z.string().optional(), status: botStatus.optional(), meetingUrl: z.string().optional()}); export const participant = z.object({id: z.string().optional(), email: z.string().optional(), organizer: z.boolean().optional(), name: z.string().optional(), status: z.string().optional()}); export const conversationImportStatus = z.enum(["NONE", "PENDING", "IN_PROGRESS", "FINISHED", "DISCARDED", "FAILED"]); export const scorecardResultSummary = z.object({min: z.number().int().optional(), max: z.number().int().optional(), averageScore: z.number().optional(), summaryText: z.string().optional()}); export const scorecardItemResultStatus = z.enum(["CALCULATED", "CALCULATING"]); export const scorecardType = z.literal("NUMERIC"); export const numericScorecardResult = z.object({min: z.number().int().optional(), max: z.number().int().optional(), score: z.number().int().optional()}); export const scorecardItemResult = z.object({uuid: z.string().optional(), title: z.string().optional(), status: scorecardItemResultStatus.optional(), type: scorecardType.optional(), position: z.number().int().optional(), numericResult: numericScorecardResult.optional(), description: z.string().optional(), evidences: z.array(z.string()).optional(), scorecardItemUUID: z.string().optional()}); export const scorecardResult = z.object({uuid: z.string().optional(), title: z.string().optional(), summary: scorecardResultSummary.optional(), items: z.array(scorecardItemResult).optional()}); export const linkedCrmRecord = z.object({id: z.string(), code: z.string()}); export const zoomMetadata = z.object({calleeName: z.string(), calleeNumber: z.string(), callerName: z.string(), callerNumber: z.string()}); export const links = z.object({self: z.string().optional(), related: z.string().optional()}); export const conversation = z.object({type: z.literal("conversations").optional(), id: z.string().optional(), attributes: z.object({uuid: z.string().optional(), transcript: z.record(z.string(), z.unknown()).optional(), boards: z.array(conversationBoard).optional(), finishedAt: z.string().optional(), title: z.string().optional(), liveStreamStartedAt: z.string().optional(), liveStreamEndedAt: z.string().optional(), talktracks: z.array(conversationTalktrack).optional(), createdAt: z.string().optional(), updatedAt: z.string().nullable().optional(), userUUID: z.string().optional(), user: user.optional(), team: team.optional(), teamUUID: z.string().optional(), extractedIntelligence: z.record(z.string(), extractedIntelligenceItem).optional(), confirmedExtractedIntelligence: z.record(z.string(), extractedIntelligenceItem).optional(), externalIntelligenceOpportunityID: z.string(), crmExportStatus: crmExportStatus.optional(), archived: z.boolean().optional(), externalOpportunity: cRMExportOpportunity, videoUID: z.string().optional(), videoStatus: videoStatus.optional(), bots: z.array(conversationBot).optional(), transcriptStatus: z.string().optional(), participants: z.array(participant).optional(), attendees: z.array(participant).optional(), referenceable: z.boolean().optional(), private: z.boolean().optional(), mediaStorageStatus: videoStatus.optional(), importStatus: conversationImportStatus.optional(), scorecardResults: z.array(scorecardResult).optional(), labels: z.record(z.string(), z.unknown()).optional(), labelTagsToFilterIfNA: z.array(z.string()).optional(), deprecatedLabelCategories: z.array(z.string()).optional(), isInternal: z.boolean().optional(), mediaDuration: z.number().optional(), dealUUID: z.string(), emailTemplateID: z.string().optional(), linkedCrmRecords: z.array(linkedCrmRecord).optional(), externalAccounts: z.array(linkedCrmRecord).optional(), externalContacts: z.array(linkedCrmRecord).optional(), isEmpty: z.boolean().optional(), zoomMetadata: zoomMetadata, importMetadata: z.record(z.string(), z.unknown()), zoomMeetingJoinUrl: z.string().optional(), googleMeetJoinUrl: z.string().optional(), microsoftTeamsJoinUrl: z.string().optional(), webexJoinUrl: z.string().optional()}).optional(), links: links.optional()}); export const meta = z.object({pageCount: z.number().int().optional(), totalRecords: z.number().int().optional(), pageNumber: z.number().int().optional(), pageSize: z.number().int().optional()}); export const conversationsResponse = z.object({data: z.array(conversation).optional(), links: links.optional(), meta: meta.optional(), nextCursor: z.string().optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * List Conversations (Optimized) * * GET /conversations/list */ export const getApiConversationsList = async (args: GetApiConversationsListArgs, options?: GetApiConversationsListOptions) => { const {baseUrl = "https://api.attention.tech/v2", fetch: fetchFn = fetch, APIKeyHeader} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.fromDateTime != null) query.append("fromDateTime", String(args.fromDateTime)) if (args.toDateTime != null) query.append("toDateTime", String(args.toDateTime)) if (args.fromUpdatedAtDateTime != null) query.append("fromUpdatedAtDateTime", String(args.fromUpdatedAtDateTime)) if (args.toUpdatedAtDateTime != null) query.append("toUpdatedAtDateTime", String(args.toUpdatedAtDateTime)) if (args.cursor != null) query.append("cursor", String(args.cursor)) if (args.page != null) query.append("page", String(args.page)) if (args.size != null) query.append("size", String(args.size)) if (args['filter[owner.id]'] != null) query.append("filter[owner.id]", args['filter[owner.id]'].join(',')) if (args['filter[owner.email]'] != null) query.append("filter[owner.email]", args['filter[owner.email]'].join(',')) if (args['filter[title]'] != null) query.append("filter[title]", String(args['filter[title]'])) if (args['filter[participants.email]'] != null) query.append("filter[participants.email]", args['filter[participants.email]'].join(',')) if (args['filter[external_opportunity.id]'] != null) query.append("filter[external_opportunity.id]", args['filter[external_opportunity.id]'].join(',')) if (args['filter[crm_field.entity_code]'] != null) query.append("filter[crm_field.entity_code]", String(args['filter[crm_field.entity_code]'])) if (args['filter[crm_field.field_name]'] != null) query.append("filter[crm_field.field_name]", String(args['filter[crm_field.field_name]'])) if (args['filter[crm_field.values]'] != null) query.append("filter[crm_field.values]", args['filter[crm_field.values]'].join(',')) if (args['filter[team.id]'] != null) query.append("filter[team.id]", args['filter[team.id]'].join(',')) if (args['filter[hide_internal]'] != null) query.append("filter[hide_internal]", String(args['filter[hide_internal]'])) if (args['filter[hide_non_analyzed]'] != null) query.append("filter[hide_non_analyzed]", String(args['filter[hide_non_analyzed]'])) if (args['filter[analyzed]'] != null) query.append("filter[analyzed]", String(args['filter[analyzed]'])) if (args['filter[hide_pending]'] != null) query.append("filter[hide_pending]", String(args['filter[hide_pending]'])) if (args['filter[hide_transcript]'] != null) query.append("filter[hide_transcript]", String(args['filter[hide_transcript]'])) if (args['filter[include_private]'] != null) query.append("filter[include_private]", String(args['filter[include_private]'])) if (args['filter[hide_failed]'] != null) query.append("filter[hide_failed]", String(args['filter[hide_failed]'])) if (args['filter[include_internal_participants]'] != null) query.append("filter[include_internal_participants]", String(args['filter[include_internal_participants]'])) if (args['filter[include_zoom_metadata]'] != null) query.append("filter[include_zoom_metadata]", String(args['filter[include_zoom_metadata]'])) if (args['filter[include_import_metadata]'] != null) query.append("filter[include_import_metadata]", String(args['filter[include_import_metadata]'])) if (args.detailedTranscript != null) query.append("detailedTranscript", String(args.detailedTranscript)) if (args.withCrmRecords != null) query.append("withCrmRecords", String(args.withCrmRecords)) if (args.withIntelligenceItems != null) query.append("withIntelligenceItems", String(args.withIntelligenceItems)) if (APIKeyHeader !== undefined) headers.set("Authorization", APIKeyHeader) const url = `${baseUrl.replace(/\/+$/, '')}/conversations/list${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(conversationsResponse, await res.json()) };