# DigitalCX - Webhook helpers

The [sdk-webhooks](https://www.npmjs.com/package/@cxco/sdk-webhooks) is a package that wraps DigitalCX webhooks inbound and outbound payloads into simple javascript objects.
It supports Validation, Transaction and Context Variable webhooks.  

## Install and usage

Run `npm install @cxco/sdk-webhooks`

Then you can use the three main classes:

* `ValidationResponse` for handling validation webhooks
* `TransactionResponse` for handling transaction (end slot) webhooks
* `ContextResponse` for handling Context Variable webhooks

For instance in an express route handlers to extract 3 digits from the user input you could do:

```javascript
const { ValidationResponse } = require('@cxco/sdk-webhooks')
const matchThreeNumbers = require('./utils/matchThreeNumbers')

/**
 * Express middleware to handle the validation webhook and find 3 numbers in the user input
 *
 * @param {object} req
 * @param {object} res
 * @param {function} next
 */
module.exports = function findThreeNumbers (req, res, next) {
    try {
        // make sure the req.body JSON has already been parsed with the body-parse middleware
        const slot = new ValidationResponse(req.body)

        // make sure we are validating the current slot
        if (slot.isCurrentSlot) {
            const match = matchThreeNumbers(input)

            if (match !== '') {
                // this will set the value to the matched numbers
                // and set the status of the slot to 'done'
                slot.setValue(match)
            }
        }

        // return the payload using the toModel method
        res.send(slot.toModel())
    } catch (error) {
        // call the error handling middleware
        next(error)
    }
}
```

## ValidationResponse 

```javascript
const slot = new ValidationResponse(req.body)

// check if it is the initial response
slot.initialRequest // boolean

// check if it si the current slot that is being validated
slot.isCurrentSlot // boolean

// set the value of the slot
slot.setValue('new value') // will also set the status to 'done'

// add to the metadata
slot.metadata.foo = 'bar'

// build the required response payload
slot.toModel()
```

## Mock functions

There are three mock functions available to test your webhooks:

* `mockSlot` will mock the configuration of a slot including the set value, status and metadata.
* `mockValidationPayload` to mock the full validation webhook payload. Uses `mockSlot` to define the `payload.slot` object.
* `mockTransationPayload` to mock the full transaction webhook payload. Uses `mockSlot` to define the elements in `payload.slots` array.

You can use them in your tests like so:

```javascript
const { mocks, ValidationResponse } = require('@cxco/sdk-webhooks').

describe('isCurrentSlot', () => {
    it('is true when the current slot is the active one', () => {
        const payload = mocks.mockValidationPayload({
            inputSlotName: 'the current slot',
            slot: mocks.mockSlot({ name: 'the current slot' })
        })

        const instance = new ValidationResponse(payload)

        expect(instance.isCurrentSlot).toBe(true)
    })

    it('is false when current slot is not the active one', () => {
        const payload = mocks.mockValidationPayload({
            inputSlotName: 'the current slot',
            slot: mocks.mockSlot({ name: 'another slot' })
        })

        const instance = new ValidationResponse(payload)

        expect(instance.isCurrentSlot).toBe(false)
    })
})

```

## ContextResponse

ContextResponse wraps the inbound payload. The function `setOutboundContextVariable` sets the value for a given context.


```javascript
const  { ContextResponse } = require('@cxco/sdk-webhooks')
//...
app.post('/context', function (req, res) {

    const cxtResponse = new ContextResponse(req.body)

    cxtResponse.setOutboundContextVariable("season", "summer")
    // build the required response payload and send as an answer
    res.send(cxtResponse.toModel())
})
```