Inline Sales Force NodeJS Lambda

Objective

At Galactic Fog we needed a way to funnel our web sales notifications from our website to our Leads in Sales Force. However, we had no desire to build a stand alone web service and deal with its inherit complexities. Normally, we would write a simple nodejs server, host, maintain and integrate the process into our CI pipeline. The server would always be running, requiring additional resources and monitoring. This is a perfect task for a lambda function!

Requirements

  • Implement App As Serverless Solution
  • Expose publicly for our website
  • Obfuscate any potentially sensitive information from the client
  • Provide some sort of thottling

Pre Requisites

  • You are authenticated and authorized to Gestalt Platform
  • You have already defined a Hierarchy (Org, Workspace, Environment)
  • You have already defined an API in Gestalt Platform
  • You have the appropriate access to your Sales Force Platform

Create an API Creating a New Sales Force Lead

Under the covers we are performing a request like this: POST https://webto.salesforce.com/servlet/servlet.WebToLead

With an application/x-www-form-urlencoded payload:

oid=${sfOID}&lead_source=Website&first_name=${firstName}&last_name=${lastName}&company=${message.company}&email=${message.email}&title=${message.title}&phone=${message.phone}&employees=${message.size}&00N1I00000KJ0Id=${message.message}

Note

Your payload will vary depending on your form fields, but the oid is always required

Define the Lambda

Since this is an Inline Lambda we will need to use the core NodeJS https API so we can make REST request. If you want to roll this is a packaged lambda(which we recommend) checkout Packaged Slack Lambda.

  1. Navigate to your desired Environment and on the Create Menu Click Create Lambda
  2. Select the desired Lambda Provider and Name
  3. Select the a NodeJS Runtime and select Inline Code Type
  4. Specify the **Handler as run
  5. Paste the source code below into the editor. Notice the exports.run where .run is the Handler i.e. the function main we want to invoke when the lambda is called
var exports = module.exports = {};
exports.run = function(event, context, callback) {
  const https = require('https');
  const eventData = event && JSON.parse(event);
  const message = (eventData && eventData.payload) || 'a payload was not provided to the message';

  const sfHost = process.env.SF_API_BASEPATH;
  const sfPath = process.env.SF_PATH;
  const sfOID = process.env.SF_OID;
  const sfOptions = { host: sfHost, path: sfPath };

  // Your query may differ depending on your sales force form fields
  const sfPayload = `oid=${sfOID}&lead_source=Website&first_name=${firstName}&last_name=${lastName}&company=${message.company}&email=${message.email}&title=${message.title}&phone=${message.phone}&employees=${message.size}&00N1I00000KJ0Id=${message.message}`;

  // https request POST method
  const request = (options, payload, contentType = 'application/json') => {
     const postOptions = Object.assign({
      method: 'POST',
      headers: {
        'Content-Type': contentType,    
        'Content-Length': Buffer.byteLength(payload),
      },
      json: true,
     }, options);

    const req = https.request(postOptions, (res) => {
      res.on('data', (chunk) => {
        console.log(`BODY: ${chunk}`);
      });
      res.on('end', () => {
        callback(null, 'SUCCESS');
      });
    });

    req.on('error', (e) => {
      console.error(`problem with request: ${e.message}`);
      callback(e.message, 'ERROR');
    });

    // write data to request body
    req.write(payload);
    req.end();       
  };

  request(sfOptions, sfPayload, 'application/x-www-form-urlencoded');
};

Configure Environment Variables

Environment Variables that are defined on the Lamnda are passed to nodeJS lambdas via process.ENV:

  1. Define three variables in the Environment Variables
  2. SF_API_BASEPATH: webto.salesforce.com
  3. SF_PATH: /servlet/servlet.WebToLead
  4. SF_OID: <youroid>
  5. Click Create

Expose an API Endpoint

Now that we've created ourk Lambda we need to expose an api endoint.

  1. On the same Lambda screen, in the Public Endpoints section click Add Endpoint
  2. Select an API and click Next
  3. Enter a Relative Path e.g /send
  4. Check only the POST Allowed HTTP Method
  5. Check the Rate Limit and enter 60 (the number of requests allowed per minute)
  6. Click Finish
  7. Click or copy the Public URL which you will use to make your REST API call

Using your favority REST client you can post the following message format using the following settings:

  • URL: The public URL that ws generated when you created the endpoint:
  • Headers: Content-Type: application/json
  • Method POST
  • Body:
{
    "payload": {
        "firstName": "Rick",'       
    "lastName": "Sanchez",
        "company": "gfi",
        "phone": "123-123-1234",
        "email": "test@test.com",
        "title": "Mad Scientist",
        "size": "1-2",
        "message": "Morty!",
    }
}

You should see a message in a new Lead in your Sales force Leads!