Skip to main content
Glama
api-client.ts•7.1 kB
/** * EuConquisto Composer HTTP API Client * * Direct API implementation to replace browser automation. * Uses the discovered storage API endpoints for composition management. */ import { readFileSync } from 'fs'; import { resolve, dirname } from 'path'; import { fileURLToPath } from 'url'; // Check if fetch is available globally (Node.js 18+) const globalFetch = global.fetch || (typeof fetch !== 'undefined' ? fetch : null); if (!globalFetch) { throw new Error('This module requires Node.js 18+ with built-in fetch support, or a fetch polyfill'); } export interface CompositionMetadata { title: string; description?: string; thumb?: string | null; tags?: string[]; } export interface CompositionWidget { id: string; type: string; content: string; background_color?: string; padding_top?: number; padding_bottom?: number; [key: string]: any; // Allow additional widget-specific properties } export interface CompositionData { version: string; metadata: CompositionMetadata; interface: { content_language: string; index_option: string; font_family: string; show_summary: string; finish_btn: string; }; structure: CompositionWidget[]; } export interface APIResponse { success: boolean; data?: any; error?: string; statusCode: number; } export class EuConquistoAPIClient { private readonly baseURL = "https://api.digitalpages.com.br"; private readonly projectUID = "36c92686-c494-ec11-a22a-dc984041c95d"; private readonly jwtToken: string; constructor() { // Read the corrected JWT token from file (ES module compatible) const currentDir = dirname(fileURLToPath(import.meta.url)); const tokenPath = resolve(currentDir, '../correct-jwt-new.txt'); this.jwtToken = readFileSync(tokenPath, 'utf8').trim(); } /** * Get authorization headers for API requests */ private getHeaders(): Record<string, string> { return { 'Authorization': `Bearer ${this.jwtToken}`, 'User-Agent': 'EuConquisto-MCP-Client/1.0', }; } /** * Create a new composition via the storage API */ async createComposition(compositionData: CompositionData, uid?: string): Promise<APIResponse> { try { const compositionUID = uid || this.generateUID(); const url = `${this.baseURL}/storage/v1.0/content?uid=${compositionUID}&manual_project_uid=${this.projectUID}`; // Create the composition file content const compositionJSON = JSON.stringify(compositionData, null, 2); // Create FormData for multipart upload const formData = new FormData(); const blob = new Blob([compositionJSON], { type: 'digitalpages/composer' }); formData.append('file', blob, 'composition.rdpcomposer'); const response = await fetch(url, { method: 'POST', headers: this.getHeaders(), body: formData }); const result = await response.json(); return { success: response.ok, data: result, statusCode: response.status, error: response.ok ? undefined : `API Error: ${response.status} ${response.statusText}` }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Unknown error', statusCode: 0 }; } } /** * Update an existing composition */ async updateComposition(uid: string, compositionData: CompositionData): Promise<APIResponse> { try { const url = `${this.baseURL}/storage/v1.0/content?uid=${uid}&manual_project_uid=${this.projectUID}`; const compositionJSON = JSON.stringify(compositionData, null, 2); const formData = new FormData(); const blob = new Blob([compositionJSON], { type: 'digitalpages/composer' }); formData.append('file', blob, 'composition.rdpcomposer'); const response = await fetch(url, { method: 'PUT', headers: this.getHeaders(), body: formData }); const result = await response.json(); return { success: response.ok, data: result, statusCode: response.status, error: response.ok ? undefined : `API Error: ${response.status} ${response.statusText}` }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Unknown error', statusCode: 0 }; } } /** * Test API connection */ async testConnection(): Promise<APIResponse> { try { // Test with a simple GET request to check authentication const url = `${this.baseURL}/storage/v1.0/search?project_uid=${this.projectUID}&limit=1`; const response = await fetch(url, { method: 'GET', headers: this.getHeaders() }); let responseData; try { responseData = await response.json(); } catch { responseData = await response.text(); } return { success: response.ok, data: response.ok ? { message: 'API connection successful', endpoint: this.baseURL, project: this.projectUID, response: responseData } : responseData, statusCode: response.status, error: response.ok ? undefined : `Connection failed: ${response.status} ${response.statusText}` }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Connection error', statusCode: 0 }; } } /** * Create a basic composition structure */ createBasicComposition(title: string, description?: string): CompositionData { return { version: "1.1", metadata: { title, description: description || "", thumb: null, tags: [] }, interface: { content_language: "pt_br", index_option: "buttons", font_family: "Lato", show_summary: "disabled", finish_btn: "disabled" }, structure: [] }; } /** * Add a text widget to composition */ addTextWidget(content: string, backgroundColor: string = "#FFFFFF"): CompositionWidget { return { id: this.generateUID(), type: "text-1", content: `<p>${content}</p>`, background_color: backgroundColor, padding_top: 0, padding_bottom: 0 }; } /** * Add a header widget to composition */ addHeaderWidget(title: string, subtitle?: string): CompositionWidget { const content = subtitle ? `<h1>${title}</h1><h2>${subtitle}</h2>` : `<h1>${title}</h1>`; return { id: this.generateUID(), type: "head-1", content, background_color: "#FFFFFF", padding_top: 20, padding_bottom: 20 }; } /** * Generate a simple UID for widgets/compositions */ private generateUID(): string { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { const r = Math.random() * 16 | 0; const v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rkm097git/euconquisto-composer-mcp-poc'

If you have feedback or need assistance with the MCP directory API, please join our Discord server