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.
nvm install v18# Check the installed node versionnode -v# Set the version v18 as defaultnvm 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:
"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:
export GITHUB_TOKEN=<your PAT generated through the GitHub console>echo '@arcxp:registry=https://npm.pkg.github.com/' >> ~/.npmrcecho '//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}' >> ~/.npmrc
Use npm Command
To use npm login command:
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:
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: developmentLocal 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:
-
Navigate to the integration directory
cd ifx-example-webhooks
-
npm install
to install dependencies -
Create a new file called
editionFinalizeHandler.js
insidesrc/eventHandlers/
-
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"]} -
Define and export the router’s name:
src/eventsHandlers.js const editionFinalizeHandler = require('./eventsHandlers/editionFinalizeHandler');module.exports = {editionFinalizeHandler,} -
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; -
Start local server
npm run localTestingServer
-
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:
- Create “test” event handlers for each event you are researching
- Map those events to the handler
- Ensure useful logging is in place i.e.
console.log(event)
- Bundle, deploy and promote the integration to Sandbox
- Trigger the event by performing an action, such as updating an author or a story
- 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)