Update Express app to make API calls to Salesforce
In this section, you will update your Express application to create a new Task on Salesforce when your webhook is triggered from a call.
To update an ExpressJS application:
In your application, add the JSForce library as well as dotenv by using:
npm install jsforce dotenv--saveCreate a new file called
.env, which will have the following:SF_USERNAME='' SF_PASSWORD='' SF_TOKEN=''The
SF_USERNAMEandSF_PASSWORDwill be the username and password used to login into Salesforce. TheSF_TOKENis the token you should have received via email when your security token was generated by Salesforce.Create a new Javascript file, called
Salesforce.jsand add the following:var jsforce = require('jsforce'); var conn = new jsforce.Connection(); function login() { return new Promise((resolve, reject) => { conn.login(process.env.SF_USERNAME, process.env.SF_PASSWORD + process.env.SF_TOKEN, function(err, res) { if (err) {reject(err); return} resolve(res) }) }) } function getContact(phone_number) { return new Promise((resolve, reject) => { var q = `SELECT Id FROM Contact WHERE Phone='${phone_number}'` console.log(q) conn.query(q, function(err, res) { if (err) {reject(err); console.log(err);} resolve(res) }) }) } function createContact(first_name, last_name, phone_number) { return new Promise((resolve, reject) => { //Create new contact, get the record ID console.log(`Create contact ${first_name} ${last_name} ${phone_number}`) var data = { FirstName : first_name, LastName : last_name, Phone:phone_number} if (first_name != null) { data['FirstName'] = first_name } if (last_name != null) { data['LastName'] = last_name } conn.sobject("Contact").create(data, function(err, ret) { if (err || !ret.success) { reject(err); console.error(err, ret); return } console.log("Created new contact id : " + ret.id); resolve(ret) }); }) } function addTask(subject, call_dur, recordId) { return new Promise((resolve, reject) => { conn.sobject("Task").create({ TaskSubtype : 'Call', CallDurationInSeconds : call_dur, Subject:subject, WhoId:recordId}, function(err, ret) { if (err || !ret.success) { reject(err); console.error(err, ret); return } console.log("Created new task id : " + ret.id); resolve(ret) }); }) } module.exports.login = login module.exports.getContact = getContact module.exports.createContact = createContact module.exports.addTask = addTaskUpdate the code in
app.jsto import this new file:var salesforce = require('./Salesforce.js')When the app loads, write the code to login using your Salesforce credentials.
salesforce.login() .then(function(res) { console.log(res) }).catch((function(err) { console.log(err) }))Update the code in the
app.post('/webhook) section of your application to use the newSalesforce.jsfile.require('dotenv').config() const express = require('express') const app = express() const port = 3000 app.post('/webhook', (req, res) => { var event = req.body.event var callerId = event.callerId; var first_name = null var last_name = null var phone_number = event.phoneNumber.replace(/\D/g,'') if (typeof(callerId) != "undefined") { [last_name, first_name] = callerId.split(" ") } else { last_name = phone_number } var direction = event.direction var duration = event.duration var state = event.state if (state == "ANSWERED") { var name = `${first_name} ${last_name}` if (typeof(callerId) == "undefined") { name = phone_number } var subject = `${direction.toLowerCase()} call with ${name}` salesforce.getContact(phone_number) .then(function(contact) { console.log(contact) if (contact["totalSize"] == 0) { //Create new contact return salesforce.createContact(first_name, last_name, phone_number) .then(function(contact) { var contactId = contact["Id"] return salesforce.addTask(subject, duration, contactId) }) } else { //Grab the first contact var contactId = contact["records"][0]["Id"] return salesforce.addTask(subject, duration, contactId) } }).catch(function(err) { console.log(err) }) } res.sendStatus(200); }); app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))This code will be triggered when a call is made or received from your VBC number, When the call is completed(
if (state == "ANSWERED")), the application will first look for a Contact with the given phone number(event.phoneNumber).This will call the
salesforce.getContact()function to search for the Contact. If the Contact exists, we create a new Task using the functionsalesforce.addTask(). This will create a new Task in Salesforce that includes the title, the associated Contact(using thecontactId) and the duration of the call.If there are no Contacts that match the given phone number, using the
contact["totalSize"] == 0check, the application will then create a new Contact using theevent.callerIdproperty from the webhook, and split the string into a first name and last name. Note, outgoing calls MAY not have this property. In this case, we will use the phone number as the Contact's last name.To start your application, run the following command:
node app.js
Your application will now create a new Task in Salesforce when a completed call is made or received.
Note: Make sure the port you have specified (300) is the same port you use when creating your ngrok URL.
Log incoming calls to Salesforce
Logging incoming calls into Salesforce