DigiReply Chatbot Webhook Documentation

Overview

DigiReply's webhook system allows you to integrate your chatbot with external applications by receiving real-time notifications about key events. Webhooks are HTTP callbacks that send POST requests to your specified URL when events occur, such as receiving a message or a live chat request. This enables you to build custom workflows, automate processes, and enhance your chatbot's functionality.

Benefits of Using Webhooks

  • Real-Time Updates: Get instant notifications about chatbot interactions, allowing you to respond quickly.
  • Automation: Trigger actions in your CRM, ticketing system, or other tools based on chatbot events.
  • Customization: Build tailored integrations to suit your business needs, such as logging messages or escalating live chat requests.
  • Scalability: Handle high volumes of events efficiently with a secure, rate-limited system.

Supported Events

DigiReply supports the following webhook events. Each event includes a JSON payload with relevant data, sent as a POST request to your registered webhook URL.

1. on_message_received

Triggered when a user sends a message to the chatbot.

Payload:


{
  "event_type": "on_message_received",
  "bot_id": 21,
  "visitor_id": "v_76f4v2c3e13",
  "message": "Hello, I need help with billing.",
  "type": "text",
  "intent": "billing_inquiry",
  "timestamp": "2025-04-26T10:30:45Z"
}
                        

Use Cases:

  • Log user messages in a database or analytics platform for tracking.
  • Trigger notifications in your CRM for customer inquiries.
  • Analyze message content for sentiment or intent to enhance responses.

2. on_ticket_created

Triggered when a ticket is created through the chatbot (e.g., for a support request).

Payload:


{
  "event_type": "on_ticket_created",
  "bot_id": 21,
  "visitor_id": "v_76f4v2c3e13",
  "ticket_number": "TICKET123",
  "ticket_data": {
    "name": "John Doe",
    "email": "john@example.com",
    "description": "Billing issue"
  },
  "timestamp": "2025-04-26T10:32:10Z"
}
                        

Use Cases:

  • Integrate with helpdesk systems (e.g., Zendesk, Freshdesk) to log tickets.
  • Notify support teams of new tickets for follow-up.
  • Track ticket creation metrics for operational insights.

3. on_live_chat_requested

Triggered when a user requests a live chat session (e.g., by typing "live chat").

Payload:


{
  "event_type": "on_live_chat_requested",
  "bot_id": 21,
  "visitor_id": "v_76f4v2c3e13",
  "session_status": "pending",
  "message": "I need live support",
  "request_time": "2025-04-26T10:32:10Z"
}
                        

Use Cases:

  • Alert support agents to join the live chat session.
  • Create a record in your CRM or helpdesk system.
  • Monitor live chat request frequency for staffing decisions.

4. before_response_sent

Triggered before the chatbot sends a response, allowing modification or skipping of the response.

Payload:


{
  "event_type": "before_response_sent",
  "bot_id": 21,
  "visitor_id": "v_76f4v2c3e13",
  "response": {
    "response": "Original response",
    "type": "text"
  },
  "message": "Test message",
  "source_type": "bot",
  "intent": "webhook",
  "timestamp": "2025-04-26T10:40:15Z"
}
                        

Use Cases:

  • Override chatbot responses based on specific intents or conditions.
  • Skip error responses to improve user experience.
  • Log responses for auditing or debugging purposes.

Setup Instructions

Follow these steps to configure and use webhooks with DigiReply.

