Skip to main content
Glama
digitalpages-api-client.js9.72 kB
/** * @document DigitalPages API Client for EuConquisto Platform Integration * @version 1.0.0 * @status active * @author Claude Code * @created 2025-07-01 * @description Complete DigitalPages API integration for server-side composition persistence */ import fetch from 'node-fetch'; export class DigitalPagesAPIClient { constructor(jwtToken) { this.jwtToken = jwtToken; this.config = { BASE_URL: 'https://api.digitalpages.com.br', DYNAMIC_CONTENT_URL: 'https://dynamic-content.euconquisto.com', PROJECT_UID: '36c92686-c494-ec11-a22a-dc984041c95d', CONNECTOR_UID: '93c952c2-680c-ed11-bd6e-dc98407f3f93', PROJECT_KEY: 'e3894d14dbb743d78a7efc5819edc52e', API_ENV: 'prd' }; } /** * Validate user authentication * @returns {Promise<Object>} User validation response */ async validateUser() { try { const response = await fetch(`${this.config.BASE_URL}/auth/v1.0/user/me`, { method: 'GET', headers: { 'Authorization': `Bearer ${this.jwtToken}`, 'Accept': 'application/json' } }); if (!response.ok) { throw new Error(`User validation failed: ${response.status}`); } return await response.json(); } catch (error) { console.error('❌ User validation error:', error); throw error; } } /** * Validate project access * @returns {Promise<Object>} Project validation response */ async validateProject() { try { const response = await fetch(`${this.config.BASE_URL}/auth/v1.0/project/uid/${this.config.PROJECT_UID}`, { method: 'GET', headers: { 'Authorization': `Bearer ${this.jwtToken}`, 'Accept': 'application/json' } }); if (!response.ok) { throw new Error(`Project validation failed: ${response.status}`); } return await response.json(); } catch (error) { console.error('❌ Project validation error:', error); throw error; } } /** * Validate connector access * @returns {Promise<Object>} Connector validation response */ async validateConnector() { try { const response = await fetch(`${this.config.BASE_URL}/auth/v1.1/connector/uid/${this.config.CONNECTOR_UID}`, { method: 'GET', headers: { 'Authorization': `Bearer ${this.jwtToken}`, 'Accept': 'application/json' } }); if (!response.ok) { throw new Error(`Connector validation failed: ${response.status}`); } return await response.json(); } catch (error) { console.error('❌ Connector validation error:', error); throw error; } } /** * Generate composition UID * @param {Object} composition - Composition data * @returns {string} Base64/gzip encoded UID */ generateCompositionUid(composition) { // For now, generate a unique identifier // In production, this should match the UID encoding pattern from network traffic const timestamp = Date.now(); const random = Math.random().toString(36).substring(2, 15); return `composition-${timestamp}-${random}`; } /** * Save composition to DigitalPages API * @param {Object} composition - Composition data to save * @returns {Promise<Object>} Save response with composition details */ async saveComposition(composition) { try { console.log('💾 Saving composition to DigitalPages API...'); // Generate composition UID const compositionUid = this.generateCompositionUid(composition); // Prepare the API endpoint const saveUrl = `${this.config.BASE_URL}/storage/v1.0/content/versions/dynamic`; const params = new URLSearchParams({ manual_project_uid: this.config.PROJECT_UID, uid: compositionUid }); // Make the POST request const response = await fetch(`${saveUrl}?${params}`, { method: 'POST', headers: { 'Authorization': `Bearer ${this.jwtToken}`, 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ ...composition, metadata: { ...composition.metadata, projectUid: this.config.PROJECT_UID, connectorUid: this.config.CONNECTOR_UID, contentType: 'digitalpages/composer', apiEnv: this.config.API_ENV } }) }); if (!response.ok) { const errorText = await response.text(); throw new Error(`Composition save failed: ${response.status} - ${errorText}`); } const result = await response.json(); console.log('✅ Composition saved successfully'); console.log(`📍 Composition UID: ${compositionUid}`); return { success: true, compositionUid: compositionUid, response: result, timestamp: new Date().toISOString() }; } catch (error) { console.error('❌ Composition save error:', error); return { success: false, error: error.message, timestamp: new Date().toISOString() }; } } /** * Verify composition was saved successfully * @param {string} compositionUid - UID of the composition to verify * @returns {Promise<Object>} Verification response */ async verifyComposition(compositionUid) { try { console.log('🔍 Verifying composition persistence...'); const verifyUrl = `${this.config.BASE_URL}/storage/v1.0/content/versions/`; const params = new URLSearchParams({ uid: compositionUid }); const response = await fetch(`${verifyUrl}?${params}`, { method: 'GET', headers: { 'Authorization': `Bearer ${this.jwtToken}`, 'Accept': 'application/json' } }); if (!response.ok) { throw new Error(`Verification failed: ${response.status}`); } const result = await response.json(); console.log('✅ Composition verified successfully'); return { success: true, verified: true, data: result, timestamp: new Date().toISOString() }; } catch (error) { console.error('❌ Verification error:', error); return { success: false, verified: false, error: error.message, timestamp: new Date().toISOString() }; } } /** * Retrieve composition content * @param {string} compositionUid - UID of the composition to retrieve * @returns {Promise<Object>} Composition content */ async getComposition(compositionUid) { try { const contentUrl = `${this.config.BASE_URL}/storage/v1.0/content`; const params = new URLSearchParams({ uid: compositionUid, access_token: this.jwtToken, project_key: this.config.PROJECT_KEY, api_env: this.config.API_ENV }); const response = await fetch(`${contentUrl}?${params}`, { method: 'GET', headers: { 'Accept': 'application/json' } }); if (!response.ok) { throw new Error(`Content retrieval failed: ${response.status}`); } return await response.json(); } catch (error) { console.error('❌ Content retrieval error:', error); throw error; } } /** * Generate permanent composition URL * @param {string} compositionUid - UID of the composition * @returns {string} Permanent URL for the composition */ generatePermanentUrl(compositionUid) { // Generate the permanent URL based on the dynamic content pattern const directoryUid = this.config.PROJECT_UID.substring(0, 8); // Example extraction const stateHash = Date.now().toString(36); // Example state hash return `${this.config.DYNAMIC_CONTENT_URL}/storage/v1.0/content/instance/uid/${compositionUid}/d/${directoryUid}/p/${this.config.PROJECT_UID}/state/${stateHash}/path/`; } /** * Complete workflow: validate, save, and verify composition * @param {Object} composition - Composition data * @returns {Promise<Object>} Complete workflow result */ async saveAndVerifyComposition(composition) { try { console.log('🚀 Starting complete DigitalPages API workflow...'); // Step 1: Validate authentication console.log('🔐 Validating authentication...'); await this.validateUser(); await this.validateProject(); // Step 2: Save composition console.log('💾 Saving composition...'); const saveResult = await this.saveComposition(composition); if (!saveResult.success) { throw new Error(`Save failed: ${saveResult.error}`); } // Step 3: Verify persistence console.log('🔍 Verifying persistence...'); const verifyResult = await this.verifyComposition(saveResult.compositionUid); // Step 4: Generate permanent URL const permanentUrl = this.generatePermanentUrl(saveResult.compositionUid); console.log('✅ Complete workflow successful'); console.log(`🌐 Permanent URL: ${permanentUrl}`); return { success: true, compositionUid: saveResult.compositionUid, permanentUrl: permanentUrl, saveResult: saveResult, verifyResult: verifyResult, timestamp: new Date().toISOString() }; } catch (error) { console.error('❌ Complete workflow error:', error); return { success: false, error: error.message, timestamp: new Date().toISOString() }; } } } export default DigitalPagesAPIClient;

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