mirror of
https://github.com/complexcaresolutions/whatsapp-bot.git
synced 2026-03-17 15:04:07 +00:00
Phase 1 implementation with all core modules: - Fastify webhook server with Meta signature validation - WhatsApp Cloud API client (send text/template/interactive, mark as read) - LLM abstraction layer with Claude provider (Haiku for speed) - BullMQ message processing pipeline (dedup, rate limiting) - Bot routing (MessageRouter, ConversationManager, EscalationManager) - Payload CMS integration (InteractionWriter via direct DB, RulesLoader, TemplateResolver) - Healthcare-safe system prompt with medical keyword detection - PM2 ecosystem config Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
72 lines
1.9 KiB
TypeScript
72 lines
1.9 KiB
TypeScript
import { getLogger } from '../lib/logger.js'
|
|
import { getConfig } from '../config.js'
|
|
|
|
const log = getLogger('payload-client')
|
|
|
|
export class PayloadClient {
|
|
private baseUrl: string
|
|
private apiKey?: string
|
|
|
|
constructor() {
|
|
const config = getConfig()
|
|
this.baseUrl = config.PAYLOAD_API_URL
|
|
this.apiKey = config.PAYLOAD_API_KEY
|
|
}
|
|
|
|
async find<T>(
|
|
collection: string,
|
|
query: Record<string, unknown> = {},
|
|
): Promise<{ docs: T[]; totalDocs: number }> {
|
|
const params = new URLSearchParams()
|
|
for (const [key, value] of Object.entries(query)) {
|
|
if (value !== undefined) {
|
|
params.set(key, String(value))
|
|
}
|
|
}
|
|
|
|
const url = `${this.baseUrl}/${collection}?${params.toString()}`
|
|
const response = await this.request<{ docs: T[]; totalDocs: number }>(url)
|
|
return response
|
|
}
|
|
|
|
async findByID<T>(collection: string, id: number | string): Promise<T> {
|
|
const url = `${this.baseUrl}/${collection}/${id}`
|
|
return this.request<T>(url)
|
|
}
|
|
|
|
async create<T>(
|
|
collection: string,
|
|
data: Record<string, unknown>,
|
|
): Promise<T> {
|
|
const url = `${this.baseUrl}/${collection}`
|
|
return this.request<T>(url, {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
private async request<T>(url: string, init?: RequestInit): Promise<T> {
|
|
const headers: Record<string, string> = {
|
|
'Content-Type': 'application/json',
|
|
}
|
|
if (this.apiKey) {
|
|
headers['Authorization'] = `Bearer ${this.apiKey}`
|
|
}
|
|
|
|
const response = await fetch(url, {
|
|
...init,
|
|
headers: { ...headers, ...init?.headers },
|
|
})
|
|
|
|
if (!response.ok) {
|
|
const body = await response.text().catch(() => '')
|
|
log.error(
|
|
{ url, status: response.status, body: body.slice(0, 200) },
|
|
'Payload API error',
|
|
)
|
|
throw new Error(`Payload API error: ${response.status}`)
|
|
}
|
|
|
|
return response.json() as Promise<T>
|
|
}
|
|
}
|