# How-to listen Web Socket events and Implement IFX email service provider

Source: https://dev.arcxp.com/subscriptions/identity/build/ifx-email-service-provider-integration-and-websocket-events/

Keeping Arc XP Subscriptions data in sync with your other systems, including your email newsletter system, is vitally important. Arc XP Subscriptions streams all relevant events via WebSocket, allowing for easy integration.

> **Note:**
> 
> Before starting, ensure you meet the **prerequisites** defined for [Manage User Accounts: Developer Interface](https://dev.arcxp.com/subscriptions/identity/learn/manage-user-accounts-developer-interface/#prerequisites).

## How to listen to WebSocket events

You can listen to Arc events by opening a WebSocket connection to

- `wss://{base_URL}/retail/api/v1/event/stream/{index}`

When generating a Developer Token, general use cURL also contains the `base_URL` that you can use to create a WebSocket connection.

`index` is the starting point of the stream of messages in Unix time. You can stream all existing messages by passing in 0 as the index. Default TTL for messages is 14 days. Ideally, you can keep track of the index of your last processed event and any future connections can be opened with that index as the starting point so that you don’t replay messages that you have already handled.

> **Note:**
> 
> **Disconnect events (code 1006)**  
> The WebSocket system is designed to fail over to a new instance during maintenance and scheduled down times. Clients will be disconnected at this time, although no data will be lost. Customers should ensure their connection clients are designed to reconnect automatically when this happens.

### Event Message Structure

All messages have the same structure, and all events are documented in the JSON format:

```json
{
  // Identifies the position of the stream, a sequential id of the message
  "index": "1556553823611",
  // The key that client code can use to handle different actions per message based on its type
  "type": "EVENT_TYPE",
  // Containing its own JSON or text structure
  // changes based on the value of the "type" field
  "message": {
    "identifier": "mail@wapo.com",
    "uuid": "753750ac-7c84-40a3-8178-8bf5cbd66653",
    "email": "mail@wapo.com"
  },
  // Provides the Epoch time when the event occurred
  "eventTime": 1556553823611
}
```

Sample message payload

```json
{
  "index":"1551207953693",
  "type":"MY_TYPE",
  "message": {
    "test":"demo message 1551207953693"
  },
  "eventTime":1551207953693
}
```

### Ways to connect to the stream

**API Browser**

Create a WebSocket request in the API browser of your choice e.g. Postman, Insomnia.

Terminal window

```bash
  wss://{base_URL}/retail/api/v1/event/stream/{index}
  Headers: {
    Authorization: {ARC_ACCESS_TOKEN}
    Arc-Site: {siteID}
  }
```

> **Note:**
> 
> We don’t recomment using Postman for listening Web socket events. When Postman detects no more events, the connection is closed.

**Node**

1. Install Node <https://nodejs.org/en/>
2. Install a Node.js [WebSocket library](https://www.npmjs.com/package/ws), run `npm install ws`
3. cd to your working directory
4. Run `npm init`
5. Create file named `app.js` with the below javascript. Replace `domain` with your domain.
6. Run `node app.js`

```js
var WebSocket = require('ws')
var options = {
    headers: {
        "Arc-Site": "siteID",
        "Authorization": "Bearer {ARC_ACCESS_TOKEN}"
    }
};
const connection = new WebSocket('wss://{base_URL}/retail/api/v1/event/stream/{index}', options)
connection.onopen = () => {
    setInterval(function () {
        connection.send('ping');
    }, 5000);
    console.log('Connection Established');
}
connection.onerror = error => {
    console.log(`WebSocket error: ${error.message}`)
}
connection.onmessage = e => {
    var obj = JSON.parse(e.data);
    if(obj.type !== 'PONG'){
        console.log(obj)
    }
}
```

## SendGrid Email Service Provider Connector using IFX

Many of our clients use email service provider (ESP) to effectively manage and execute email marketing campaigns, resulting in improved deliverability, engagement, and ultimately business growth. However, it may be a bit cumbersome for clients currently to manually connect Arc Subscriptions WebSocket events to their ESP. Today we will be showing how to create integration between Subscriptions and SendGrid using IFX Node.js implementations. This will allow clients to send transactional emails triggered by the Subscription events. Many of our clients may already have an ESP of choice for marketing purposes and this integration can be also extended to easily send emails with the existing ESP. 

Arc XP’s Subscriptions make setting up your email service provider (ESP) quick and painless with our extendable Connector. The Connector utilized IFX to create an integration between Subscriptions WebSocket events and SendGrid. Want to continue using your preferred ESP? Just extend this Connector using this guide. You will be up and running quickly and then can move on to tailoring your marketing and transactional emails for your business.

> **Note:**
> 
> Please refer to [IFX API documentation](https://dev.arcxp.com/api/integrations/integrations-production/) for any issues with API calls. Other useful links:
> 
> - [Welcome to the IFX 2.0 world!](https://docs.arcxp.com/alc/en/welcome-to-the-ifx-2-0-world?id=kb%5Farticle%5Fview&sys%5Fkb%5Fid=ef9f1e31878dc210637f315d0ebb3544&spa=1)
> - [Create and Manage Integrations](https://dev.arcxp.com/integrations/manage-integrations/create-and-manage-integrations)
> - [Bundle deployment workflow!](https://dev.arcxp.com/integrations/bundle-management/bundle-deployment-workflow/)

### How to configure IFX ESP integration

1. Create IFX integration  
Create IFX integration by calling `/admin/integration`. ![ifx-email-servic-provider-integration-and-websocket-events-1](https://dev.arcxp.com/images/subscriptions/identity/build/ifx-email-servic-provider-integration-and-websocket-events/ifx-email-servic-provider-integration-and-websocket-events-1.png)If you are having trouble, please read through detailed guidelines in the [IFX documentation](https://dev.arcxp.com/integrations/manage-integrations/create-and-manage-integrations).
2. Download a zip file of the bundled code  
Call `/admin/bundles/{integrationName}/download/{bundleName}` to download template bundle. ![ifx-email-servic-provider-integration-and-websocket-events-2](https://dev.arcxp.com/images/subscriptions/identity/build/ifx-email-servic-provider-integration-and-websocket-events/ifx-email-servic-provider-integration-and-websocket-events-2.png)
3. Subscribe to the desired events using IFX subscriptions API  
Below is an example API call enabling `commerce:VERIFY_EMAIL` event in `subssinglesite` sandbox environment. Make sure that the event name is in all capital letters. ![ifx-email-servic-provider-integration-and-websocket-events-3](https://dev.arcxp.com/images/subscriptions/identity/build/ifx-email-servic-provider-integration-and-websocket-events/ifx-email-servic-provider-integration-and-websocket-events-3.png)This should be done for each event that you’d like your integration to listen to.
4. Modify the template code  
_**Disclaimer:** Recipes are reference implementations intended to help developers get started more quickly, but are not guaranteed to cover all scenarios nor are they supported by Arc XP. They are are provided “as is” and Arc XP is not responsible for it after you begin using it. Recipes may be updated to incorporate best practices or new solutions at the sole discretion of Arc XP._

  - Download and unzip [subssinglesite-esp-subssinglesite-1-0-0 2.zip](https://github.com/arcxp/arcxp-subscriptions%5Fsendgrid%5Fexample) and copy the code in the src to the newly created repository. If you do not have access to this, please submit an ACS request.
  - Follow the `readme` on the template code to install NPM packages and run the local testing server
  - `@sendgrid/mail` would need to be installed on top of what’s already on the template code
  - More details on running the app locally can be found [here](https://dev.arcxp.com/integrations/how-to-guides/getting-integrations-running-locallynodejs-write-build-run)
  - For secrets and sensitive information such as the SendGrid API key, you should store these values by following [this guide](https://dev.arcxp.com/integrations//secrets/create-a-secure-secret-and-use-within-your-integration/)
  - For non-sensitive information, such as `CDN_ENDPOINT`, `EMAIL_SENDER`, and `WEB_SITE_URL`, these can be stored in the respective environments (`.env.development`, `.env.sandbox`, and `.env.production`)
  - You will need to update `templateId` used in each email handler with the values from dynamic templates from your SendGrid account as well as variables in the .env files  
  ![ifx-email-servic-provider-integration-and-websocket-events-4](https://dev.arcxp.com/images/subscriptions/identity/build/ifx-email-servic-provider-integration-and-websocket-events/ifx-email-servic-provider-integration-and-websocket-events-4.png)  
`eventsRouter.json` determines which event gets routed to a specific handler. For example, when `commerce:VERIFY_EMAIL` event is triggered, logic inside the `verifyEmailHandler` will be executed. ![ifx-email-servic-provider-integration-and-websocket-events-5](https://dev.arcxp.com/images/subscriptions/identity/build/ifx-email-servic-provider-integration-and-websocket-events/ifx-email-servic-provider-integration-and-websocket-events-5.png)The events emitted by Arc Subscriptions include predefined data on these events but if you want some custom data, you can call developer API from the event handler to get the data and use those in the dynamic email template. For example, if the `firstName` was not provided, a developer can call a developer API with [PAT](https://dev.arcxp.com/api/accessing-arcxp-apis/) and use the result to populate the dynamic template. ![ifx-email-servic-provider-integration-and-websocket-events-6](https://dev.arcxp.com/images/subscriptions/identity/build/ifx-email-servic-provider-integration-and-websocket-events/ifx-email-servic-provider-integration-and-websocket-events-6.png)
5. Set up a SendGrid account  
Use [this link](https://docs.sendgrid.com/for-developers/sending-email/api-getting-started) to get started with SendGrid.  
_Note: For this implementation, we’ve created an account and verified the account as a single sender verification._  
![ifx-email-servic-provider-integration-and-websocket-events-7](https://dev.arcxp.com/images/subscriptions/identity/build/ifx-email-servic-provider-integration-and-websocket-events/ifx-email-servic-provider-integration-and-websocket-events-7.png)  
Create an API key under the account.  
![ifx-email-servic-provider-integration-and-websocket-events-8](https://dev.arcxp.com/images/subscriptions/identity/build/ifx-email-servic-provider-integration-and-websocket-events/ifx-email-servic-provider-integration-and-websocket-events-8.png)  
Create dynamic templates to be used with different events  
![ifx-email-servic-provider-integration-and-websocket-events-9](https://dev.arcxp.com/images/subscriptions/identity/build/ifx-email-servic-provider-integration-and-websocket-events/ifx-email-servic-provider-integration-and-websocket-events-9.png)  
You’ll need template ids later in the guide.  
![ifx-email-servic-provider-integration-and-websocket-events-10](https://dev.arcxp.com/images/subscriptions/identity/build/ifx-email-servic-provider-integration-and-websocket-events/ifx-email-servic-provider-integration-and-websocket-events-10.png)  
The dynamic template uses Handlebars. `{{}}` can be used to insert variables and test data can be inserted to preview the email  
![ifx-email-servic-provider-integration-and-websocket-events-11](https://dev.arcxp.com/images/subscriptions/identity/build/ifx-email-servic-provider-integration-and-websocket-events/ifx-email-servic-provider-integration-and-websocket-events-11.png)
6. Bundle, Deploy, Promote  
Follow [this guide](https://dev.arcxp.com/integrations/bundle-management/bundle-deployment-workflow/) to bundle, deploy and promote your integration.
7. Debugging and Testing

  - You can test your code locally by starting up a local server by running `npm run localTestingServer` and then sending POST requests to `http://127.0.0.1:8080/ifx/local/invoke` to verify that your handlers are behaving in the expected way
  - Keeping a WebSocket connection live while testing events can be helpful in verifying that the events are being triggered.
  - You can also use the IFX log API. Initialize the log search by calling `/admin/logs/integration/{integrationName}` then view results by calling `/admin/events/subscriptions`
  - Detailed IFX guide on how to use log API can be found [How to Use Integration Logs with IFX](https://docs.arcxp.com/alc/en/how-to-use-integration-logs-with-ifx?id=kb%5Farticle%5Fview&sys%5Fkb%5Fid=6abbeed7479eb510a87626c2846d433f)
  - You can use `console.log` in event handlers for testing and debugging as it’ll show up on the IFX logs
  - More information on debugging: [Debugging and Testing Deployed Integrations](https://docs.arcxp.com/alc/en/debugging-and-testing-deployed-integrations?id=kb%5Farticle%5Fview&sys%5Fkb%5Fid=859bfa0d87017d10637f315d0ebb3558 "https://docs.arcxp.com/alc/en/debugging-and-testing-deployed-integrations?id=kb_article_view&sys_kb_id=859bfa0d87017d10637f315d0ebb3558")
