I’m having trouble making the iframe html element communicate with the page and making the page communicate with scripti.web.js, even after modifying it more than 15 times the problem persists, how can I resolve this error?
Product:
wix editor, frontend page iframe widget html
My goal is to create a chat for questions and answers, but I can’t make the iframe element, page and backend communicate correctly even with more than 15 modifications
page code that uses velo and element messaging to communicate with the iframe element and backend :
// chatai.js
import { webMethod, Permissions } from "wix-web-module";
import { enviarPergunta } from "backend/script.web.js";
export const askQuestion = webMethod(Permissions.Anyone, async (question) => {
try {
const response = await enviarPergunta(question);
return response;
} catch (error) {
console.error('Error in askQuestion:', error);
return 'Error communicating with backend';
}
});
$w.onReady(async function () {
// Recebe mensagem do HTML e processa
$w("#html2").onMessage(async (event) => {
const receivedData = event.data;
console.log('Received message from HTML:', receivedData);
if (receivedData && receivedData.type === 'SEND_MESSAGE') {
const question = receivedData.text;
const response = await askQuestion(question);
$w("#html2").postMessage({ type: 'RECEIVE_MESSAGE', text: response });
}
});
});
HTML iframe element code of custom codes that uses messaging event to communicate with the page:
<script type="text/javascript">
// Adiciona um event listener ao formulário com id 'message-form' para interceptar o evento de submissão
document.getElementById('message-form').addEventListener('submit', async function(event) {
// Previne o comportamento padrão do formulário, que seria recarregar a página
event.preventDefault();
// Seleciona o campo de entrada com a classe 'input-msg'
const input = document.querySelector('.input-msg');
// Obtém o texto da mensagem, removendo espaços em branco do início e do final
const messageText = input.value.trim();
// Verifica se o campo de entrada não está vazio
if (messageText) {
// Adiciona a mensagem ao container de conversação com o tipo 'sent'
addMessage(messageText, 'sent');
// Limpa o campo de entrada após o envio da mensagem
input.value = '';
try {
// Define uma função para enviar a mensagem para o backend usando `postMessage`
function respond() {
// Envia a mensagem para o iframe ou janela pai usando postMessage
window.parent.postMessage(messageText, "http://www.microsoftware.com/chatai");
}
// Adiciona um listener para o evento 'message' que será acionado quando uma mensagem for recebida
window.onmessage = (event) => {
if (event.data) {
// A variável 'receivedData' deve receber a resposta do backend
let receivedData = event.data;
// Verifica se a resposta contém dados
if (receivedData) {
// Extrai os resultados da resposta
const scriptResults = receivedData.results;
// Concatena todos os textos gerados ou erros em uma única string, separando-os por uma quebra de linha
const responseText = Object.values(scriptResults)
.map((result) => result.generated_text || result.error)
.join('\n');
// Adiciona a resposta ao container de conversação com o tipo 'received'
addMessage(responseText, 'received');
} else {
// Caso não haja resposta do servidor, adiciona uma mensagem de erro ao container de conversação
addMessage('No response from server', 'error');
}
}
};
// Chama a função respond para enviar a mensagem
respond();
} catch (error) {
// Se ocorrer um erro durante a comunicação com o backend, registra o erro no console e adiciona uma mensagem de erro ao container de conversação
console.error(error);
addMessage('Error communicating with backend', 'error');
}
}
});
// Função para adicionar uma mensagem ao container de conversação
function addMessage(text, type) {
// Seleciona o container de conversação com o id 'conversation-container'
const conversationContainer = document.getElementById('conversation-container');
// Cria um novo elemento div para a mensagem
const messageElement = document.createElement('div');
// Define a classe do elemento com base no tipo de mensagem ('sent', 'received', 'error')
messageElement.className = `message ${type}`;
// Define o texto do elemento como o texto da mensagem
messageElement.textContent = text;
// Adiciona o novo elemento ao container de conversação
conversationContainer.appendChild(messageElement);
// Faz com que o container de conversação role para mostrar a última mensagem adicionada
conversationContainer.scrollTop = conversationContainer.scrollHeight;
}
</script>
backend code that uses velo to communicate with the page:
// script.web.js
import { Permissions, webMethod } from "wix-web-module";
import { askQuestion } from 'backend/consulta.js'; // Importa a função askQuestion do backend
// Define um método web para enviar perguntas e receber respostas do consulta.js
export const enviarPergunta = webMethod(Permissions.SiteMember, async (question) => {
try {
// Chama a função askQuestion do backend e passa a pergunta como parâmetro
const resposta = await askQuestion(question);
return resposta;
} catch (error) {
console.error("Erro ao chamar askQuestion:", error);
return { error: "Erro ao processar a pergunta" };
}
});
Previously, velo code support said that my error was using exclusive backend methods on the frontend of the page and even after correcting this I was unable to make the chat work correctly because no type of response appeared in it.
References that you use to communicate between scripts: