npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@andrewcturing/salesforce-webhooks

v1.1.14

Published

Provides an interface to create webhooks in Salesforce for different SObject events

Downloads

11

Readme

Salesforce Webhooks

jverce npm

Introduction

The purpose of this package is to provide a convenient interface to the Salesforce API in order to create or delete webhooks in the Salesforce platform. It offers a simple interface to create basic webhooks for "created", "updated" or "deleted" events on any SObject type (although such types must be triggerable, as specified by an SObject's metadata)

Please note that this is a Node.js package and hasn't been tested in a browser-like environment.

Getting Started

Installation

Nothing special here: just a regular NPM/Yarn Node.js package.

NPM

npm install --save salesforce-webhooks

Yarn

yarn add salesforce-webhooks

Usage

This package can be used to either create or delete a webhook from Salesforce. It just serves as an interface and convenience tool to do all the required wiring, customization and interaction with Salesforce under the hood. It does not however keep track of created webhooks, it's purpose is not to manage those webhooks beyond creation or deletion of its low-level components.

Instantiation

The interface is exposed through the SalesforceClient class. To start, create a new instance of this class by providing the following information about your Salesforce organization:

  • Salesforce auth token: a valid REST API token with write access to the Salesforce SOAP API (see for example the Salesforce REST API Developer Guide)
  • Instance: the instance identifier where the target organization is running. See this page for more information.
  • API Version: this is an optional parameter. It is set to 50.0 by default, and this is the target version for which this package was developed.

The above parameter names are authToken, instance and apiVersion, respectively. So, to create a new instance of SalesforceClient execute the following code:

const { SalesforceClient } = require("salesforce-webhooks");
const authToken = "a secret API token"; // This is supposed to be secret!
const instance = "na139"; // This is just an example instance.
const client = new SalesforceClient({
  authToken,
  instance,
  apiVersion: "50.0",
});
console.log(client);
// SalesforceClient {
//  authToken: 'a secret token',
//  metadataApiUrl: 'https://na139.salesforce.com/services/Soap/m/50.0',
//  soapApiUrl: 'https://na139.salesforce.com/services/Soap/s/50.0'
//}

Note that the *ApiUrl properties contain information about the instance and the API version.

The client parameters can also be extracted from environment variables if they are not provided to the constructor:

export SALESFORCE_API_VERSION='50.0'
export SALESFORCE_AUTH_TOKEN='a secret API token'
export SALESFORCE_INSTANCE='na139'

The constructor will resort to the environment variables above if no valid arguments were provided to it:

const { SalesforceClient } = require("salesforce-webhooks");
const client = new SalesforceClient();
console.log(client);
// SalesforceClient {
//  authToken: 'a secret token',
//  metadataApiUrl: 'https://na139.salesforce.com/services/Soap/m/50.0',
//  soapApiUrl: 'https://na139.salesforce.com/services/Soap/s/50.0'
//}

Webhook Creation

Every webhook creation interface requires users to provide at least the following arguments:

  • endpointUrl: the URL of the endpoint that the webhook should call whenever it gets triggered
  • sObjectType: the type of SObject that this webhook will react to

The following interfaces serve the purpose of creating webhooks:

  • createWebhookNew: creates a webhook that gets triggers when a new object is created
  • createWebhookUpdated: creates a webhook that gets triggers when an object is updated
  • createWebhookDeleted: creates a webhook that gets triggers when an object is deleted
  • createWebhook: it takes an additional argument event whose values can be either new, updated or deleted, and it creates a webhook that gets triggers when an event of type event happens to an object

An optional parameter called secretToken can be provided in order to verify the authenticity of the HTTP calls at the target endpoint. Whenever the endpoint receives an HTTP call, it can verify that the X-Webhook-Token header matches the secret token provided through the secretToken argument.

To create a webhook that will make an HTTP POST call to http://example.com whenever a new account is created, run the following code:

const client = new SalesforceClient(...);   // See the Instantiation section above.
const webhookOpts = {
    endpointUrl: 'http://example.com',
    sObjectType: 'Account',
    secretToken: 'some secret arbitrary string',
};
const webhookData = await client.createWebhookNew(webhookOpts);
console.log(webhookData);
// {
//   remoteSiteName: 'SW_Endpoint_9c680f2bb526a0fbdc34a2aef7e5',
//   classNames: [
//     'SW_SObjectFactory_3452ca73469dc9c2094f01',
//     'SW_Callout_ae23bd24aa8c2abbc0c78db11e7f',
//     'SW_CalloutMock_6a18a2dfa993157c6574bd7c',
//     'SW_Test_85d9edee3617e831a7fbfe43cb30e084'
//   ],
//   triggerNames: [ 'SW_Trigger_b868fb7dbbcdea44930014e7a585' ]
// }

If you don't know the type of event at compile time, you can use the more flexible interface createWebhook which allows you to specify the type of event at runtime. The output of the following code is equivalent to the one in the code above:

const client = new SalesforceClient(...);   // See the Instantiation section above.
const webhookOpts = {
    endpointUrl: 'http://example.com',
    sObjectType: 'Account',
    secretToken: 'some secret arbitrary string',
    event: 'new'
};
const webhookData = await client.createWebhook(webhookOpts);
console.log(webhookData);
// {
//   remoteSiteName: 'SW_Endpoint_9c680f2bb526a0fbdc34a2aef7e5',
//   classNames: [
//     'SW_SObjectFactory_3452ca73469dc9c2094f01',
//     'SW_Callout_ae23bd24aa8c2abbc0c78db11e7f',
//     'SW_CalloutMock_6a18a2dfa993157c6574bd7c',
//     'SW_Test_85d9edee3617e831a7fbfe43cb30e084'
//   ],
//   triggerNames: [ 'SW_Trigger_b868fb7dbbcdea44930014e7a585' ]
// }

The information returned by these methods is required whenever you wish to delete the resources created by them.

Webhook Deletion

As mentioned in the previous section, after creating a webhook the call returns useful data that can be used to delete all the resources created before.

So after creating a webhook, we can do this to delete it:

await client.deleteWebhook(webhookData);

Additional Context

The concept of webhooks in Salesforce is a bit blurry: they do not exist explicitly, but the platform provides enough building blocks for developers to implement them.

Apex

This section briefly describes the Lightning Platform aspects that this package leverages to implement webhooks in Salesforce. In a nutshell:

  • Salesforce has a runtime environment within the platform (called Lightning Platform) in which developers can compile, test, deploy and execute arbitrary code. This code is written in a special programming language called Apex
  • Apex is a strongly-typed object-oriented programming language whose main building blocks are classes and triggers:
    • Classes share the similar semantics as any other object-oriented programming language in the sense that they offer inheritance, encapsulation and polymorphism.
    • Triggers are a particular kind of program that reacts (or gets triggered) by a predetermined set of events (e.g. whenever a new account is created, or when some contact information is updated). They can describe arbitrary logic, however it is usually encouraged to keep such logic as simple/thin as possible (think controllers in the MVC model).
  • Apex code can be operated under the usual development cycle where code is developed locally, compile and tested in the environment, and deployed. Depending on the type of environment in which the developer works, there are certain requirements that the code must meet in order to make it to production:
    • For production organizations, tests are mandatory and they must succeed in order for the code to be deployed. Also, overall test coverage cannot drop below 75%, so if the new code causes the overall test coverage to go below that threshold it won't get deployed.
    • For developer or sandbox organizations, code just needs to compile.
  • In order for code to make HTTP calls to 3rd party URL's (i.e. the usual webhook case), the organization must be explicitly configured to "whitelist" such URL's. This is called Remote Site Setting.

Approach

Under the hood, this package performs the following actions when creating a webhook:

  1. Creates a Remote Site Setting for the provided endpoint URL. This will allow the Apex code to make HTTP calls to such endpoint.
  2. Deploys some supporting Apex classes that do not depend on the input parameters (e.g. mocking class, factory class, the HTTP callout, etc.)
  3. Based on the event type and SObject type parameters, a customized trigger is deployed that will get called whenever such an event happens to the specified SObject type. This trigger will get executed and will make an HTTP call to the provided endpoint URL. Please note that for a single event on an SObject instance, multiple triggers can be executed, depending on the currently deployed Apex triggers. If you creat multiple webhooks with the same parameters, their endpoint will receive as many HTTP calls as the number of equivalent webhooks.

Upon successful creation of a webhook, the package returns an object with information relative to all the entities created above. This information must be stored for future use whenever users which to clean-up those resources. The package itself does not keep track of those resources after the call to createWebhook* completes.

For deletion, the same steps described above is performed in reverse order, except that instead of creating those resources, they are removed.