Step 1: Register a Webhook

  1. Access the Integrations Tab:
    • Log in to your DigiReply dashboard.
    • Navigate to your bot's settings and select the Integrations tab.
  2. Add a Webhook URL:
    • Enter your webhook endpoint URL (e.g., https://yourserver.com/webhook).
    • Requirement: The URL must use HTTPS for security.
    • Click Save to register the webhook.
  3. Generate an Authorization Token:
    • DigiReply generates a unique Authorization token for your webhook.
    • Copy this token and store it securely. It's required for authenticating incoming webhook requests.

Step 2: Configure Your Server

Your server must handle POST requests from DigiReply's webhook system. Here's how to set it up:

  1. Validate the Authorization Header:
    • DigiReply includes an Authorization header in every webhook request (e.g., Authorization: Bearer your_token).
    • Verify the token matches the one provided in the dashboard.
  2. Handle the JSON Payload:
    • Parse the JSON body to extract the event type and other data.
    • Process the event based on your application's logic (e.g., log to a database, trigger a notification).
  3. Respond with a 200 Status Code:
    • Return a 200 OK response to acknowledge receipt.
    • Non-200 responses may trigger retries, increasing server load.
  4. Implement Rate-Limiting:
    • DigiReply limits webhooks to 10 calls per bot to prevent abuse.
    • Ensure your server can handle bursts of requests efficiently and responds quickly.

Step 3: Test Your Webhook

  1. Send a Test Event:
    • In the Integrations tab, use the Test Webhook button to send a sample message_received event.
    • Verify that your server receives the request and processes it correctly.
  2. Check Logs:
    • Monitor your server logs for incoming requests and errors.
    • Ensure the Authorization header is validated and the payload is parsed correctly.
  3. Simulate Real Events:
    • Interact with your chatbot (e.g., send a message, request live chat) to trigger real events.
    • Confirm that your server handles all event types as expected.

Examples

Example 1: Handling Webhooks in PHP

Below is a sample PHP script to handle DigiReply webhooks. It processes four event types: on_message_received, on_ticket_created, on_live_chat_requested, and before_response_sent. The script validates the Authorization header, logs event details to separate files, and provides custom responses based on event types and intents.

Example Payload Structure

{
    "event_type": "on_ticket_created",
    "bot_id": "21",
    "visitor_id": "v_76f4v2c3e13",
    "ticket_number": "TIC-20250507-5320",
    "ticket_data": {
        "name": "John Doe",
        "email": "john@example.com",
        "description": "Need help with integration"
    }
}

Example Response Structure

{
    "status": "success",
    "action": "override_response",
    "response": "Ticket TIC-20250507-5320 has been created successfully."
}

Standardized Log Entry Format

{
    "timestamp": "2025-05-07 00:46:01",
    "event": "ticket.created",
    "source": "chatbot",
    "data": {
        "ticket_number": "TIC-20250507-5320",
        "project_name": "Default Project",
        "priority": "medium",
        "status": "open",
        "created_by": "John Doe",
        "created_by_email": "john@example.com",
        "subject": "Support Ticket from John Doe",
        "description": "Need help with integration",
        "bot_id": "21",
        "visitor_id": "v_76f4v2c3e13"
    }
}

Implementation Example

<?php
require_once 'config/database.php';  // Include database connection

// Secret token for basic authentication
define('WEBHOOK_SECRET', 'PASTE_YOUR_SECRET_KEY_HERE');

// Set response header to JSON
header('Content-Type: application/json');

// Enable error logging
ini_set('log_errors', 1);
ini_set('error_log', 'webhook_error.log');

// Verify the Authorization header
$headers = getallheaders();
$auth_header = isset($headers['Authorization']) ? $headers['Authorization'] : '';
if ($auth_header !== 'Bearer ' . WEBHOOK_SECRET) {
    error_log("Unauthorized access attempt: auth_header='$auth_header'");
    http_response_code(401);
    echo json_encode(['error' => 'Unauthorized']);
    exit;
}

// Read the JSON payload
$input = file_get_contents('php://input');
$payload = json_decode($input, true);
if (!$payload) {
    error_log("Invalid JSON payload: input='$input'");
    http_response_code(400);
    echo json_encode(['error' => 'Invalid JSON payload']);
    exit;
}

// Determine event_type
$event_type = isset($payload['event_type']) ? $payload['event_type'] : '';
$valid_event_types = ['on_message_received', 'on_ticket_created', 'on_live_chat_requested', 'before_response_sent'];
error_log("Processing webhook with event_type='$event_type', payload=" . json_encode($payload));

if (!in_array($event_type, $valid_event_types)) {
    error_log("Invalid event type: event_type='$event_type', payload=" . json_encode($payload));
    http_response_code(400);
    echo json_encode(['error' => 'Invalid event type']);
    exit;
}

// Initialize response
$response = ['status' => 'success'];

// Handle event types
if ($event_type === 'on_message_received') {
    // Log message details
    $log_entry = [
        'timestamp' => date('Y-m-d H:i:s'),
        'event_type' => $event_type,
        'bot_id' => $payload['bot_id'] ?? 'unknown',
        'visitor_id' => $payload['visitor_id'] ?? 'unknown',
        'message' => $payload['message'] ?? 'no message',
        'type' => $payload['type'] ?? 'unknown',
        'intent' => $payload['intent'] ?? 'none'
    ];
    $log_file = 'webhook_log.txt';
    error_log("Writing to webhook_log.txt: " . json_encode($log_entry));
    if (!is_writable($log_file) && !touch($log_file)) {
        error_log("Cannot write to webhook_log.txt: file is not writable");
    }
    if (!file_put_contents(
        $log_file,
        json_encode($log_entry, JSON_PRETTY_PRINT) . PHP_EOL,
        FILE_APPEND | LOCK_EX
    )) {
        error_log("Failed to write to webhook_log.txt");
    }

    // Intent-specific response
    if (isset($payload['intent']) && $payload['intent'] === 'greeting.hello') {
        $response['action'] = 'override_response';
        $response['response'] = 'Welcome! How can I assist you today?';
    }
} elseif ($event_type === 'on_ticket_created') {
    // Validate required fields
    if (!isset($payload['ticket_number']) || !isset($payload['bot_id']) || !isset($payload['visitor_id'])) {
        error_log("Missing required fields for on_ticket_created: payload=" . json_encode($payload));
        http_response_code(400);
        echo json_encode(['error' => 'Missing required fields']);
        exit;
    }

    try {
        // Get project name from bot_id
        $stmt = $pdo->prepare("
            SELECT p.name as project_name 
            FROM bots b 
            JOIN projects p ON b.project_id = p.id 
            WHERE b.id = ?
        ");
        $stmt->execute([$payload['bot_id']]);
        $project = $stmt->fetch(PDO::FETCH_ASSOC);

        // Create standardized log entry
        $log_entry = [
            'timestamp' => date('Y-m-d H:i:s'),
            'event' => 'ticket.created',
            'source' => 'chatbot',
            'data' => [
                'ticket_number' => $payload['ticket_number'],
                'project_name' => $project['project_name'] ?? 'Unknown Project',
                'priority' => 'medium',  // Default priority for chatbot tickets
                'status' => 'open',
                'created_by' => $payload['ticket_data']['name'] ?? 'Unknown',
                'created_by_email' => $payload['ticket_data']['email'] ?? 'Unknown',
                'subject' => isset($payload['ticket_data']['name']) ? 
                            "Support Ticket from " . $payload['ticket_data']['name'] : 
                            "Support Ticket",
                'description' => $payload['ticket_data']['description'] ?? '',
                'bot_id' => $payload['bot_id'],
                'visitor_id' => $payload['visitor_id']
            ]
        ];

        $log_file = 'tickets.txt';
        error_log("Writing standardized format to tickets.txt: " . json_encode($log_entry));
        
        if (!is_writable($log_file) && !touch($log_file)) {
            error_log("Cannot write to tickets.txt: file is not writable");
        }
        
        if (!file_put_contents(
            $log_file,
            json_encode($log_entry) . PHP_EOL,
            FILE_APPEND | LOCK_EX
        )) {
            error_log("Failed to write to tickets.txt");
        }
    } catch (Exception $e) {
        error_log("Error processing ticket webhook: " . $e->getMessage());
        http_response_code(500);
        echo json_encode(['error' => 'Internal server error']);
        exit;
    }

    // Override response for ticket creation
    $response['action'] = 'override_response';
    $response['response'] = "Ticket {$payload['ticket_number']} has been created successfully.";
} elseif ($event_type === 'on_live_chat_requested') {
    // Validate required fields
    if (!isset($payload['bot_id']) || !isset($payload['visitor_id'])) {
        error_log("Missing required fields for on_live_chat_requested: payload=" . json_encode($payload));
        http_response_code(400);
        echo json_encode(['error' => 'Missing required fields']);
        exit;
    }

    // Log live chat request details
    $log_entry = [
        'timestamp' => date('Y-m-d H:i:s'),
        'event_type' => $event_type,
        'bot_id' => $payload['bot_id'],
        'visitor_id' => $payload['visitor_id'],
        'session_status' => $payload['session_status'] ?? 'unknown',
        'message' => $payload['message'] ?? 'no message',
        'request_time' => $payload['request_time'] ?? 'unknown'
    ];
    $log_file = 'live_chat_log.txt';
    error_log("Writing to live_chat_log.txt: " . json_encode($log_entry));
    if (!is_writable($log_file) && !touch($log_file)) {
        error_log("Cannot write to live_chat_log.txt: file is not writable");
    }
    if (!file_put_contents(
        $log_file,
        json_encode($log_entry, JSON_PRETTY_PRINT) . PHP_EOL,
        FILE_APPEND | LOCK_EX
    )) {
        error_log("Failed to write to live_chat_log.txt");
    }

    // Override response for live chat request
    $response['action'] = 'override_response';
    $response['response'] = 'Your live chat request has been received. An agent will assist you shortly.';
} elseif ($event_type === 'before_response_sent') {
    // Validate required fields
    if (!isset($payload['bot_id']) || !isset($payload['visitor_id']) || !isset($payload['response'])) {
        error_log("Missing required fields for before_response_sent: payload=" . json_encode($payload));
        http_response_code(400);
        echo json_encode(['error' => 'Missing required fields']);
        exit;
    }

    // Log response details
    $log_entry = [
        'timestamp' => date('Y-m-d H:i:s'),
        'event_type' => $event_type,
        'bot_id' => $payload['bot_id'],
        'visitor_id' => $payload['visitor_id'],
        'response' => $payload['response'],
        'message' => $payload['message'] ?? 'no message',
        'source_type' => $payload['source_type'] ?? 'unknown'
    ];
    $log_file = 'response_log.txt';
    error_log("Writing to response_log.txt: " . json_encode($log_entry));
    if (!is_writable($log_file) && !touch($log_file)) {
        error_log("Cannot write to response_log.txt: file is not writable");
    }
    if (!file_put_contents(
        $log_file,
        json_encode($log_entry, JSON_PRETTY_PRINT) . PHP_EOL,
        FILE_APPEND | LOCK_EX
    )) {
        error_log("Failed to write to response_log.txt");
    }

    // Overwrite response based on conditions
    $modified_response = $payload['response'];
    
    // Example 1: Change response for a specific intent
    if (isset($payload['intent']) && $payload['intent'] === 'webhook') {
        $modified_response['response'] = 'This is a webhook test.';
        $modified_response['source_type'] = 'webhook';
        $response['action'] = 'override_response';
        $response['response'] = $modified_response;
    }
    
    // Example 2: Skip error responses
    if ($modified_response['type'] === 'error') {
        $response['action'] = 'skip';
    }
}

// Respond with success
http_response_code(200);
echo json_encode($response);
?>
Key Implementation Features:
  • Database Integration: Automatically looks up project name from bot_id
  • Standardized Logging: Consistent format across web and chatbot tickets
  • Error Handling: Comprehensive error catching and logging
  • Field Validation: Required field checking before processing
  • Unified Format: Same logging format for both web and chatbot tickets

Example 2: Testing Your Webhook Implementation

You can test your webhook implementation using tools like cURL or Postman. Here are examples for testing different event types:

Testing Ticket Creation


curl -X POST https://your-domain.com/webhook.php \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
    "event_type": "on_ticket_created",
    "bot_id": "21",
    "visitor_id": "v_123456",
    "ticket_number": "TIC-20250507-5320",
    "ticket_data": {
        "name": "John Doe",
        "email": "john@example.com",
        "description": "Need help with integration"
    }
}'

Expected Response:

{
    "status": "success",
    "action": "override_response",
    "response": "Ticket TIC-20250507-5320 has been created successfully."
}

Testing Message Reception


curl -X POST https://your-domain.com/webhook.php \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
    "event_type": "on_message_received",
    "bot_id": "21",
    "visitor_id": "v_123456",
    "message": "Hello!",
    "intent": "greeting.hello"
}'

