Challenges with Passing caller_id Phone Number from UI Page to Script Include for OTP Verification
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-08-2024 01:54 PM
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:
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.
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-11-2024 11:56 PM
HI @naborowiak ,
- 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?
You can log the number after its received by script include before process it into Twilio. The format/type of the field can sometime change the numbers to comma seprated, int, etc...
- 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?
Logging data using gs.log gs.info etc. will help you to verify the data formats...
Alternatively, before passing the phonenumber to script include you can ensure to have certain check to see if the data is not empty or if the data has the right format etc +31 12345 +1 5345345 etc...
I hope this helps...
☑️ Please mark responses as HELPFUL or ACCEPT SOLUTION to assist future users in finding the right solution....