Challenges with Passing caller_id Phone Number from UI Page to Script Include for OTP Verification

naborowiak
Tera Contributor

Hello ServiceNow Community,

 

I'm encountering a challenge with a feature I'm implementing, which involves sending an OTP (One Time Password) to either a personal or business phone number associated with the caller_id of an incident record. The process is facilitated through a custom UI Page and a Script Include, but I'm facing issues with correctly passing the phone number from the UI Page to the Script Include for the OTP sending process.

 

Current Implementation:

  1. Script Include (VerifyCodeAjax): This Script Include is intended to receive a phoneType (personal or business), fetch the corresponding phone number from the user record (caller_id on Incident), format it, and send an OTP using Twilio.

  2. UI Page: The UI Page allows users to select between their personal and business phone numbers (fetched and displayed on the page) and initiates the OTP sending process via a GlideAjax call to the VerifyCodeAjax Script Include.

Issue Experienced: The process fails to correctly identify and send the OTP to the selected phone number. Specifically, when "Personal" is selected, the system still attempts to send the OTP to the "Business" phone number.

 

Script Include Snippet:

 

var VerifyCodeAjax = Class.create();
VerifyCodeAjax.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    sendCode: function() {
        var phoneType = this.getParameter('sysparm_phone_type').toString().trim();
        gs.info('sendCode - Phone Type: ' + phoneType);

        var recordId = this.getParameter('sysparm_record_id');
        var incidentGR = new GlideRecord('incident');
        if (!incidentGR.get(recordId)) {
            return "Incident record not found!";
        }

        var userSysId = incidentGR.getValue('caller_id');
        var userGR = new GlideRecord('sys_user');
        if (!userGR.get(userSysId)) {
            return "User not found!";
        }

        var phoneNumberField = phoneType === 'personal' ? 'mobile_phone' : 'u_work_mobile';
        var phoneNumber = userGR.getValue(phoneNumberField);
        if (!phoneNumber) {
            return "Phone number not found for selected type!";
        }

        var formattedPhoneNumber = this.formatPhoneNumber(phoneNumber);
        if (!formattedPhoneNumber) {
            return "Invalid phone number format!";
        }

        gs.info('sendCode - Formatted Phone Number: ' + formattedPhoneNumber);

        // Assuming sending SMS logic here

        var r = new sn_ws.RESTMessageV2('TWILIO', 'TWILIO Verify');
        r.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
        r.setRequestBody('to=' + encodeURIComponent(formattedPhoneNumber) + '&channel=sms');
        var response = r.execute();
        var responseBody = response.getBody();
        var httpStatus = response.getStatusCode();

        gs.info('HTTP Status for sending code: ' + httpStatus);
        gs.info('Response Body: ' + responseBody);

        return "Code sent to " + (phoneType === 'personal' ? "personal" : "business") + " phone number.";

    },

    verifyCode: function() {
        var verificationCode = this.getParameter('sysparm_verification_code');
        var phoneType = this.getParameter('sysparm_phone_type');
        var recordId = this.getParameter('sysparm_record_id');

        var incidentGR = new GlideRecord('incident');
        if (!incidentGR.get(recordId)) {
            return "Incident record not found!";
        }

        var userSysId = incidentGR.getValue('caller_id');
        var userGR = new GlideRecord('sys_user');
        if (!userGR.get(userSysId)) {
            return "User not found!";
        }

        var phoneNumberField = phoneType === 'personal' ? 'mobile_phone' : 'u_work_mobile';
        var phoneNumber = userGR.getValue(phoneNumberField);
        var formattedPhoneNumber = this.formatPhoneNumber(phoneNumber);
        if (!formattedPhoneNumber) {
            return "Invalid phone number format!";
        }

        // Assuming verification logic here
        var r = new sn_ws.RESTMessageV2('TWILIO', 'TWILIO Verify');
        r.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
        r.setRequestBody('to=' + encodeURIComponent(formattedPhoneNumber) + '&code=' + verificationCode);

        var response = r.execute();
        var responseBody = response.getBody();
        var httpStatus = response.getStatusCode();

        gs.info('HTTP Status for verification: ' + httpStatus);
        gs.info('Response Body: ' + responseBody);

        var responseObj = JSON.parse(responseBody);
        if (responseObj.success) {
            gs.info('Verification successful.');
            return "Verification successful!";
        } else {
            gs.info('Verification failed.');
            return "Verification failed!";
        }
    },

    formatPhoneNumber: function(phoneNumber) {
        var cleaned = phoneNumber.replace(/\D/g, '');
        return cleaned.length === 10 ? '+1' + cleaned : '';
    },

    type: 'VerifyCodeAjax'
});

 

 

 

 

UI Page Snippet:

 

 

