Trying to set up a webhook that triggers on a queue SLA breach. I configured the endpoint in Genesys Cloud admin, but the Slack message comes through empty. The webhook payload contains the queueId and threshold, but I’m not sure how to map this to the Slack block kit JSON in the webhook settings. Here is the payload I see in the test: {“queueId”: “123”, “threshold”: 90}. How do I structure the JSON body so Slack renders the queue name and breach time correctly? The current setup just sends raw JSON.
Slack doesn’t parse raw GC payloads. You need a middleware like Zapier or a simple AWS Lambda to transform that JSON into Slack’s block kit format before sending it to the webhook URL.
The middleware suggestion is overkill for this. You can handle the transformation directly in Genesys Cloud using the webhook’s Transform step if you’re using the newer event stream setup, but if you’re stuck with the legacy routing webhooks, you’re right that it sends raw JSON. However, the issue isn’t just the format; it’s that the payload only has IDs. Slack needs text. You need to enrich the data before it hits Slack.
If you control the endpoint, spin up a tiny Node.js or Python listener. Here’s how to fetch the queue name using the PureCloud SDK inside that handler to build the proper Block Kit payload:
const PureCloudApi = require('@genesyscloud/genesyscloud');
async function enrichSlackPayload(gcPayload) {
// Initialize SDK with your client credentials
const api = new PureCloudApi.GenesysCloudApi();
await api.login({
loginOptions: {
grantType: 'client_credentials',
clientId: process.env.GC_CLIENT_ID,
clientSecret: process.env.GC_CLIENT_SECRET
}
});
const routingApi = new PureCloudApi.RoutingApi(api);
// Fetch queue details to get the name
const queueResponse = await routingApi.getRoutingQueue(gcPayload.queueId);
const queueName = queueResponse.body.name;
// Construct Slack Block Kit Message
const slackPayload = {
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: `:warning: *SLA Breach Detected*\nQueue: ${queueName}\nThreshold: ${gcPayload.threshold}%\nTime: ${new Date().toISOString()}`
}
}
]
};
return slackPayload;
}
This fetches the actual queue name so the alert is readable. Without this lookup, you’re sending queueId: 123 to Slack, which is useless for agents.
Cause:
The raw payload from Genesys Cloud only contains IDs (queueId, threshold). Slack’s Block Kit requires human-readable text and specific structural objects (blocks, elements). Sending raw GC JSON to a Slack incoming webhook results in an empty or malformed message because Slack ignores fields it doesn’t recognize as block elements. You need to transform the data.
Solution:
You can’t do this with a simple static JSON body in the webhook config. You need a transformation layer. Since I’m a guy, I usually handle this with a script using a REST Proxy to call an internal Lambda or Azure Function that does the mapping. It keeps the logic out of the noisy event stream configs.
Here is the transformation logic you need. If you use a middleware (like the Lambda suggested above), your input is the GC event, and your output must be the Slack Block Kit structure.
Input (from Genesys):
{
"queueId": "12345678-1234-1234-1234-123456789012",
"threshold": 90,
"eventTime": "2023-10-27T10:00:00Z"
}
Required Output (for Slack Webhook):
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*SLA Breach Alert*\nQueue ID: `12345678-1234-1234-1234-123456789012`\nThreshold Exceeded: 90%"
}
}
]
}
If you are building this in use a REST Proxy action.
- Set Method to
POST. - Set URL to your transformation endpoint (e.g., AWS Lambda).
- In the Body, map the event attributes:
queueId:{{event.queueId}}threshold:{{event.threshold}}
The Lambda function then fetches the queue name using the Genesys Admin API (GET /api/v2/queues/{queueId}) if you need the name, constructs the Block Kit JSON, and returns it. Your webhook then posts that returned JSON to Slack.
Don’t try to do the API lookup inside the webhook config itself. It won’t work. Keep the enrichment in the middleware.