Are you hitting the Slack webhook directly from Genesys Cloud or through an intermediate service?
The issue is almost certainly the variable syntax. Genesys Cloud webhooks don’t resolve {{queue.name}} inside the JSON body string like a template engine. They send the raw JSON structure with the actual data nested under data. Slack’s incoming webhook expects a flat text key. If you send that template string literally, Slack receives invalid JSON or a string it can’t parse as expected.
I ran into this exact 400 error last week while building a similar alert system in C#. The fix is to send the raw object and handle the formatting on the receiving end, or use a very specific payload structure if you’re using an intermediary like Azure Functions.
If you are hitting Slack directly, you can’t use template variables in the body. You have to send the full event payload and parse it. But since you can’t write code inside the Genesys webhook config, the best approach is to point the webhook to a lightweight API endpoint (like an Azure Function or a simple Express server) that transforms the data.
Here’s how the Genesys Cloud webhook payload actually looks when it hits your endpoint. Note that queue is nested inside data:
{
"type": "queue",
"id": "12345",
"data": {
"name": "Support Team",
"waitTime": 120000
}
}
Your C# Azure Function handler should look something like this to transform it for Slack:
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
ILogger log)
{
var body = await new StreamReader(req.Body).ReadToEndAsync();
var payload = JsonConvert.DeserializeObject<GenesysEvent>(body);
// Transform to Slack format
var slackPayload = new {
text = $"Queue {payload.Data.Name} has breached SLA. Current wait: {payload.Data.WaitTime / 1000}s"
};
var client = new HttpClient();
var content = new StringContent(JsonConvert.SerializeObject(slackPayload), Encoding.UTF8, "application/json");
// Post to Slack
var response = await client.PostAsync(SLACK_WEBHOOK_URL, content);
if (!response.IsSuccessStatusCode)
{
return new StatusCodeResult(500);
}
return new OkObjectResult("Posted to Slack");
}
public class GenesysEvent
{
public string Type { get; set; }
public string Id { get; set; }
public QueueData Data { get; set; }
}
public class QueueData
{
public string Name { get; set; }
public long WaitTime { get; set; } // in milliseconds
}
This way, Genesys sends valid JSON, your function validates it, and you send valid JSON to Slack. Direct templating in the webhook body just doesn’t work as expected.