Java Script SDK Uncaught TypeError: Cannot read properties of undefined (reading 'ApiClient')

Hi

I developed a services on AWS hosting the js and HTML files that I am integrating into genesys cloud for the agents to use and I get this error when its loading and its designed to pull in the conversation but it does not happen.
Uncaught TypeError: Cannot read properties of undefined (reading 'ApiClient')
at main.js:4:38
(anonymous) @ main.js:4

After this I get this stash-logger.js:233 ["Failed to authenticate gcba: Error: gcbaId is not provided: undefined",{"activeConversations":["58f0b3f4-ac0c-4c8c-8c10-6f5a8eeb743d"]}]

Can you please advice what you need to assist me with this issue

Hi Abrie,

Can you provide some more info and could you share some of your code so we can try to replicate this? Also, does this issue show up when you run locally?

Regards,
Declan

When running locally it works but I had to make changes to make it work in aws so its scalable here is my main.js code that use aws api gateway with the information and sends the body of the email in a post > import view from './view.js';

import config from './config.js';

const client = window.platformClient.ApiClient.instance;

const conversationsApi = new platformClient.ConversationsApi();
let currentConversationId = '';
let translationData = null;
let genesysCloudLanguage = 'en-us';
let messageId = '';
let customerEmail = '';
let customerName = '';
let agentEmail = '';
let agentName = '';
let subject = '';

function extractEmailBody(emailContent) {
// Attempt to isolate the latest message in the thread
// Look for patterns indicating the start of a quoted message
const quotedMessagePattern = /On .* wrote:/;
let latestMessageContent = emailContent;
const match = emailContent.search(quotedMessagePattern);
if (match !== -1) {
// If a quoted message start is found, slice the content to only include text before it
latestMessageContent = emailContent.slice(0, match);
}

// Split the latest email content into lines for easier processing
const lines = latestMessageContent.split(/\r?\n/);
let bodyLines = [];

// Flags to detect headers and unwanted lines
let inHeader = true;

for (const line of lines) {
    // Check for timestamp and header patterns typical at the start of each email in a thread
    if (inHeader && line.match(/\w{3}, \d{2} \w{3} \d{4} \d{2}:\d{2}/)) {
        continue;
    }
    
    // Enhance footer detection with additional common patterns
    if (line.match(/(--|Kind regards,|Best regards,|Sincerely,|Thank you,|Thanks,|Regards,|\bwww\.\S+|LinkedIn|Twitter|Facebook|✆|📞|\bPhone:|\bEmail:)/i)) {
        // Stop processing if we hit common footer patterns
        break;
    }

    // When the header ends, collect the body lines
    if (line === '') {
        inHeader = false;
    }

    if (!inHeader) {
        bodyLines.push(line);
    }
}

// Join the body lines back into a single string and trim it
return bodyLines.join('\n').trim();

}

function getEmailDetails(data){
console.log('[getEmailDetails] Extracting email details...');
// Extract the body of the email using the new function
let emailBody = extractEmailBody(data.textBody);

customerEmail = data.from.email;
customerName = data.from.name;
agentEmail  = data.to[0].email;
agentName = data.to[0].name;
subject = data.subject;

console.log(`[getEmailDetails] Details extracted: Subject - ${subject}, From - ${customerEmail}, To - ${agentEmail}`);

translateMessage(emailBody, genesysCloudLanguage, 'customer')
.then((translatedData) => {
    translationData = translatedData;
    console.log('[getEmailDetails] Email body translated.');
}).catch(error => console.error('[getEmailDetails] Error translating email body:', error));

}

function translateMessage(message, language, purpose){
console.log([translateMessage] Translating message for "${purpose}" in "${language}" language.);

const apiGatewayUrl = 'https://w63tpm9jnj.execute-api.eu-west-2.amazonaws.com/default/AWSTranslateV2'; // Replace with your actual API Gateway URL

return fetch(apiGatewayUrl, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        // If you have set up an API key or other authorization, include it here as a header
    },
    body: JSON.stringify({
        text: message,
        targetLanguageCode: language
    })
})
.then(response => {
    if (!response.ok) {
        throw new Error('Network response was not ok');
    }
    return response.json();
})
.then(data => {
    console.log(`[translateMessage] Translation success for "${purpose}".`);
    view.addMessage(data.translatedText, purpose); // Adjust this if the structure of data is different
    return data;
})
.catch(error => {
    console.error('[translateMessage] Translation error:', error);
    throw error;
});

}

