Skip to content
Product Documentation

Locally Simulate HTTP Requests

Background

This guide will get you familiar with writing code in an integration and invoking that code on your local machine. It assumes you have already created an integration and set the runtime as node.

Asynchronous events originating from the Event Registry cannot be sent from other environments to local workstations. Developers can simulate an event trigger locally by invoking an HTTP endpoint that IFX exposes.

Once you have the hang of it, you can invoke integrations and write your custom logic! Some example use cases might be:

  • Publish new stories to a syndication partner, such as Facebook

  • Inform an external service of a story update or a story deletion

  • Enrich stories with custom data, such as adding automatic tags to a story that are provided by an external service

Prerequisites

In order to build and run your Node.js integrations, Node.js version v18.x is recommended. Using Node.js Version Manager (nvm) install a specific Node.js version.

Customer integrations are run in an execution environment with Node.js version 18.X.

Terminal window
nvm install v18
# Check the installed node version
node -v
# Set the version v18 as default
nvm alias default v18

IFX integration development is done locally, and then deployed and promoted to sandbox and production later. Your integration should be fully tested before deploying to ensure no user workflows are broken.

When starting local servers on your machine, make sure that you aren’t running any services which could proxy internet traffic to that port. Reverse proxies which do such things will likely pose a security risk.

Download Starter Bundle

When you create a new integration, you are given a starter bundle. You can download it locally and begin coding. For more information, see Download a Bundle. As a reminder, you are responsible for your own source control.

Install Node.js SDK Dependency

Ensure package.json has the latest Node.js SDK. Below is only an example:

package.json
"dependencies": {
"@arcxp/arcxp-ifx-node-sdk": "1.3.2"
}

Create a GitHub PAT

Create a personal access token with read:package scope in your GitHub account. Please follow the instructions from here.

Install SDK

Once a PAT is created, there are two ways to install/download the Node.js SDK. The first option is to create your local .npmrc file manually. Another option is to use npm login command.

Create .npmrc Manually

This method seems to be the simplest. To create your local .npmrc file, first make sure you have a GitHub PAT ready.

Next, run each of the following commands:

Terminal window
export GITHUB_TOKEN=<your PAT generated through the GitHub console>
echo '@arcxp:registry=https://npm.pkg.github.com/' >> ~/.npmrc
echo '//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}' >> ~/.npmrc

Use npm Command

To use npm login command:

Terminal window
npm login --scope=@arcxp --auth-type=legacy --registry=https://npm.pkg.github.com
# --- Username: your GitHub username
# --- Password: your PAT generated through the GitHub console https://github.com/settings/tokens
# --- Email: your GitHub email

Then you should be able to run npm install from the root dir

If all succeeded, then you can run npm run localTestingServer.

Run a Local Server

To spin up a local server where local code can be tested, issue the command npm run localTestingServer

When the server has started successfully, it will look like this:

Terminal window
gigib@my-C02146 my-ifx-integration % npm run localTestingServer
> @myorg/myorg-my-ifx-integration@1.0.0 localTestingServer
> node node_modules/@arcxp/arcxp-ifx-node-sdk/localTestingServer
Loading environment configuration for env: development
Local Express Server Started at http://127.0.0.1:8080/ifx/local/invoke

http://127.0.0.1:8080/ifx/local/invoke can now be used to POST event messages to and invoke integrations locally.

Invoking an Integration Locally

Once you have the local server running, you can POST event messages to invoke integrations locally. But first you need to have the correct payload to properly test your code. There is a few ways to acheive this.

Event Payload Model

All events will have the same fundemental structure:

{
"organizationId": "string",
"key": "string",
"typeId": "int",
"uuid": "string",
"currentUserId": "string",
"version": "int",
"invocationId": "string",
"body": {"PAYLOAD BODY HERE"}
}

The body serves as the designated area for event data, and its structure can be customized to meet any specific requirements by the event originating application.

For example, the websked:edition_finalize event will send the following event message:

{
"organizationId": "myorgname",
"key": "websked:edition_finalize",
"typeId": 1,
"uuid": "",
"currentUserId": "",
"version": 2,
"invocationId": "ABCD-123534R4-DAFSDFA-8363",
"body": {
"type": "edition_finalize",
"orgId": "string",
"publication": {
"name": "string",
"publicationId": "string",
"editionId": "string",
"editionTime": "number",
"editionUrl": "string",
"storyIds": [
"string"
],
"sectionId": "string",
"website": "string",
"publicationSetId?": "string"
}
}
}

Test it Out

Let’s take a very simple (made up) event message so we can see it working:

  1. Navigate to the integration directory cd ifx-example-webhooks

  2. npm install to install dependencies

  3. Create a new file called editionFinalizeHandler.js inside src/eventHandlers/

  4. Add a router for websked:edition_finalize so that when the event comes in, it knows which handler to invoke:

    src/eventsRouter.json
    {
    "editionFinalizeHandler": ["websked:edition_finalize"]
    }
  5. Define and export the router’s name:

    src/eventsHandlers.js
    const editionFinalizeHandler = require('./eventsHandlers/editionFinalizeHandler');
    module.exports = {
    editionFinalizeHandler,
    }
  6. Add handler code:

    src/eventHandlers/editionFinalizeHandler.js
    const editionFinalizeHandler = async (event) => {
    console.log(event.body.my_data);
    return "this handler is doing stuff!";
    }
    module.exports = editionFinalizeHandler;
  7. Start local server npm run localTestingServer

  8. Use Postman (or cURL) to POST a payload to the local server POST http://127.0.0.1:8080/ifx/local/invoke/ and include the JSON below as the POST body:

    {
    "organizationId": "stagingmultisitelarge",
    "key": "websked:edition_finalize",
    "typeId": 1,
    "uuid": "",
    "currentUserId": "",
    "version": 2,
    "invocationId": "b2ed9ee7-90ce-4e72-bf72-10bfb0e4186d",
    "body": {
    "my_data": "Hello!!!!!"
    }
    }

    In the Postman console we can see the return message from our handler code:

    and back in our code editor, the result of console.log(event.body.my_data):

How to Get a Payload Model

Each application that send events to IFX defines its own payload inside of the event.body, such as Composer's Send to Print event.

You can get the payload model of events you are trying to simulate from the Event Menu. In cases where the payload is not provided:

  1. Create “test” event handlers for each event you are researching
  2. Map those events to the handler
  3. Ensure useful logging is in place i.e. console.log(event)
  4. Bundle, deploy and promote the integration to Sandbox
  5. Trigger the event by performing an action, such as updating an author or a story
  6. Query the logs to view the payload

Save the payload. Locally you can use it to change small pieces of data, such as the headline, to create new scenarios.

Stopping a Running Integration

In Terminal, use the hotkey Ctrl + C to stop the process. Once you do this you will need to issue the run command again. If you make code changes be sure to re-build and run the integration again.

Troubleshooting

Make sure package.json includes @arcxp/arcxp-ifx-node-sdk in the dependencies:

You can find the latest version of the SDK here

"dependencies": {
"@arcxp/arcxp-ifx-node-sdk": "{LatestVersion}"
}

If npm install gives errors like the below, check for the availability of the @arcxp/arcxp-ifx-node-sdk version mentioned in the package.json file.

If you get an error like typeError: Object.hasOwn is not a function, check the installed Node.js version (compatible Node.js version is v18.x.x)