# Data Action Concepts

import { DataActionCards } from "../components/DataActionCards";

## Overview

Spoke supports data actions as a mechanism for customizing organization specific work flows. They are useful for configuring additional call rules, such as blocking outbound calls to specific phone numbers, or overriding the caller ID shown on outbound calls.

To get started, you will need to configure a data action in the Spoke [Account Portal](https://account.spokephone.com/developers/data-actions). You will need to provide a valid, publicly routable `HTTPS` URL that accepts `GET` or `POST` requests with the `application/json` content type.

Spoke will invoke this URL with the corresponding payload when performing a data action.

For security reasons, we strongly recommend that you ensure requests to your endpoint come from Spoke. The easiest method to validate that a request was sent via Spoke is to verify the signature.

## Securing Data Actions

### Verifying the signature

A request is considered valid based on the following conditions:
- The `x-spoke-timestamp` header is a valid UNIX timestamp, and represents a time sent within the last 5 minutes (using millisecond precision). This header allows the consumer to validate when a request was sent, to avoid [replay attacks](https://en.wikipedia.org/wiki/Replay_attack).
- The `x-spoke-signature` header is formatted as `sha256=<HMAC algorithm cipher text>`, and it contains the correct hash based on the hexadecimal representation of the SHA256 HMAC algorithm with the signing secret applied to `<x-spoke-timestamp header value>.<request data>`.
  - The calculated hash includes the timestamp to ensure that an attacker cannot modify the timestamp without also invalidating the message signature.
  - The source of `<request data>` depends on the HTTP method used:
    - For `GET` requests, it is the request URL including the query parameters
    - For `POST` requests, it is the raw request body

A request can be validated via the following:
```js
const isValidSpokeRequest = (requestData: string, signingSecret: string, spokeTimestamp: number, spokeSignature: string): boolean => {

  // Determine if timestamp is valid
  const isValidTimestamp = (Date.now() - spokeTimestamp) <= 300000; // 5 x 60 x 1000
  if (!isValidTimestamp) {
    return false;
  }

  // Determine if the signature is valid
  const [algorithm, cipher] = spokeSignature.split("=");
  const body = `${spokeTimestamp}.${requestData}`

  const h = crypto.createHmac(algorithm, signingSecret);
  h.update(body);
  return h.digest("hex") === cipher;
}
```

## Delivery Attempts

Spoke will attempt to deliver Data Action events to your server once. To successfully invoke the data action, your endpoint *must* respond with a valid response payload within 2 seconds of the HTTP request being received.

Failure to return a response within the timeout period will *not* be treated as an error condition. If your endpoint does not return a response within the timeout period, the call will proceed as planned, using the original configuration for the call.

## Available Data Actions

<DataActionCards />