function sendMessage(){
console.log('[sendMessage] Sending message...');
let message = document.getElementById('message-textarea').value;

translateMessage(message, getSourceLanguage(), 'agent')
.then((translatedData) => {
    let body = {
        'to': [{'email': customerEmail, 'name': customerName}],
        'from': {'email': agentEmail, 'name': agentName},
        'subject': subject,
        'textBody': translatedData.translated_text,
        'historyIncluded': true
    };

    conversationsApi.postConversationsEmailMessages(currentConversationId, body)
        .then(() => console.log('[sendMessage] Translated email sent to customer.'))
        .catch(error => console.error('[sendMessage] Error sending translated email:', error));
}).catch(error => console.error('[sendMessage] Error in translation process:', error));    

}

function copyToClipboard(){
console.log('[copyToClipboard] Copying message to clipboard...');
let message = document.getElementById('message-textarea').value;

translateMessage(message, getSourceLanguage(), 'agent')
.then((translatedData) => {
    var dummy = document.createElement('textarea');
    document.body.appendChild(dummy);
    dummy.value = translatedData.translated_text;
    dummy.select();
    document.execCommand('copy');
    document.body.removeChild(dummy);

    console.log('[copyToClipboard] Translated message copied to clipboard!');
}).catch(error => console.error('[copyToClipboard] Error copying message to clipboard:', error));

}

function getSourceLanguage(){
console.log('[getSourceLanguage] Determining source language...');
let sourceLang = translationData === null ? 'en' : translationData.source_language;
console.log([getSourceLanguage] Source language determined: ${sourceLang});
return sourceLang;
}

document.addEventListener('DOMContentLoaded', () => {
// Event Handlers Setup
const btnSend = document.getElementById('btn-send');
const btnCopy = document.getElementById('btn-copy');

if(btnSend) {
    btnSend.addEventListener('click', sendMessage);
} else {
    console.error('[Event Setup] btn-send not found');
}

if(btnCopy) {
    btnCopy.addEventListener('click', copyToClipboard);
} else {
    console.error('[Event Setup] btn-copy not found');
}

// Initial Setup
console.log('[Initial Setup] Starting application setup...');
const urlParams = new URLSearchParams(window.location.search);
currentConversationId = urlParams.get('conversationid');
genesysCloudLanguage = urlParams.get('language');

client.setPersistSettings(true, 'chat-translator');
client.setEnvironment(config.genesysCloud.region);
client.loginImplicitGrant(config.clientID, config.redirectUri, { state: JSON.stringify({ conversationId: currentConversationId, language: genesysCloudLanguage }) })
.then(data => {
    console.log('[Initial Setup] Logged in successfully.');

    let stateData = JSON.parse(data.state);
    currentConversationId = stateData.conversationId;
    genesysCloudLanguage = stateData.language;

    return conversationsApi.getConversationsEmail(currentConversationId);
}).then(data => {
    console.log('[Initial Setup] Conversation data retrieved.');

    messageId = data.participants.find(p => p.purpose == 'customer').messageId;
    return conversationsApi.getConversationsEmailMessage(currentConversationId, messageId);
}).then(data => { 
    console.log('[Initial Setup] Email message data retrieved.');
    getEmailDetails(data);
}).then(() => {
    console.log('[Initial Setup] Finished Setup.');
}).catch(e => console.error('[Initial Setup] Setup error:', e));

});

Hi

Do you perhaps have any feedback for me

Hi Abrie,

If your code works locally, the problem might be due to different configuration in your aws environment. The issue could be with how you are using window. It's possible platformClient is not being added to window correctly.

Regards,
Declan