Inbound email action not creating variables

joaopalmeida
Tera Contributor

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!

6 REPLIES 6

Rafael Batistot
Tera Sage

Hi @joaopalmeida 

 

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.

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

Ankur Bawiskar
Tera Patron
Tera Patron

@joaopalmeida 

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.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

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