GudDesk
Docs
Custom Agents

Custom Agents

Build external AI agents that integrate with GudDesk.

Agents are external services that receive webhook events from GudDesk and act on conversations via the REST API. Each agent brings its own logic, LLM, and billing — GudDesk provides the data and actions.

How Agents Work

  1. Install — register your agent in a workspace (via the dashboard or API). GudDesk creates a webhook endpoint and a dedicated API key.
  2. Receive events — GudDesk sends webhook payloads to your agent's URL when conversations and messages happen.
  3. Act — your agent calls the GudDesk API to reply, tag, assign, or resolve conversations using the API key it received at install.

This is the same pattern used by gud-agent, the open-source reference implementation.

Architecture

┌─────────────┐     webhook POST     ┌──────────────┐
│   GudDesk   │ ──────────────────▶  │  Your Agent  │
│  (Platform) │                      │  (External)  │
│             │  ◀──────────────────  │              │
└─────────────┘   REST API calls     └──────────────┘
                  (with API key)

Your agent is a web service at a public HTTPS URL. It can be written in any language and use any LLM provider.

Installing an Agent

Via the Dashboard

  1. Go to Settings > AI Agents
  2. Click Install Agent
  3. Enter a name, your agent's webhook URL, and select which events to subscribe to
  4. Click Install Agent
  5. Save the webhook signing secret and API key — they're shown only once

Via the API

curl -X POST https://guddesk.com/api/v1/agents \
  -H "Authorization: Bearer gd_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "RefundBot",
    "description": "Handles refund requests automatically",
    "webhookUrl": "https://your-agent.com/webhook",
    "events": {
      "onMessageCreated": true,
      "onConversationCreated": true
    }
  }'

The response includes one-time credentials:

{
  "data": {
    "id": "clx...",
    "name": "RefundBot",
    "credentials": {
      "webhookSecret": "a1b2c3...",
      "apiKey": "gd_xyz789..."
    }
  }
}

Receiving Webhooks

When subscribed events occur, GudDesk sends a POST request to your webhook URL:

{
  "event": "message.created",
  "data": {
    "conversationId": "conv_123",
    "messageId": "msg_456",
    "type": "VISITOR",
    "body": "I want a refund for order #1234",
    "workspaceId": "ws_789"
  },
  "timestamp": "2025-01-15T10:30:00.000Z"
}

Headers

HeaderDescription
X-GudDesk-SignatureHMAC SHA-256 signature: sha256=<hex>
X-GudDesk-EventEvent name (e.g., message.created)
X-GudDesk-Agent-IdYour agent's ID in GudDesk

Verifying Signatures

Verify the X-GudDesk-Signature header using your webhook secret:

import { createHmac } from "crypto";
 
function verifySignature(payload: string, secret: string, signature: string): boolean {
  const expected = createHmac("sha256", secret).update(payload).digest("hex");
  return signature === `sha256=${expected}`;
}

Available Events

EventDescription
message.createdA visitor or agent sent a message
conversation.createdA new conversation started
conversation.closedA conversation was resolved
conversation.assignedA conversation was assigned to a team member

Acting via the API

Use the API key from installation to call the GudDesk API. The key is scoped to the workspace and has READ_WRITE permission.

Reply to a conversation

curl -X POST https://guddesk.com/api/agent/reply \
  -H "Authorization: Bearer gd_xyz789..." \
  -H "Content-Type: application/json" \
  -d '{
    "conversationId": "conv_123",
    "body": "Your refund for order #1234 has been processed!",
    "senderName": "RefundBot"
  }'

Update a conversation

curl -X PATCH https://guddesk.com/api/v1/conversations/conv_123 \
  -H "Authorization: Bearer gd_xyz789..." \
  -H "Content-Type: application/json" \
  -d '{
    "status": "CLOSED",
    "tags": ["refund", "resolved"]
  }'

Read conversation messages

curl "https://guddesk.com/api/v1/conversations/conv_123/messages" \
  -H "Authorization: Bearer gd_xyz789..."

Example: Simple Echo Agent

A minimal agent in Node.js that echoes back visitor messages:

import express from "express";
import { createHmac } from "crypto";
 
const app = express();
app.use(express.json());
 
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET!;
const API_KEY = process.env.GUDDESK_API_KEY!;
const GUDDESK_URL = process.env.GUDDESK_URL || "https://guddesk.com";
 
app.post("/webhook", async (req, res) => {
  // Verify signature
  const signature = req.headers["x-guddesk-signature"] as string;
  const expected = `sha256=${createHmac("sha256", WEBHOOK_SECRET)
    .update(JSON.stringify(req.body))
    .digest("hex")}`;
 
  if (signature !== expected) {
    return res.status(401).send("Invalid signature");
  }
 
  const { event, data } = req.body;
 
  // Only respond to visitor messages
  if (event === "message.created" && data.type === "VISITOR") {
    await fetch(`${GUDDESK_URL}/api/agent/reply`, {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        conversationId: data.conversationId,
        body: `Echo: ${data.body}`,
        senderName: "EchoBot",
      }),
    });
  }
 
  res.status(200).send("OK");
});
 
app.listen(3001);

Best Practices

  • Verify webhook signatures — always check the X-GudDesk-Signature header
  • Respond quickly — return a 200 status within a few seconds; do heavy processing asynchronously
  • Start simple — build agents for one specific task, not general-purpose bots
  • Always have an escalation path — if your agent can't handle something, leave the conversation open for a human
  • Use senderName — identify your agent's replies so humans know which bot responded

Next Steps

  • API Overview — Full REST API documentation
  • Webhooks — Webhook event reference and payload format
  • gud-agent — Open-source AI support agent reference implementation