portal-aiatende-api 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -397,6 +397,13 @@ interface MessagingConversationsListResponse {
397
397
  totalPages: number;
398
398
  };
399
399
  }
400
+ /** Um anexo de Message.media (Portal) — shape gravado em prisma/schema.prisma's Message.media (Json). */
401
+ interface MessagingMediaItem {
402
+ id: string;
403
+ mediaType?: string;
404
+ mimeType?: string;
405
+ fileSize?: number;
406
+ }
400
407
  interface MessagingMessage {
401
408
  id: string;
402
409
  externalId: string;
@@ -406,7 +413,7 @@ interface MessagingMessage {
406
413
  status: string;
407
414
  content: Record<string, unknown>;
408
415
  waMessageId: string | null;
409
- media: unknown[];
416
+ media: MessagingMediaItem[];
410
417
  sentByType: 'platform_user' | 'api_key' | 'external_agent' | 'whatsapp_app' | null;
411
418
  sentById: string | null;
412
419
  sentByName: string | null;
@@ -498,6 +505,10 @@ interface UploadMediaResponse {
498
505
  mimeType: string;
499
506
  fileSize: number;
500
507
  }
508
+ interface DownloadMediaResponse {
509
+ data: Buffer;
510
+ contentType: string;
511
+ }
501
512
 
502
513
  /**
503
514
  * Canal WhatsApp direto (aiatendeWa) — proxy pras rotas `/api/clients/{clientId}/messaging/...`
@@ -522,6 +533,13 @@ declare class MessagingResource extends BaseResource {
522
533
  * registro de mídia local pra conexões Cloud API).
523
534
  */
524
535
  uploadMedia(clientId: string, payload: UploadMediaPayload): Promise<UploadMediaResponse>;
536
+ /**
537
+ * Baixa os bytes de um anexo (Message.media[].id) — usado hoje só pelo caminho de imagem do
538
+ * canal aiatendeWa (monta uma data URI pra mandar pro modelo de visão, já que a URL não pode
539
+ * ser pública). Áudio/PDF seguem passando a URL autenticada direto pros métodos de
540
+ * transcrição/extração do atende360-assistant, sem baixar bytes por aqui.
541
+ */
542
+ downloadMedia(clientId: string, mediaId: string): Promise<DownloadMediaResponse>;
525
543
  }
526
544
 
527
545
  declare class PortalClient {
@@ -539,4 +557,4 @@ declare class PortalApiError extends Error {
539
557
  constructor(message: string, info?: Partial<PortalApiError>);
540
558
  }
541
559
 
542
- export { type AiActivationSchedule, type AiCareStatus, type AiConfig, type AiExperiment, type AiExperimentConfig, type AiExperimentCriteria, type AiExperimentVariant, type AiPrompt, type AiResumeMode, type BusinessHours, type CalendarConfig, type Client, type ClientsListResponse, ClientsResource, type ConversationHistoryMessage, type DateException, type GetInternalContextParams, type InternalContextChunk, type InternalContextResult, KnowledgeResource, type KommoAccount, type KommoConfig, type ListConversationsFilters, type LossReasonMapping, type MessagingContact, type MessagingConversation, type MessagingConversationsListResponse, type MessagingMessage, type MessagingMessagesListResponse, type MessagingPhoneNumber, MessagingResource, type NudgeSettings, type PatchConversationPayload, type PipelineMapping, PortalApiError, PortalClient, type PortalClientConfig, type SendMessagePayload, type SendMessageResponse, type StageMapping, type TimeRange, type UploadMediaPayload, type UploadMediaResponse, type Wazzup, type WazzupChannel };
560
+ export { type AiActivationSchedule, type AiCareStatus, type AiConfig, type AiExperiment, type AiExperimentConfig, type AiExperimentCriteria, type AiExperimentVariant, type AiPrompt, type AiResumeMode, type BusinessHours, type CalendarConfig, type Client, type ClientsListResponse, ClientsResource, type ConversationHistoryMessage, type DateException, type DownloadMediaResponse, type GetInternalContextParams, type InternalContextChunk, type InternalContextResult, KnowledgeResource, type KommoAccount, type KommoConfig, type ListConversationsFilters, type LossReasonMapping, type MessagingContact, type MessagingConversation, type MessagingConversationsListResponse, type MessagingMediaItem, type MessagingMessage, type MessagingMessagesListResponse, type MessagingPhoneNumber, MessagingResource, type NudgeSettings, type PatchConversationPayload, type PipelineMapping, PortalApiError, PortalClient, type PortalClientConfig, type SendMessagePayload, type SendMessageResponse, type StageMapping, type TimeRange, type UploadMediaPayload, type UploadMediaResponse, type Wazzup, type WazzupChannel };
package/dist/index.d.ts CHANGED
@@ -397,6 +397,13 @@ interface MessagingConversationsListResponse {
397
397
  totalPages: number;
398
398
  };
399
399
  }
400
+ /** Um anexo de Message.media (Portal) — shape gravado em prisma/schema.prisma's Message.media (Json). */
401
+ interface MessagingMediaItem {
402
+ id: string;
403
+ mediaType?: string;
404
+ mimeType?: string;
405
+ fileSize?: number;
406
+ }
400
407
  interface MessagingMessage {
401
408
  id: string;
402
409
  externalId: string;
@@ -406,7 +413,7 @@ interface MessagingMessage {
406
413
  status: string;
407
414
  content: Record<string, unknown>;
408
415
  waMessageId: string | null;
409
- media: unknown[];
416
+ media: MessagingMediaItem[];
410
417
  sentByType: 'platform_user' | 'api_key' | 'external_agent' | 'whatsapp_app' | null;
411
418
  sentById: string | null;
412
419
  sentByName: string | null;
@@ -498,6 +505,10 @@ interface UploadMediaResponse {
498
505
  mimeType: string;
499
506
  fileSize: number;
500
507
  }
508
+ interface DownloadMediaResponse {
509
+ data: Buffer;
510
+ contentType: string;
511
+ }
501
512
 
502
513
  /**
503
514
  * Canal WhatsApp direto (aiatendeWa) — proxy pras rotas `/api/clients/{clientId}/messaging/...`
@@ -522,6 +533,13 @@ declare class MessagingResource extends BaseResource {
522
533
  * registro de mídia local pra conexões Cloud API).
523
534
  */
524
535
  uploadMedia(clientId: string, payload: UploadMediaPayload): Promise<UploadMediaResponse>;
536
+ /**
537
+ * Baixa os bytes de um anexo (Message.media[].id) — usado hoje só pelo caminho de imagem do
538
+ * canal aiatendeWa (monta uma data URI pra mandar pro modelo de visão, já que a URL não pode
539
+ * ser pública). Áudio/PDF seguem passando a URL autenticada direto pros métodos de
540
+ * transcrição/extração do atende360-assistant, sem baixar bytes por aqui.
541
+ */
542
+ downloadMedia(clientId: string, mediaId: string): Promise<DownloadMediaResponse>;
525
543
  }
526
544
 
527
545
  declare class PortalClient {
@@ -539,4 +557,4 @@ declare class PortalApiError extends Error {
539
557
  constructor(message: string, info?: Partial<PortalApiError>);
540
558
  }
541
559
 
542
- export { type AiActivationSchedule, type AiCareStatus, type AiConfig, type AiExperiment, type AiExperimentConfig, type AiExperimentCriteria, type AiExperimentVariant, type AiPrompt, type AiResumeMode, type BusinessHours, type CalendarConfig, type Client, type ClientsListResponse, ClientsResource, type ConversationHistoryMessage, type DateException, type GetInternalContextParams, type InternalContextChunk, type InternalContextResult, KnowledgeResource, type KommoAccount, type KommoConfig, type ListConversationsFilters, type LossReasonMapping, type MessagingContact, type MessagingConversation, type MessagingConversationsListResponse, type MessagingMessage, type MessagingMessagesListResponse, type MessagingPhoneNumber, MessagingResource, type NudgeSettings, type PatchConversationPayload, type PipelineMapping, PortalApiError, PortalClient, type PortalClientConfig, type SendMessagePayload, type SendMessageResponse, type StageMapping, type TimeRange, type UploadMediaPayload, type UploadMediaResponse, type Wazzup, type WazzupChannel };
560
+ export { type AiActivationSchedule, type AiCareStatus, type AiConfig, type AiExperiment, type AiExperimentConfig, type AiExperimentCriteria, type AiExperimentVariant, type AiPrompt, type AiResumeMode, type BusinessHours, type CalendarConfig, type Client, type ClientsListResponse, ClientsResource, type ConversationHistoryMessage, type DateException, type DownloadMediaResponse, type GetInternalContextParams, type InternalContextChunk, type InternalContextResult, KnowledgeResource, type KommoAccount, type KommoConfig, type ListConversationsFilters, type LossReasonMapping, type MessagingContact, type MessagingConversation, type MessagingConversationsListResponse, type MessagingMediaItem, type MessagingMessage, type MessagingMessagesListResponse, type MessagingPhoneNumber, MessagingResource, type NudgeSettings, type PatchConversationPayload, type PipelineMapping, PortalApiError, PortalClient, type PortalClientConfig, type SendMessagePayload, type SendMessageResponse, type StageMapping, type TimeRange, type UploadMediaPayload, type UploadMediaResponse, type Wazzup, type WazzupChannel };
package/dist/index.js CHANGED
@@ -176,10 +176,31 @@ var MessagingResource = class extends BaseResource {
176
176
  );
177
177
  const response = await this.client.post(
178
178
  `/api/clients/${clientId}/messaging/media`,
179
- form
179
+ form,
180
+ // A instância do axios (client.ts) fixa Content-Type: application/json como default —
181
+ // sem isto, esse header explícito vence e nunca deixa o axios detectar o FormData nativo
182
+ // e gerar o multipart/form-data; boundary=... correto. `undefined` remove o default do
183
+ // merge de headers só nesta chamada, liberando a detecção automática.
184
+ { headers: { "Content-Type": void 0 } }
180
185
  );
181
186
  return response.data;
182
187
  }
188
+ /**
189
+ * Baixa os bytes de um anexo (Message.media[].id) — usado hoje só pelo caminho de imagem do
190
+ * canal aiatendeWa (monta uma data URI pra mandar pro modelo de visão, já que a URL não pode
191
+ * ser pública). Áudio/PDF seguem passando a URL autenticada direto pros métodos de
192
+ * transcrição/extração do atende360-assistant, sem baixar bytes por aqui.
193
+ */
194
+ async downloadMedia(clientId, mediaId) {
195
+ const response = await this.client.get(
196
+ `/api/clients/${clientId}/messaging/media/${mediaId}`,
197
+ { responseType: "arraybuffer" }
198
+ );
199
+ return {
200
+ data: Buffer.from(response.data),
201
+ contentType: response.headers["content-type"] || "application/octet-stream"
202
+ };
203
+ }
183
204
  };
184
205
 
185
206
  // src/client.ts
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/base.ts","../src/errors.ts","../src/resources/clients/index.ts","../src/resources/knowledge/index.ts","../src/resources/messaging/index.ts"],"sourcesContent":["export * from './client';\nexport * from './types';\nexport * from './errors';\nexport * from './resources/clients';\nexport * from './resources/clients/types';\nexport * from './resources/knowledge';\nexport * from './resources/knowledge/types';\nexport * from './resources/messaging';\nexport * from './resources/messaging/types';\n","import axios, { AxiosInstance } from 'axios';\nimport { PortalClientConfig } from './types';\nimport { ClientsResource } from './resources/clients';\nimport { KnowledgeResource } from './resources/knowledge';\nimport { MessagingResource } from './resources/messaging';\nimport { PortalApiError } from './errors';\n\nconst DEFAULT_BASE_URL = 'https://portal.aiatende.com.br';\n\nexport class PortalClient {\n public config: PortalClientConfig;\n public httpClient: AxiosInstance;\n\n public clients: ClientsResource;\n public knowledge: KnowledgeResource;\n public messaging: MessagingResource;\n\n constructor(config: PortalClientConfig) {\n this.config = config;\n\n this.httpClient = axios.create({\n baseURL: config.baseUrl || DEFAULT_BASE_URL,\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n 'x-internal-token': config.apiKey\n }\n });\n\n this.httpClient.interceptors.response.use(\n (response) => response,\n (error) => {\n if (error.response) {\n const errData = error.response.data;\n throw new PortalApiError(errData?.error || 'Portal API Error', {\n status: error.response.status,\n raw: errData\n });\n }\n throw error;\n }\n );\n\n this.clients = new ClientsResource(this.httpClient);\n this.knowledge = new KnowledgeResource(this.httpClient);\n this.messaging = new MessagingResource(this.httpClient);\n }\n}\n","import { AxiosInstance } from 'axios';\n\nexport abstract class BaseResource {\n protected client: AxiosInstance;\n\n constructor(client: AxiosInstance) {\n this.client = client;\n }\n}\n","export class PortalApiError extends Error {\n status?: number;\n raw?: unknown;\n\n constructor(message: string, info?: Partial<PortalApiError>) {\n super(message);\n this.name = 'PortalApiError';\n\n if (info) {\n this.status = info.status;\n this.raw = info.raw;\n }\n }\n}\n","import { BaseResource } from '../../base';\nimport { PortalApiError } from '../../errors';\nimport { Client, ClientsListResponse } from './types';\n\nexport class ClientsResource extends BaseResource {\n /** Busca o Client dono de um subdomínio Kommo (`GET /api/clients?kommo_subdomain=...`). */\n async getByKommoSubdomain(subdomain: string): Promise<Client | null> {\n const response = await this.client.get<ClientsListResponse>('/api/clients', {\n params: { kommo_subdomain: subdomain, includeConfigs: true }\n });\n return response.data.data[0] ?? null;\n }\n\n /** Busca o Client dono de um canal Wazzup (`GET /api/clients?channelId=...`). */\n async getByWazzupChannelId(channelId: string): Promise<Client | null> {\n const response = await this.client.get<ClientsListResponse>('/api/clients', {\n params: { channelId, includeConfigs: true }\n });\n return response.data.data[0] ?? null;\n }\n\n /**\n * Busca o Client pelo seu id direto (`GET /api/clients/{id}`) — inclui `aiConfig` e\n * `messagingConfig` (sem a API key criptografada). Usado pelo canal aiatendeWa, que resolve o\n * tenant a partir do `clientId` já incluído no payload do relay de webhook, sem precisar de\n * um identificador de canal indireto como Kommo subdomain ou Wazzup channelId.\n */\n async getById(clientId: string): Promise<Client | null> {\n try {\n const response = await this.client.get<Client>(`/api/clients/${clientId}`);\n return response.data;\n } catch (error) {\n if (error instanceof PortalApiError && error.status === 404) return null;\n throw error;\n }\n }\n}\n","import { z } from 'zod';\nimport { BaseResource } from '../../base';\nimport { PortalApiError } from '../../errors';\nimport { GetInternalContextParams, InternalContextResult } from './types';\n\nconst internalContextChunkSchema = z.object({\n chunkId: z.string().optional(),\n content: z.string(),\n similarity: z.number(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nconst internalContextResultSchema = z.array(internalContextChunkSchema);\n\nexport class KnowledgeResource extends BaseResource {\n /** Recupera trechos relevantes da base RAG do cliente pra uma pergunta em texto puro (`POST /api/knowledge/internal/context`). O Portal gera o embedding internamente usando a `apiKey` do AiConfig. */\n async getInternalContext(params: GetInternalContextParams): Promise<InternalContextResult> {\n const response = await this.client.post<unknown>('/api/knowledge/internal/context', {\n aiConfigId: params.aiConfigId,\n question: params.question,\n conversationHistory: params.conversationHistory\n });\n\n const parsed = internalContextResultSchema.safeParse(response.data);\n if (!parsed.success) {\n throw new PortalApiError('Resposta inválida de /api/knowledge/internal/context', {\n raw: parsed.error.flatten(),\n });\n }\n return parsed.data;\n }\n}\n","import { BaseResource } from '../../base';\nimport {\n ListConversationsFilters,\n MessagingConversation,\n MessagingConversationsListResponse,\n MessagingMessagesListResponse,\n PatchConversationPayload,\n SendMessagePayload,\n SendMessageResponse,\n UploadMediaPayload,\n UploadMediaResponse,\n} from './types';\n\n/**\n * Canal WhatsApp direto (aiatendeWa) — proxy pras rotas `/api/clients/{clientId}/messaging/...`\n * do Portal, que por sua vez falam com a plataforma de mensageria própria\n * (plataforma_whatsapp_coexistence). O atende360-assistant nunca fala direto com essa\n * plataforma — sempre por aqui, autenticado via a mesma `apiKey`/APP_API_KEY já usada pro\n * resto do SDK.\n */\nexport class MessagingResource extends BaseResource {\n async listConversations(\n clientId: string,\n filters?: ListConversationsFilters,\n ): Promise<MessagingConversationsListResponse> {\n const response = await this.client.get<MessagingConversationsListResponse>(\n `/api/clients/${clientId}/messaging/conversations`,\n { params: filters },\n );\n return response.data;\n }\n\n async getConversation(clientId: string, conversationId: string): Promise<MessagingConversation> {\n const response = await this.client.get<MessagingConversation>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}`,\n );\n return response.data;\n }\n\n async patchConversation(\n clientId: string,\n conversationId: string,\n payload: PatchConversationPayload,\n ): Promise<MessagingConversation> {\n const response = await this.client.patch<MessagingConversation>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}`,\n payload,\n );\n return response.data;\n }\n\n async getMessages(\n clientId: string,\n conversationId: string,\n params?: { page?: number; limit?: number },\n ): Promise<MessagingMessagesListResponse> {\n const response = await this.client.get<MessagingMessagesListResponse>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}/messages`,\n { params },\n );\n return response.data;\n }\n\n async sendMessage(\n clientId: string,\n conversationId: string,\n payload: SendMessagePayload,\n ): Promise<SendMessageResponse> {\n const response = await this.client.post<SendMessageResponse>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}/messages`,\n payload,\n );\n return response.data;\n }\n\n /**\n * Upload de mídia (ex.: áudio gerado por TTS) — pré-requisito pra mandar `type: 'audio'` no\n * `sendMessage` (o `content.id` retornado aqui vira `content.id` do envio; `storagePath`\n * precisa ser ecoado em `content._media.storagePath` no send, senão a plataforma não cria o\n * registro de mídia local pra conexões Cloud API).\n */\n async uploadMedia(clientId: string, payload: UploadMediaPayload): Promise<UploadMediaResponse> {\n const form = new FormData();\n // Ordem importa: phoneNumberId/isVoiceNote precisam vir ANTES de file no multipart — o\n // parser do Portal (e o da plataforma por trás dele) lê em stream.\n form.append('phoneNumberId', payload.phoneNumberId);\n if (payload.isVoiceNote) form.append('isVoiceNote', 'true');\n form.append(\n 'file',\n new Blob([new Uint8Array(payload.file)], { type: payload.mimeType }),\n payload.filename,\n );\n\n const response = await this.client.post<UploadMediaResponse>(\n `/api/clients/${clientId}/messaging/media`,\n form,\n );\n return response.data;\n }\n}\n"],"mappings":"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","names":["axios"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/base.ts","../src/errors.ts","../src/resources/clients/index.ts","../src/resources/knowledge/index.ts","../src/resources/messaging/index.ts"],"sourcesContent":["export * from './client';\nexport * from './types';\nexport * from './errors';\nexport * from './resources/clients';\nexport * from './resources/clients/types';\nexport * from './resources/knowledge';\nexport * from './resources/knowledge/types';\nexport * from './resources/messaging';\nexport * from './resources/messaging/types';\n","import axios, { AxiosInstance } from 'axios';\nimport { PortalClientConfig } from './types';\nimport { ClientsResource } from './resources/clients';\nimport { KnowledgeResource } from './resources/knowledge';\nimport { MessagingResource } from './resources/messaging';\nimport { PortalApiError } from './errors';\n\nconst DEFAULT_BASE_URL = 'https://portal.aiatende.com.br';\n\nexport class PortalClient {\n public config: PortalClientConfig;\n public httpClient: AxiosInstance;\n\n public clients: ClientsResource;\n public knowledge: KnowledgeResource;\n public messaging: MessagingResource;\n\n constructor(config: PortalClientConfig) {\n this.config = config;\n\n this.httpClient = axios.create({\n baseURL: config.baseUrl || DEFAULT_BASE_URL,\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n 'x-internal-token': config.apiKey\n }\n });\n\n this.httpClient.interceptors.response.use(\n (response) => response,\n (error) => {\n if (error.response) {\n const errData = error.response.data;\n throw new PortalApiError(errData?.error || 'Portal API Error', {\n status: error.response.status,\n raw: errData\n });\n }\n throw error;\n }\n );\n\n this.clients = new ClientsResource(this.httpClient);\n this.knowledge = new KnowledgeResource(this.httpClient);\n this.messaging = new MessagingResource(this.httpClient);\n }\n}\n","import { AxiosInstance } from 'axios';\n\nexport abstract class BaseResource {\n protected client: AxiosInstance;\n\n constructor(client: AxiosInstance) {\n this.client = client;\n }\n}\n","export class PortalApiError extends Error {\n status?: number;\n raw?: unknown;\n\n constructor(message: string, info?: Partial<PortalApiError>) {\n super(message);\n this.name = 'PortalApiError';\n\n if (info) {\n this.status = info.status;\n this.raw = info.raw;\n }\n }\n}\n","import { BaseResource } from '../../base';\nimport { PortalApiError } from '../../errors';\nimport { Client, ClientsListResponse } from './types';\n\nexport class ClientsResource extends BaseResource {\n /** Busca o Client dono de um subdomínio Kommo (`GET /api/clients?kommo_subdomain=...`). */\n async getByKommoSubdomain(subdomain: string): Promise<Client | null> {\n const response = await this.client.get<ClientsListResponse>('/api/clients', {\n params: { kommo_subdomain: subdomain, includeConfigs: true }\n });\n return response.data.data[0] ?? null;\n }\n\n /** Busca o Client dono de um canal Wazzup (`GET /api/clients?channelId=...`). */\n async getByWazzupChannelId(channelId: string): Promise<Client | null> {\n const response = await this.client.get<ClientsListResponse>('/api/clients', {\n params: { channelId, includeConfigs: true }\n });\n return response.data.data[0] ?? null;\n }\n\n /**\n * Busca o Client pelo seu id direto (`GET /api/clients/{id}`) — inclui `aiConfig` e\n * `messagingConfig` (sem a API key criptografada). Usado pelo canal aiatendeWa, que resolve o\n * tenant a partir do `clientId` já incluído no payload do relay de webhook, sem precisar de\n * um identificador de canal indireto como Kommo subdomain ou Wazzup channelId.\n */\n async getById(clientId: string): Promise<Client | null> {\n try {\n const response = await this.client.get<Client>(`/api/clients/${clientId}`);\n return response.data;\n } catch (error) {\n if (error instanceof PortalApiError && error.status === 404) return null;\n throw error;\n }\n }\n}\n","import { z } from 'zod';\nimport { BaseResource } from '../../base';\nimport { PortalApiError } from '../../errors';\nimport { GetInternalContextParams, InternalContextResult } from './types';\n\nconst internalContextChunkSchema = z.object({\n chunkId: z.string().optional(),\n content: z.string(),\n similarity: z.number(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nconst internalContextResultSchema = z.array(internalContextChunkSchema);\n\nexport class KnowledgeResource extends BaseResource {\n /** Recupera trechos relevantes da base RAG do cliente pra uma pergunta em texto puro (`POST /api/knowledge/internal/context`). O Portal gera o embedding internamente usando a `apiKey` do AiConfig. */\n async getInternalContext(params: GetInternalContextParams): Promise<InternalContextResult> {\n const response = await this.client.post<unknown>('/api/knowledge/internal/context', {\n aiConfigId: params.aiConfigId,\n question: params.question,\n conversationHistory: params.conversationHistory\n });\n\n const parsed = internalContextResultSchema.safeParse(response.data);\n if (!parsed.success) {\n throw new PortalApiError('Resposta inválida de /api/knowledge/internal/context', {\n raw: parsed.error.flatten(),\n });\n }\n return parsed.data;\n }\n}\n","import { BaseResource } from '../../base';\nimport {\n DownloadMediaResponse,\n ListConversationsFilters,\n MessagingConversation,\n MessagingConversationsListResponse,\n MessagingMessagesListResponse,\n PatchConversationPayload,\n SendMessagePayload,\n SendMessageResponse,\n UploadMediaPayload,\n UploadMediaResponse,\n} from './types';\n\n/**\n * Canal WhatsApp direto (aiatendeWa) — proxy pras rotas `/api/clients/{clientId}/messaging/...`\n * do Portal, que por sua vez falam com a plataforma de mensageria própria\n * (plataforma_whatsapp_coexistence). O atende360-assistant nunca fala direto com essa\n * plataforma — sempre por aqui, autenticado via a mesma `apiKey`/APP_API_KEY já usada pro\n * resto do SDK.\n */\nexport class MessagingResource extends BaseResource {\n async listConversations(\n clientId: string,\n filters?: ListConversationsFilters,\n ): Promise<MessagingConversationsListResponse> {\n const response = await this.client.get<MessagingConversationsListResponse>(\n `/api/clients/${clientId}/messaging/conversations`,\n { params: filters },\n );\n return response.data;\n }\n\n async getConversation(clientId: string, conversationId: string): Promise<MessagingConversation> {\n const response = await this.client.get<MessagingConversation>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}`,\n );\n return response.data;\n }\n\n async patchConversation(\n clientId: string,\n conversationId: string,\n payload: PatchConversationPayload,\n ): Promise<MessagingConversation> {\n const response = await this.client.patch<MessagingConversation>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}`,\n payload,\n );\n return response.data;\n }\n\n async getMessages(\n clientId: string,\n conversationId: string,\n params?: { page?: number; limit?: number },\n ): Promise<MessagingMessagesListResponse> {\n const response = await this.client.get<MessagingMessagesListResponse>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}/messages`,\n { params },\n );\n return response.data;\n }\n\n async sendMessage(\n clientId: string,\n conversationId: string,\n payload: SendMessagePayload,\n ): Promise<SendMessageResponse> {\n const response = await this.client.post<SendMessageResponse>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}/messages`,\n payload,\n );\n return response.data;\n }\n\n /**\n * Upload de mídia (ex.: áudio gerado por TTS) — pré-requisito pra mandar `type: 'audio'` no\n * `sendMessage` (o `content.id` retornado aqui vira `content.id` do envio; `storagePath`\n * precisa ser ecoado em `content._media.storagePath` no send, senão a plataforma não cria o\n * registro de mídia local pra conexões Cloud API).\n */\n async uploadMedia(clientId: string, payload: UploadMediaPayload): Promise<UploadMediaResponse> {\n const form = new FormData();\n // Ordem importa: phoneNumberId/isVoiceNote precisam vir ANTES de file no multipart — o\n // parser do Portal (e o da plataforma por trás dele) lê em stream.\n form.append('phoneNumberId', payload.phoneNumberId);\n if (payload.isVoiceNote) form.append('isVoiceNote', 'true');\n form.append(\n 'file',\n new Blob([new Uint8Array(payload.file)], { type: payload.mimeType }),\n payload.filename,\n );\n\n const response = await this.client.post<UploadMediaResponse>(\n `/api/clients/${clientId}/messaging/media`,\n form,\n // A instância do axios (client.ts) fixa Content-Type: application/json como default —\n // sem isto, esse header explícito vence e nunca deixa o axios detectar o FormData nativo\n // e gerar o multipart/form-data; boundary=... correto. `undefined` remove o default do\n // merge de headers só nesta chamada, liberando a detecção automática.\n { headers: { 'Content-Type': undefined } },\n );\n return response.data;\n }\n\n /**\n * Baixa os bytes de um anexo (Message.media[].id) — usado hoje só pelo caminho de imagem do\n * canal aiatendeWa (monta uma data URI pra mandar pro modelo de visão, já que a URL não pode\n * ser pública). Áudio/PDF seguem passando a URL autenticada direto pros métodos de\n * transcrição/extração do atende360-assistant, sem baixar bytes por aqui.\n */\n async downloadMedia(clientId: string, mediaId: string): Promise<DownloadMediaResponse> {\n const response = await this.client.get<ArrayBuffer>(\n `/api/clients/${clientId}/messaging/media/${mediaId}`,\n { responseType: 'arraybuffer' },\n );\n return {\n data: Buffer.from(response.data),\n contentType: (response.headers['content-type'] as string) || 'application/octet-stream',\n };\n }\n}\n"],"mappings":"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","names":["axios"]}
package/dist/index.mjs CHANGED
@@ -136,10 +136,31 @@ var MessagingResource = class extends BaseResource {
136
136
  );
137
137
  const response = await this.client.post(
138
138
  `/api/clients/${clientId}/messaging/media`,
139
- form
139
+ form,
140
+ // A instância do axios (client.ts) fixa Content-Type: application/json como default —
141
+ // sem isto, esse header explícito vence e nunca deixa o axios detectar o FormData nativo
142
+ // e gerar o multipart/form-data; boundary=... correto. `undefined` remove o default do
143
+ // merge de headers só nesta chamada, liberando a detecção automática.
144
+ { headers: { "Content-Type": void 0 } }
140
145
  );
141
146
  return response.data;
142
147
  }