<style>
   /* Additional styles for phone number labels and last four digits */
    .phone-label {
        font-weight: bold;
    }
    .phone-number {
        font-style: italic;
    }
    .sms-verification-container {
        display: flex;
        flex-direction: column;
        align-items: center;
        padding: 20px 60px 25% 60px; /* Increased bottom padding */
        background-color: #f5f5f5;
        border-radius: 5px;
        color: #010f59;
        text-align: center;
        font-size: 1.2em; /* Increased font size */
        background-size: 40px 40px;
        background-position: 0 0, 20px 20px;
    }
    .sms-verification-container .company-logo {
        max-width: 50%;
        height: auto;
        margin-bottom: 20px;
    }
    .sms-verification-container .image-container {
        border-radius: 50%;
        background-color: white;
        padding: 20px; /* Increased padding */
        margin-bottom: 20px;
    }
    .sms-verification-container .image-container img {
        max-width: 100%;
        height: auto;
    }
    .sms-verification-container .verify-text {
        font-weight: bold;
    }
    .sms-verification-container .sms-text {
        font-weight: normal;
    }
    .sms-verification-container .btn {
        padding: 15px 30px;
        margin: 15px;
        font-size: 1.4em;
        transition: background-color 0.3s;
        color: #fff;
        border-radius: 2rem !important; /* Rounded corners with a radius of 2rem */
    }
    .sms-verification-container .btn-send {
        background-color: #1702ff; /* Blue color for Send button */
    }
    .sms-verification-container .btn-send:hover {
        background-color: #0e01cc; /* Darker shade of blue for hover */
    }
    .sms-verification-container .btn-verify {
        background-color: #00b317; /* Green color for Verify button */
    }
    .sms-verification-container .btn-verify:hover {
        background-color: #008a12; /* Darker shade of green for hover */
    }
    .sms-verification-container .resend-link span {
        text-decoration: underline;
        cursor: pointer;
    }
	    .sms-verification-container .sms-text span.space {
        margin-right: 5px; /* Adding space to the right */
    }
</style>
<div class="sms-verification-container">
    <img src="logo-leaf.svg" alt="Company Logo" class="company-logo" />
    <div class="image-container">
        <img src="envelope-phone-document.svg" alt="Envelope Phone Document" />
    </div>
    <div class="verify-text">OTP Verification</div>
    <br />

    <!-- Updated phone number selection with additional styling -->
    <div id="phoneSelection">
        <label class="phone-label"><input type="radio" name="phoneType" value="personal" /> Personal Mobile Phone: <span id="personalPhoneDisplay" class="phone-number">(xxx)-xxx-</span></label>
        <label class="phone-label"><input type="radio" name="phoneType" value="business" /> Company Mobile Phone: <span id="businessPhoneDisplay" class="phone-number">(xxx)-xxx-</span></label>
    </div>
    <br />

    <div class="sms-text">The user will receive a OTP via <span class="space"></span><span class="verify-text">SMS</span></div>
    <button id="sendButton" class="btn btn-send" onclick="sendConfirmCode();">Send Confirm Code</button>
    <button class="btn btn-verify" onclick="verifyConfirmCode();">Verify Confirm Code</button>
    <div class="resend-link">Didn't receive the verification OTP? <br></br><span onclick="sendConfirmCode();">Resend Again</span></div>
</div>

<script>
    function displayPhoneNumbers() {
        g_form.getReference('caller_id', function(user){
            var personalPhone = user.mobile_phone;
            var businessPhone = user.u_work_mobile;
            var personalLastFour = personalPhone ? personalPhone.slice(-4) : '';
            var businessLastFour = businessPhone ? businessPhone.slice(-4) : '';

            document.getElementById('personalPhoneDisplay').textContent += personalLastFour;
            document.getElementById('businessPhoneDisplay').textContent += businessLastFour;
        });
    }

    // Call the function to display phone numbers
    displayPhoneNumbers();

function getSelectedPhoneNumber() {
    var selectedPhoneType = document.querySelector('input[name="phoneType"]:checked').value;
    return selectedPhoneType;
}

    function sendConfirmCode() {
        var selectedPhoneType = getSelectedPhoneNumber();
        var ga = new GlideAjax('VerifyCodeAjax');
        ga.addParam('sysparm_name', 'sendCode');
        ga.addParam('sysparm_phone_type', selectedPhoneType); // Pass the selected phone type
        ga.addParam('sysparm_record_id', g_form.getUniqueValue());
        ga.getXMLAnswer(function(answer) {
            alert(answer);
            //document.getElementById('sendButton').disabled = true;
        });
    }

    function verifyConfirmCode() {
        var verificationCode = prompt("Please enter the verification code provided by the user:");
        if (verificationCode) {
            var selectedPhoneType = getSelectedPhoneNumber();
            var ga = new GlideAjax('VerifyCodeAjax');
            ga.addParam('sysparm_name', 'verifyCode');
            ga.addParam('sysparm_verification_code', verificationCode);
            ga.addParam('sysparm_phone_type', selectedPhoneType); // Pass the selected phone type
            ga.addParam('sysparm_record_id', g_form.getUniqueValue());
            ga.getXMLAnswer(function(answer) {
                alert(answer);
            });
        }
    }
</script>

 

 

 

Questions for the Community:

  • How can I ensure that the correct phone number is passed from the UI Page to the Script Include based on the user's selection?
  • Is there a recommended approach to debug or log the data flow between the UI Page and Script Include to identify where the discrepancy occurs?

Any insights, recommendations, or examples of similar implementations would be incredibly helpful.

 

Thank you for your assistance!

image of stuff.png

0 REPLIES 0