Inbound email action not creating variables
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-22-2025 02:52 AM
Hello guys!
I'm in need of some help. When we're receiving an email, our action is constructing the RITM. The thing is, when we're creating the RITM we need it to fill the form, but the variables aswell. We've managed to get the short description to be filled, but not the description. Can we got some help on this please?
I'll provide you guys the code from our inbound email action.
(function runAction( /*GlideRecord*/ current, /*GlideRecord*/ event, /*EmailWrapper*/ email, /*ScopedEmailLogger*/ logger, /*EmailClassifier*/ classifier) {
try {
// LOG: Informações do email recebido
gs.info('=== EMAIL RECEBIDO ===');
gs.info('From: ' + (email.from || 'N/A'));
gs.info('To: ' + (email.to || 'N/A'));
gs.info('CC: ' + (email.copied || 'N/A'));
gs.info('Subject: ' + (email.subject || 'N/A'));
gs.info('=====================');
// NOVA VERIFICAÇÃO: Ignorar emails com endereços específicos em CC
var ignoreEmails = ['dev-snow@espap.gov.pt', 'cc@espap.gov.pt', 'prd-snow@espap.gov.pt', 'ppr-snow@espap.gov.pt', 'cc@espap.pt'];
// Verifica CC (email.copied contém os endereços em CC)
var ccList = email.copied ? email.copied.toString().toLowerCase() : '';
// Verifica se algum dos emails a ignorar está presente em CC
for (var i = 0; i < ignoreEmails.length; i++) {
if (ccList.indexOf(ignoreEmails[i].toLowerCase()) !== -1) {
gs.info('Email ignorado - encontrado ' + ignoreEmails[i] + ' em CC. Remetente: ' + email.from);
return; // Sai da função sem criar o registo
}
}
// Extrai o corpo do email em formato HTML
var htmlcode = email.body_html.toString().replace(/<br\/>/g, "\n");
// Remove tags <style> e seus conteúdos
htmlcode = htmlcode.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "");
// Remove tags <script> e seus conteúdos (por segurança, se houver)
htmlcode = htmlcode.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "");
// Substitui <br/> por quebras de linha
htmlcode = htmlcode.replace(/<br\/>/g, "\n");
// (Opcional) Remove outros atributos de estilo inline, se necessário
// Exemplo: remove 'style="..."' de qualquer tag
// htmlcode = htmlcode.replace(/style="[^"]*"/gi, "");
// Obtém o assunto do email
var subject = email.subject;
// Obtém o endereço de email do remetente
var sender = email.from;
// Cria um GlideRecord para consultar a tabela sys_user (utilizadores do sistema)
var userGr = new GlideRecord('sys_user');
userGr.addQuery('email', sender); // Adiciona a condição para encontrar o utilizador pelo email
userGr.addQuery('active', true); // Garante que o utilizador está ativo
userGr.setLimit(1); // Limita o resultado a um único registo
userGr.query(); // Executa a consulta
if (userGr.next()) {
// Se encontrar um utilizador ativo com o email correspondente, associa-o ao registo atual
current.opened_by = userGr.getUniqueValue(); // Define o utilizador como o que abriu o registo
// Condição adicional: se o remetente for 'mailing-noreply@espap.gov.pt', deixa o campo "Requerente" vazio
if (sender == 'mailing-noreply@espap.gov.pt') {
// logger.info('Antes de definir vazio, Requested_for: ' + current.requested_for);
current.setValue('requested_for', '1'); // Define "Requerente" como vazio
// logger.info('Requested_for definido como vazio para: ' + sender);
// logger.info('Após definir vazio, Requested_for: ' + current.requested_for); // Log para verificação
} else {
current.requested_for = userGr.getUniqueValue(); // Caso contrário, associa normalmente
}
} else {
// Se não encontrar um utilizador correspondente, cria um novo utilizador
userGr.initialize(); // Inicializa o objeto para inserção
userGr.u_tipo_utilizador = ""; // Define um valor vazio para o tipo de utilizador (pode ser alterado conforme necessário)
userGr.first_name = sender; // Usa o email como nome
userGr.user_name = sender; // Usa o email como nome de utilizador
userGr.email = sender; // Define o email
var newUserId = userGr.insert(); // Insere o novo utilizador na tabela
// Associa o novo utilizador criado ao registo atual
current.opened_by = newUserId;
// Condição adicional: se o remetente for 'mailing-noreply@espap.gov.pt', deixa o campo "Requerente" vazio
if (sender == 'mailing-noreply@espap.gov.pt') {
current.setValue('requested_for', '1'); // Define "Requerente" como vazio
//logger.info('Requested_for definido como vazio após criar novo utilizador para: ' + sender); // Log para verificação
} else {
current.requested_for = newUserId; // Caso contrário, associa normalmente
}
}
// Define o estado do registo (estado inicial, código '1')
current.state = '1';
// Define o assunto do registo
current.short_description = subject;
// Define outros campos do registo como impact, urgency, e description
current.impact = ''; // Impacto vazio (ajustar conforme necessidade)
current.urgency = ''; // Urgência vazia (ajustar conforme necessidade)
current.description = htmlcode; // Define a descrição como o corpo HTML processado
// Define o tipo de contacto como email
current.contact_type = 'email';
// 4A) CASO "simpana@espap.gov.pt"
if (sender === 'simpana@espap.gov.pt') {
// i) Se o body contiver a frase "No data was found for the selected criteria.",
// não criar registro (retorna antes de current.insert()).
if (htmlcode.indexOf("No data was found for the selected criteria.") !== -1) {
gs.info("Email de simpana@espap.gov.pt sem dados - não criar registo.");
return;
}
// Exemplo de configurações diferentes para simpana:
// (Atribuindo outro assignment group, outras categorias, etc.)
current.u_primeira_categoria = gs.getProperty('espap.primeira_categoria.sptic');
current.u_segunda_categoria = gs.getProperty('espap.segunda_categoria.recuperacao.info');
current.u_item_catalogo = gs.getProperty('espap.item.diagnosticar_erros_backup');
current.cmdb_ci = gs.getProperty('espap.cmdb_ci.backups');
}
// 4B) CASO "apoio@espap.pt", "apoio@espap.gov.pt", "ppr-apoio@espap.pt"
else if (sender == 'apoio@espap.pt' || sender == 'apoio@espap.gov.pt' || sender == 'ppr-apoio@espap.pt') {
current.urgency = '2';
current.impact = '3';
// Define campos específicos para estes remetentes
current.assignment_group.setDisplayValue('sn_gs_ditic_srh'); // Grupo de atribuição
current.u_primeira_categoria = gs.getProperty('espap.primeira_categoria.sprh'); // Primeira categoria
current.u_segunda_categoria = gs.getProperty('espap.segunda_categoria.srh'); // Segunda categoria
current.u_terceira_categoria = gs.getProperty('espap.terceira_categoria.apoio'); // Terceira categoria
current.u_item_catalogo = gs.getProperty('espap.item.apoio_funcional'); // Item do catálogo
current.cmdb_ci = gs.getProperty('espap.cmdb_ci.srhprd'); // Configuração de CI
} else {
// Para outros remetentes, define um grupo de atribuição diferente
current.assignment_group.setDisplayValue('sn_gs_ditic_sd');
}
// Insere o registo criado na base de dados
current.insert();
// gs.info('Valor final após insert quando o sender é o mailing-noreply@espap.gov.pt, Requested_for: ' + current.requested_for);
// === CASO GENÉRICO — criar variáveis se nenhuma regra especial foi aplicada ===
if (!['simpana@espap.gov.pt', 'apoio@espap.pt', 'apoio@espap.gov.pt', 'ppr-apoio@espap.pt'].includes(sender)) {
var catItemID = 'e92d56cb1b61f9101252646ee54bcbef'; // ← sys_id do item de catálogo com variáveis
current.cat_item = catItemID;
// Define os campos visíveis do pedido
current.short_description = subject;
current.description = htmlcode;
current.update();
// // Mapear as variáveis
var variaveis = {
'291d7fb4878c7510a0fc10a83cbb359d': subject, // "Breve Descrição"
'944e73f4878c7510a0fc10a83cbb35ca': htmlcode // "Descrição"
};
// // // Criar variáveis e associar ao RITM
for (var varID in variaveis) {
if (!variaveis[varID] || variaveis[varID].trim() === '')
continue; // Ignora se estiver vazio
var opt = new GlideRecord('sc_item_option');
opt.initialize();
opt.request_item = current.sys_id;
opt.item_option_new = varID;
opt.value = variaveis[varID];
var optID = opt.insert();
var mtom = new GlideRecord('sc_item_option_mtom');
mtom.initialize();
mtom.request_item = current.sys_id;
mtom.sc_item_option = optID;
mtom.insert();
}
}
} catch (ex) {
// Captura e regista erros durante a execução do script
gs.info('Inbound Error - ESPAP New Request: ' + ex);
}
})(current, event, email, logger, classifier);
I'll leave the image aswell. Basically where the variable appears on the picture is the short description. Now we wanted to get the description there aswell, but it doesn't seem to work. On the form itself, both short description and description are being correctly filled.
Thanks in Advance!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-22-2025 04:08 AM
Make sure the item_option_new IDs you’re using are the correct sys_id of the variable definitions (item_option_new table) and match the variables from the associated catalog item.
If you accidentally use the sys_id of variables from another catalog item, the variables won’t appear in the RITM view, even though the records exist in sc_item_option.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-23-2025 01:20 AM
Hi Rafael,
Thanks for the answer. Yes, that's exactly what we are using. Both short description and description variables are from the same var set, so we copied the sys_id from it. We also made sure field is HTML just like the one in the form, but still nothing gets copied to the var set
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-22-2025 04:17 AM
what debugging did you do?
why not use CART API or CartJS to create RITM, REQ?
need to create RITM based from email or outlook like based on email content
If my response helped please mark it correct and close the thread so that it benefits future readers.
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-22-2025 04:41 AM - edited 07-22-2025 04:43 AM
Whoever started this project, built this code like this. On the project we're not using REQ's at all, we never use carts. So I'm not sure this CART API or CartJS would work. Weird thing is we can force it to go on the short description but the same thing for the description just doesn't add any info there