Expected Response:

{
    "status": "success",
    "action": "override_response",
    "response": "Welcome! How can I assist you today?"
}

Testing Live Chat Request


curl -X POST https://your-domain.com/webhook.php \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
    "event_type": "on_live_chat_requested",
    "bot_id": "21",
    "visitor_id": "v_123456",
    "session_status": "pending",
    "message": "I need live support"
}'

Expected Response:

{
    "status": "success",
    "action": "override_response",
    "response": "Your live chat request has been received. An agent will assist you shortly."
}
Testing Tips:
  • Always test in a development environment first
  • Check your error logs for debugging information
  • Verify the data is properly logged in the standardized format
  • Test error cases (missing fields, invalid authentication) to ensure proper handling
  • Use tools like Postman for easier testing and request management

Example 3: Common Integration Patterns

Here are some common patterns for extending the webhook functionality:

Custom Response Override

You can override bot responses based on specific conditions:


if ($event_type === 'before_response_sent') {
    // Override response for specific intents
    if (isset($payload['intent']) && $payload['intent'] === 'custom.intent') {
        $response['action'] = 'override_response';
        $response['response'] = 'This is a custom response.';
    }
}

Enhanced Logging

Add additional context to your log entries:


$log_entry = [
    'timestamp' => date('Y-m-d H:i:s'),
    'event_type' => $event_type,
    'environment' => getenv('APP_ENV'),
    'client_ip' => $_SERVER['REMOTE_ADDR'],
    'data' => [
        // Your event-specific data
    ]
];