148
+ /**
149
+ * Baixa os bytes de um anexo (Message.media[].id) — usado hoje só pelo caminho de imagem do
150
+ * canal aiatendeWa (monta uma data URI pra mandar pro modelo de visão, já que a URL não pode
151
+ * ser pública). Áudio/PDF seguem passando a URL autenticada direto pros métodos de
152
+ * transcrição/extração do atende360-assistant, sem baixar bytes por aqui.
153
+ */
154
+ async downloadMedia(clientId, mediaId) {
155
+ const response = await this.client.get(
156
+ `/api/clients/${clientId}/messaging/media/${mediaId}`,
157
+ { responseType: "arraybuffer" }
158
+ );
159
+ return {
160
+ data: Buffer.from(response.data),
161
+ contentType: response.headers["content-type"] || "application/octet-stream"
162
+ };
163
+ }
143
164
  };
144
165
 
145
166
  // src/client.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/base.ts","../src/errors.ts","../src/resources/clients/index.ts","../src/resources/knowledge/index.ts","../src/resources/messaging/index.ts"],"sourcesContent":["import axios, { AxiosInstance } from 'axios';\nimport { PortalClientConfig } from './types';\nimport { ClientsResource } from './resources/clients';\nimport { KnowledgeResource } from './resources/knowledge';\nimport { MessagingResource } from './resources/messaging';\nimport { PortalApiError } from './errors';\n\nconst DEFAULT_BASE_URL = 'https://portal.aiatende.com.br';\n\nexport class PortalClient {\n public config: PortalClientConfig;\n public httpClient: AxiosInstance;\n\n public clients: ClientsResource;\n public knowledge: KnowledgeResource;\n public messaging: MessagingResource;\n\n constructor(config: PortalClientConfig) {\n this.config = config;\n\n this.httpClient = axios.create({\n baseURL: config.baseUrl || DEFAULT_BASE_URL,\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n 'x-internal-token': config.apiKey\n }\n });\n\n this.httpClient.interceptors.response.use(\n (response) => response,\n (error) => {\n if (error.response) {\n const errData = error.response.data;\n throw new PortalApiError(errData?.error || 'Portal API Error', {\n status: error.response.status,\n raw: errData\n });\n }\n throw error;\n }\n );\n\n this.clients = new ClientsResource(this.httpClient);\n this.knowledge = new KnowledgeResource(this.httpClient);\n this.messaging = new MessagingResource(this.httpClient);\n }\n}\n","import { AxiosInstance } from 'axios';\n\nexport abstract class BaseResource {\n protected client: AxiosInstance;\n\n constructor(client: AxiosInstance) {\n this.client = client;\n }\n}\n","export class PortalApiError extends Error {\n status?: number;\n raw?: unknown;\n\n constructor(message: string, info?: Partial<PortalApiError>) {\n super(message);\n this.name = 'PortalApiError';\n\n if (info) {\n this.status = info.status;\n this.raw = info.raw;\n }\n }\n}\n","import { BaseResource } from '../../base';\nimport { PortalApiError } from '../../errors';\nimport { Client, ClientsListResponse } from './types';\n\nexport class ClientsResource extends BaseResource {\n /** Busca o Client dono de um subdomínio Kommo (`GET /api/clients?kommo_subdomain=...`). */\n async getByKommoSubdomain(subdomain: string): Promise<Client | null> {\n const response = await this.client.get<ClientsListResponse>('/api/clients', {\n params: { kommo_subdomain: subdomain, includeConfigs: true }\n });\n return response.data.data[0] ?? null;\n }\n\n /** Busca o Client dono de um canal Wazzup (`GET /api/clients?channelId=...`). */\n async getByWazzupChannelId(channelId: string): Promise<Client | null> {\n const response = await this.client.get<ClientsListResponse>('/api/clients', {\n params: { channelId, includeConfigs: true }\n });\n return response.data.data[0] ?? null;\n }\n\n /**\n * Busca o Client pelo seu id direto (`GET /api/clients/{id}`) — inclui `aiConfig` e\n * `messagingConfig` (sem a API key criptografada). Usado pelo canal aiatendeWa, que resolve o\n * tenant a partir do `clientId` já incluído no payload do relay de webhook, sem precisar de\n * um identificador de canal indireto como Kommo subdomain ou Wazzup channelId.\n */\n async getById(clientId: string): Promise<Client | null> {\n try {\n const response = await this.client.get<Client>(`/api/clients/${clientId}`);\n return response.data;\n } catch (error) {\n if (error instanceof PortalApiError && error.status === 404) return null;\n throw error;\n }\n }\n}\n","import { z } from 'zod';\nimport { BaseResource } from '../../base';\nimport { PortalApiError } from '../../errors';\nimport { GetInternalContextParams, InternalContextResult } from './types';\n\nconst internalContextChunkSchema = z.object({\n chunkId: z.string().optional(),\n content: z.string(),\n similarity: z.number(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nconst internalContextResultSchema = z.array(internalContextChunkSchema);\n\nexport class KnowledgeResource extends BaseResource {\n /** Recupera trechos relevantes da base RAG do cliente pra uma pergunta em texto puro (`POST /api/knowledge/internal/context`). O Portal gera o embedding internamente usando a `apiKey` do AiConfig. */\n async getInternalContext(params: GetInternalContextParams): Promise<InternalContextResult> {\n const response = await this.client.post<unknown>('/api/knowledge/internal/context', {\n aiConfigId: params.aiConfigId,\n question: params.question,\n conversationHistory: params.conversationHistory\n });\n\n const parsed = internalContextResultSchema.safeParse(response.data);\n if (!parsed.success) {\n throw new PortalApiError('Resposta inválida de /api/knowledge/internal/context', {\n raw: parsed.error.flatten(),\n });\n }\n return parsed.data;\n }\n}\n","import { BaseResource } from '../../base';\nimport {\n ListConversationsFilters,\n MessagingConversation,\n MessagingConversationsListResponse,\n MessagingMessagesListResponse,\n PatchConversationPayload,\n SendMessagePayload,\n SendMessageResponse,\n UploadMediaPayload,\n UploadMediaResponse,\n} from './types';\n\n/**\n * Canal WhatsApp direto (aiatendeWa) — proxy pras rotas `/api/clients/{clientId}/messaging/...`\n * do Portal, que por sua vez falam com a plataforma de mensageria própria\n * (plataforma_whatsapp_coexistence). O atende360-assistant nunca fala direto com essa\n * plataforma — sempre por aqui, autenticado via a mesma `apiKey`/APP_API_KEY já usada pro\n * resto do SDK.\n */\nexport class MessagingResource extends BaseResource {\n async listConversations(\n clientId: string,\n filters?: ListConversationsFilters,\n ): Promise<MessagingConversationsListResponse> {\n const response = await this.client.get<MessagingConversationsListResponse>(\n `/api/clients/${clientId}/messaging/conversations`,\n { params: filters },\n );\n return response.data;\n }\n\n async getConversation(clientId: string, conversationId: string): Promise<MessagingConversation> {\n const response = await this.client.get<MessagingConversation>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}`,\n );\n return response.data;\n }\n\n async patchConversation(\n clientId: string,\n conversationId: string,\n payload: PatchConversationPayload,\n ): Promise<MessagingConversation> {\n const response = await this.client.patch<MessagingConversation>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}`,\n payload,\n );\n return response.data;\n }\n\n async getMessages(\n clientId: string,\n conversationId: string,\n params?: { page?: number; limit?: number },\n ): Promise<MessagingMessagesListResponse> {\n const response = await this.client.get<MessagingMessagesListResponse>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}/messages`,\n { params },\n );\n return response.data;\n }\n\n async sendMessage(\n clientId: string,\n conversationId: string,\n payload: SendMessagePayload,\n ): Promise<SendMessageResponse> {\n const response = await this.client.post<SendMessageResponse>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}/messages`,\n payload,\n );\n return response.data;\n }\n\n /**\n * Upload de mídia (ex.: áudio gerado por TTS) — pré-requisito pra mandar `type: 'audio'` no\n * `sendMessage` (o `content.id` retornado aqui vira `content.id` do envio; `storagePath`\n * precisa ser ecoado em `content._media.storagePath` no send, senão a plataforma não cria o\n * registro de mídia local pra conexões Cloud API).\n */\n async uploadMedia(clientId: string, payload: UploadMediaPayload): Promise<UploadMediaResponse> {\n const form = new FormData();\n // Ordem importa: phoneNumberId/isVoiceNote precisam vir ANTES de file no multipart — o\n // parser do Portal (e o da plataforma por trás dele) lê em stream.\n form.append('phoneNumberId', payload.phoneNumberId);\n if (payload.isVoiceNote) form.append('isVoiceNote', 'true');\n form.append(\n 'file',\n new Blob([new Uint8Array(payload.file)], { type: payload.mimeType }),\n payload.filename,\n );\n\n const response = await this.client.post<UploadMediaResponse>(\n `/api/clients/${clientId}/messaging/media`,\n form,\n );\n return response.data;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/client.ts","../src/base.ts","../src/errors.ts","../src/resources/clients/index.ts","../src/resources/knowledge/index.ts","../src/resources/messaging/index.ts"],"sourcesContent":["import axios, { AxiosInstance } from 'axios';\nimport { PortalClientConfig } from './types';\nimport { ClientsResource } from './resources/clients';\nimport { KnowledgeResource } from './resources/knowledge';\nimport { MessagingResource } from './resources/messaging';\nimport { PortalApiError } from './errors';\n\nconst DEFAULT_BASE_URL = 'https://portal.aiatende.com.br';\n\nexport class PortalClient {\n public config: PortalClientConfig;\n public httpClient: AxiosInstance;\n\n public clients: ClientsResource;\n public knowledge: KnowledgeResource;\n public messaging: MessagingResource;\n\n constructor(config: PortalClientConfig) {\n this.config = config;\n\n this.httpClient = axios.create({\n baseURL: config.baseUrl || DEFAULT_BASE_URL,\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n 'x-internal-token': config.apiKey\n }\n });\n\n this.httpClient.interceptors.response.use(\n (response) => response,\n (error) => {\n if (error.response) {\n const errData = error.response.data;\n throw new PortalApiError(errData?.error || 'Portal API Error', {\n status: error.response.status,\n raw: errData\n });\n }\n throw error;\n }\n );\n\n this.clients = new ClientsResource(this.httpClient);\n this.knowledge = new KnowledgeResource(this.httpClient);\n this.messaging = new MessagingResource(this.httpClient);\n }\n}\n","import { AxiosInstance } from 'axios';\n\nexport abstract class BaseResource {\n protected client: AxiosInstance;\n\n constructor(client: AxiosInstance) {\n this.client = client;\n }\n}\n","export class PortalApiError extends Error {\n status?: number;\n raw?: unknown;\n\n constructor(message: string, info?: Partial<PortalApiError>) {\n super(message);\n this.name = 'PortalApiError';\n\n if (info) {\n this.status = info.status;\n this.raw = info.raw;\n }\n }\n}\n","import { BaseResource } from '../../base';\nimport { PortalApiError } from '../../errors';\nimport { Client, ClientsListResponse } from './types';\n\nexport class ClientsResource extends BaseResource {\n /** Busca o Client dono de um subdomínio Kommo (`GET /api/clients?kommo_subdomain=...`). */\n async getByKommoSubdomain(subdomain: string): Promise<Client | null> {\n const response = await this.client.get<ClientsListResponse>('/api/clients', {\n params: { kommo_subdomain: subdomain, includeConfigs: true }\n });\n return response.data.data[0] ?? null;\n }\n\n /** Busca o Client dono de um canal Wazzup (`GET /api/clients?channelId=...`). */\n async getByWazzupChannelId(channelId: string): Promise<Client | null> {\n const response = await this.client.get<ClientsListResponse>('/api/clients', {\n params: { channelId, includeConfigs: true }\n });\n return response.data.data[0] ?? null;\n }\n\n /**\n * Busca o Client pelo seu id direto (`GET /api/clients/{id}`) — inclui `aiConfig` e\n * `messagingConfig` (sem a API key criptografada). Usado pelo canal aiatendeWa, que resolve o\n * tenant a partir do `clientId` já incluído no payload do relay de webhook, sem precisar de\n * um identificador de canal indireto como Kommo subdomain ou Wazzup channelId.\n */\n async getById(clientId: string): Promise<Client | null> {\n try {\n const response = await this.client.get<Client>(`/api/clients/${clientId}`);\n return response.data;\n } catch (error) {\n if (error instanceof PortalApiError && error.status === 404) return null;\n throw error;\n }\n }\n}\n","import { z } from 'zod';\nimport { BaseResource } from '../../base';\nimport { PortalApiError } from '../../errors';\nimport { GetInternalContextParams, InternalContextResult } from './types';\n\nconst internalContextChunkSchema = z.object({\n chunkId: z.string().optional(),\n content: z.string(),\n similarity: z.number(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nconst internalContextResultSchema = z.array(internalContextChunkSchema);\n\nexport class KnowledgeResource extends BaseResource {\n /** Recupera trechos relevantes da base RAG do cliente pra uma pergunta em texto puro (`POST /api/knowledge/internal/context`). O Portal gera o embedding internamente usando a `apiKey` do AiConfig. */\n async getInternalContext(params: GetInternalContextParams): Promise<InternalContextResult> {\n const response = await this.client.post<unknown>('/api/knowledge/internal/context', {\n aiConfigId: params.aiConfigId,\n question: params.question,\n conversationHistory: params.conversationHistory\n });\n\n const parsed = internalContextResultSchema.safeParse(response.data);\n if (!parsed.success) {\n throw new PortalApiError('Resposta inválida de /api/knowledge/internal/context', {\n raw: parsed.error.flatten(),\n });\n }\n return parsed.data;\n }\n}\n","import { BaseResource } from '../../base';\nimport {\n DownloadMediaResponse,\n ListConversationsFilters,\n MessagingConversation,\n MessagingConversationsListResponse,\n MessagingMessagesListResponse,\n PatchConversationPayload,\n SendMessagePayload,\n SendMessageResponse,\n UploadMediaPayload,\n UploadMediaResponse,\n} from './types';\n\n/**\n * Canal WhatsApp direto (aiatendeWa) — proxy pras rotas `/api/clients/{clientId}/messaging/...`\n * do Portal, que por sua vez falam com a plataforma de mensageria própria\n * (plataforma_whatsapp_coexistence). O atende360-assistant nunca fala direto com essa\n * plataforma — sempre por aqui, autenticado via a mesma `apiKey`/APP_API_KEY já usada pro\n * resto do SDK.\n */\nexport class MessagingResource extends BaseResource {\n async listConversations(\n clientId: string,\n filters?: ListConversationsFilters,\n ): Promise<MessagingConversationsListResponse> {\n const response = await this.client.get<MessagingConversationsListResponse>(\n `/api/clients/${clientId}/messaging/conversations`,\n { params: filters },\n );\n return response.data;\n }\n\n async getConversation(clientId: string, conversationId: string): Promise<MessagingConversation> {\n const response = await this.client.get<MessagingConversation>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}`,\n );\n return response.data;\n }\n\n async patchConversation(\n clientId: string,\n conversationId: string,\n payload: PatchConversationPayload,\n ): Promise<MessagingConversation> {\n const response = await this.client.patch<MessagingConversation>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}`,\n payload,\n );\n return response.data;\n }\n\n async getMessages(\n clientId: string,\n conversationId: string,\n params?: { page?: number; limit?: number },\n ): Promise<MessagingMessagesListResponse> {\n const response = await this.client.get<MessagingMessagesListResponse>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}/messages`,\n { params },\n );\n return response.data;\n }\n\n async sendMessage(\n clientId: string,\n conversationId: string,\n payload: SendMessagePayload,\n ): Promise<SendMessageResponse> {\n const response = await this.client.post<SendMessageResponse>(\n `/api/clients/${clientId}/messaging/conversations/${conversationId}/messages`,\n payload,\n );\n return response.data;\n }\n\n /**\n * Upload de mídia (ex.: áudio gerado por TTS) — pré-requisito pra mandar `type: 'audio'` no\n * `sendMessage` (o `content.id` retornado aqui vira `content.id` do envio; `storagePath`\n * precisa ser ecoado em `content._media.storagePath` no send, senão a plataforma não cria o\n * registro de mídia local pra conexões Cloud API).\n */\n async uploadMedia(clientId: string, payload: UploadMediaPayload): Promise<UploadMediaResponse> {\n const form = new FormData();\n // Ordem importa: phoneNumberId/isVoiceNote precisam vir ANTES de file no multipart — o\n // parser do Portal (e o da plataforma por trás dele) lê em stream.\n form.append('phoneNumberId', payload.phoneNumberId);\n if (payload.isVoiceNote) form.append('isVoiceNote', 'true');\n form.append(\n 'file',\n new Blob([new Uint8Array(payload.file)], { type: payload.mimeType }),\n payload.filename,\n );\n\n const response = await this.client.post<UploadMediaResponse>(\n `/api/clients/${clientId}/messaging/media`,\n form,\n // A instância do axios (client.ts) fixa Content-Type: application/json como default —\n // sem isto, esse header explícito vence e nunca deixa o axios detectar o FormData nativo\n // e gerar o multipart/form-data; boundary=... correto. `undefined` remove o default do\n // merge de headers só nesta chamada, liberando a detecção automática.\n { headers: { 'Content-Type': undefined } },\n );\n return response.data;\n }\n\n /**\n * Baixa os bytes de um anexo (Message.media[].id) — usado hoje só pelo caminho de imagem do\n * canal aiatendeWa (monta uma data URI pra mandar pro modelo de visão, já que a URL não pode\n * ser pública). Áudio/PDF seguem passando a URL autenticada direto pros métodos de\n * transcrição/extração do atende360-assistant, sem baixar bytes por aqui.\n */\n async downloadMedia(clientId: string, mediaId: string): Promise<DownloadMediaResponse> {\n const response = await this.client.get<ArrayBuffer>(\n `/api/clients/${clientId}/messaging/media/${mediaId}`,\n { responseType: 'arraybuffer' },\n );\n return {\n data: Buffer.from(response.data),\n contentType: (response.headers['content-type'] as string) || 'application/octet-stream',\n };\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "portal-aiatende-api",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Cliente TypeScript tipado para a API interna do Portal AI Atende.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",