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.
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.
on_message_receivedTriggered 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:
on_ticket_createdTriggered 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:
on_live_chat_requestedTriggered 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:
before_response_sentTriggered 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:
Follow these steps to configure and use webhooks with DigiReply.
https://yourserver.com/webhook).Authorization token for your webhook.Your server must handle POST requests from DigiReply's webhook system. Here's how to set it up:
Authorization header in every webhook request (e.g., Authorization: Bearer your_token).event type and other data.200 OK response to acknowledge receipt.message_received event.Authorization header is validated and the payload is parsed correctly.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.
{
"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"
}
}
{
"status": "success",
"action": "override_response",
"response": "Ticket TIC-20250507-5320 has been created successfully."
}
{
"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"
}
}
<?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);
?>
You can test your webhook implementation using tools like cURL or Postman. Here are examples for testing different event types:
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."
}
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?"
}
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."
}
Here are some common patterns for extending the webhook functionality:
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.';
}
}
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);
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;
}
Always validate input data and implement proper error handling to prevent security vulnerabilities and ensure reliable operation of your webhook endpoint.
Authorization header to ensure requests come from DigiReply.message, feedback) to prevent injection attacks. In PHP, use htmlspecialchars() or a library like voku/anti-xss.visitor_id and timestamp.Authorization failures or payload issues.If you need help with webhooks or any other feature, contact our support team:
Last Updated: April 26, 2025