file_put_contents('webhook_log.txt', json_encode($log_entry) . PHP_EOL, FILE_APPEND | LOCK_EX);

Error Handling

Implement comprehensive error handling:


try {
    // Your webhook logic here
} catch (PDOException $e) {
    error_log("Database error: " . $e->getMessage());
    http_response_code(500);
    echo json_encode(['error' => 'Database error occurred']);
    exit;
} catch (Exception $e) {
    error_log("General error: " . $e->getMessage());
    http_response_code(500);
    echo json_encode(['error' => 'Internal server error']);
    exit;
}
Security Note:

Always validate input data and implement proper error handling to prevent security vulnerabilities and ensure reliable operation of your webhook endpoint.

Best Practices

Security

  • Use HTTPS: Always use an HTTPS URL for your webhook endpoint to encrypt data in transit.
  • Validate Authorization: Check the Authorization header to ensure requests come from DigiReply.
  • Sanitize Payloads: Sanitize incoming data (e.g., message, feedback) to prevent injection attacks. In PHP, use htmlspecialchars() or a library like voku/anti-xss.
  • Secure Tokens: Store your Authorization token securely (e.g., in environment variables, not in code).

Reliability

  • Handle Rate Limits: Process webhook requests quickly to stay within the 10 calls per bot limit. Use queuing systems (e.g., RabbitMQ) for high volumes.
  • Implement Retries: If your server is temporarily unavailable, DigiReply may retry the request. Ensure idempotency by checking visitor_id and timestamp.
  • Log Requests: Log incoming requests and errors for debugging and monitoring.

Testing and Debugging

  • Use a Testing Tool: Use tools like Postman or ngrok to test your webhook endpoint locally.
  • Monitor Logs: Check your server logs for Authorization failures or payload issues.
  • Simulate Events: Use the Integrations tab's test feature or interact with your chatbot to trigger real events.

Troubleshooting

  • Webhook Not Triggering:
    • Verify your webhook URL is HTTPS and accessible.
    • Check the Authorization token in your server's validation logic.
    • Ensure your server responds with a 200 status code.
  • Rate Limit Exceeded:
    • Optimize your server to process requests faster.
    • Reduce the number of bots using the same webhook URL.
    • Contact support if you need assistance with rate limits.
  • Payload Errors:
    • Log the incoming payload to debug missing or malformed data.
    • Ensure your server handles all supported event types.

Contact Support

If you need help with webhooks or any other feature, contact our support team:

  • Email: support@digireply.com
  • Help Centre: Visit the DigiReply Help Centre for FAQs and additional resources.

Last Updated: April 26, 2025