2.3.1 • Published 5 years ago

node-salesforce-connection v2.3.1

Weekly downloads
361
License
MIT
Repository
github
Last release
5 years ago

node-salesforce-connection

Build Status

node-salesforce-connection is a minimal library for connecting to Salesforce from Node.js. It provides an absolute minimal wrapper that allows you to call any Salesforce API. It tries hard to not get in the way between you and Salesforce. It has no dependencies.

  1. Introduction
  2. Logging in
  3. REST
  4. SOAP
  5. Error handling

This library works in Node.js. There is an almost identical library that works in browsers, but that it not yet published as a stand-alone package.

Introduction

This documentation explains how the node-salesforce-connection library works, but you need to read this in combination with the official Salesforce API documentation, since this document does not explain how the Salesforce APIs themselves work.

Create your own project using npm init and then add this library as a dependency using npm install node-salesforce-connection --save.

Use it like this in your JS file:

let SalesforceConnection = require("node-salesforce-connection");

(async () => {

  let sfConn = new SalesforceConnection();

  await sfConn.soapLogin({
    hostname: "login.salesforce.com",
    apiVersion: "39.0",
    username: "example@example.com",
    password: "MyPasswordMySecurityToken",
  });

  let recentAccounts = await sfConn.rest("/services/data/v39.0/query/?q="
    + encodeURIComponent("select Id, Name from Account where CreatedDate = LAST_WEEK"));

  for (let account of recentAccounts.records) {
    console.log("Account " + account.Name + " was created recently.");
  }

})().catch(ex => console.error(ex.stack));

The examples use the JavaScript await keyword. This assumes the examples are placed in an async function like the one above. You don't have to use async functions, if you prefer using the traditional promise.then(handler) syntax.

Logging in

The first thing you need to do is log in to Salesforce.

Logging in using the SOAP API

You can use the soapLogin function to log in using a username and password:

let sfConn = new SalesforceConnection();

await sfConn.soapLogin({
  hostname: "login.salesforce.com",
  apiVersion: "39.0",
  username: "example@example.com",
  password: "MyPasswordMySecurityToken",
});

The function calls the SOAP login method.

The function returns a promise that behaves identically to the promise returned from the soap function. When the promise resolves successfully, sfConn will be ready to use.

Logging in using OAuth

You can log in using OAuth. Here is an example of the Username-Password OAuth Authentication Flow:

let sfConn = new SalesforceConnection();
let tokenRequest = {
  grant_type: "password",
  client_id: "MyConsumerKey",
  client_secret: "MyConsumerSecret",
  username: "example@example.com",
  password: "MyPasswordMySecurityToken",
};
let hostname = "login.salesforce.com";
await sfConn.oauthToken(hostname, tokenRequest);

The function makes a POST request to /services/oauth2/token.

The function returns a promise that behaves identically to the promise returned from the rest function. When the promise resolves successfully, sfConn will be ready to use.

Use the oauthToken function with the Web Server, Username-Password and Refresh Token OAuth authentication flows. Use the manual approach described below for the User-Agent flow.

Logging in manually

If SOAP or OAuth login does not work for you, you can manually initialize the connection with your own questionably obtained session information:

let sfConn = new SalesforceConnection();
sfConn.instanceHostname = "na1.salesforce.com";
sfConn.sessionId = ".....";

REST

The best way to make API calls is using any Salesforce REST API. Use for example the Bulk, Chatter, REST, Tooling or Reports and Dashboards API.

Example using query:

let recentAccounts = await sfConn.rest("/services/data/v39.0/query/?q="
  + encodeURIComponent("select Id, Name from Account where CreatedDate = LAST_WEEK"));

for (let account of recentAccounts.records) {
  console.log("Account " + account.Name + " was created recently.");
}

Example creating a record:

let myNewAccount = {Name: "test"};

let result = await sfConn.rest("/services/data/v39.0/sobjects/Account",
  {method: "POST", body: myNewAccount});

console.log("Created Account with ID " + result.id
  + (result.success ? " successfully." : " failed."));

The rest function accepts the following parameters:

sfConn.rest(path, {method, api, body, bodyType, headers, responseType});

The rest function returns a promise.

If the request succeeds, the promise will resolve with the HTTP response parsed according to the responseType parameter.

If the request fails because Salesforce returned an error response (such as HTTP 400), the promise will reject with an Error with these properties:

If the request fails because Node.js could not connect to Salesforce, the promise will reject with a Node.js System Error.

A SalesforceResponse object has these properties:

SOAP

If the functionality you are looking for is not available via any of the Salesforce REST APIs, you might be able to find a Salesforce SOAP API that does what you need. However, this being JavaScript, you should probably avoid SOAP when possible.

Example using upsert:

let enterpriseWsdl = sfConn.wsdl("39.0", "Enterprise");

let contacts = [
  {$type: "Contact", FirstName: "John", LastName: "Smith", Email: "john.smith@example.com"},
  {$type: "Contact", FirstName: "Jane", LastName: "Smith", Email: "jane.smith@example.com"},
];

let upsertResults = await sfConn.soap(enterpriseWsdl, "upsert",
  {externalIdFieldName: "Email", sObjects: contacts});

for (let r of sfConn.asArray(upsertResults)) {
  console.log((r.created == "true" ? "Created" : "Updated")
    + " Contact with ID " + r.id + " "
    + (r.success == "true" ? "successfully" : "failed") + ".");
}

Before you make a SOAP API request, you need a WSDL, which you get using the wsdl function. Well, you don't actually get the full WSDL file. You only get the absolute minimum information needed to make SOAP API calls from JavaScript.

The wsdl function accepts the following parameters:

sfConn.wsdl(apiVersion, apiName);

The wsdl function returns an object containing information from the WSDL that is needed to make SOAP requests.

Alternatively, you can call the wsdl function with only one parameter to get an object with all the WSDL's we know:

let wsdlSet = sfConn.wsdl(apiVersion);
let myWsdl = wsdlSet[apiName];

With the WSDL information at hand, you can make your SOAP API request using the soap function.

The soap function accepts the following parameters:

sfConn.soap(wsdl, method, args, {headers});

sObjects are a bit special in the SOAP API. You always need to specify the type of an sObject. In the Partner WSDL, use the type property (Example: {type: "Account", Name: "Example"}). In the Enterprise WSDL and others, use the $type property (Example: {$type: "Account", Name: "Example"}).

The soap function returns a promise.

If the request succeeds, the promise will resolve with the SOAP method's return value.

When you get the return value from a SOAP API call, you won't get the precise type of the returned data, since that information is only available in the WSDL. You have to convert the type yourself using these rules:

  • If you expect a string, you will get a string.
  • If you expect a number, you will get a string. Convert it to a number using for example let myNumber = Number(myValue).
  • If you expect a boolean, you will get a string. Convert it to a boolean using for example let myBoolean = myValue == "true".
  • If you expect null, you will get null.
  • If you expect an object, you will get an object.
  • If you expect an array, you will get different things if your array has zero, one or more elements. Convert it to an array using the asArray utility function, for example let myArray = sfConn.asArray(mvValue);.

If the request fails because Salesforce returned a SOAP fault, the promise will reject with an Error with these properties:

If the request fails because Node.js could not connect to Salesforce, the promise will reject with a Node.js System Error.

Error handling

The rest and soap functions return promises you can use in error handling like any other promise.

Example:

try {
  let result = await sfConn.rest("/services/data/v39.0/query/?q="
    + encodeURIComponent("select Id from UnknownObject"));
  console.log(result);
} catch (ex) {
  if (ex.name == "SalesforceRestError") {
    console.log("Salesforce returned an error: " + ex.message);
  } else if (ex.syscall == "getaddrinfo") {
    console.log("Could not make request. Are you offline?");
  } else {
    throw ex; // Unknown type of error
  }
}

Same example with an older JavaScript syntax:

sfConn.rest("/services/data/v39.0/query/?q="
  + encodeURIComponent("select Id from UnknownObject"))
.then(function(result) {
  console.log(result);
}, function(ex) {
  if (ex.name == "SalesforceRestError") {
    console.log("Salesforce returned an error: " + ex.message);
  } else if (ex.syscall == "getaddrinfo") {
    console.log("Could not make request. Are you offline?");
  } else {
    throw ex; // Unknown type of error
  }
});

History

Before I made this library, I used JSForce. It is a nice library, but I ran into a few bugs, and I needed a specific new Salesforce APIs that was not yet added to JSForce at the time. So I made this library instead, which aims to give you access to any current or future Salesforce API without needing to update the library. It aims to provide 95% of the convenience for 5% of the size/complexity.

2.3.1

5 years ago

2.3.0

7 years ago

2.2.2

7 years ago

2.2.1

7 years ago

2.2.0

7 years ago

2.1.0

7 years ago

2.0.0

7 years ago

1.0.0

7 years ago