Overview
Message History provides comprehensive tracking of all messages sent through Discord Webhook Manager. Every message sent—whether manual or scheduled—is logged with full details including:
Message content and embeds
Delivery status (success/failed)
Timestamp
Sender information
Discord API responses
Message history is automatically created for all webhook sends and is retained indefinitely unless manually deleted.
Accessing Message History
There are multiple ways to view message history:
1. Webhook-Specific History
View history for a single webhook:
Navigate to Webhooks
Go to Webhooks in the sidebar
Select Webhook
Click on the webhook you want to review
View History
Click the History tab or button to see all messages sent through this webhook
URL Pattern : /webhooks/{id}/history
Code Reference : app/app/Controllers/WebhookController.php:351-364
2. Dashboard Overview
The webhook detail page shows recent activity:
$webhook -> load ([ 'messageHistory' => function ( $query ) {
$query -> latest () -> limit ( 10 );
}]);
This displays the 10 most recent messages inline (app/app/Controllers/WebhookController.php:107-109).
3. Statistics View
The webhook show page includes aggregated statistics (app/app/Controllers/WebhookController.php:112-119):
$stats = [
'total' => $totalMessages ,
'success' => $successMessages ,
'error' => $errorMessages ,
'recent' => $recentActivity , // Last 7 days
];
Message History Data Structure
Database Schema
The message_history table stores:
Field Type Description idBIGINT Primary key webhook_idBIGINT Associated webhook user_idBIGINT User who sent the message message_contentJSON Full message payload sent_atTIMESTAMP When message was sent statusVARCHAR success or failedresponseJSON Discord API response created_atTIMESTAMP Record creation updated_atTIMESTAMP Last update
Message Content Format
The message_content field stores the complete Discord payload:
{
"content" : "Hello, Discord!" ,
"embeds" : [
{
"title" : "Announcement" ,
"description" : "Important update..." ,
"color" : 5814783 ,
"fields" : [
{
"name" : "Version" ,
"value" : "1.0.0" ,
"inline" : true
}
],
"timestamp" : "2026-03-06T12:00:00Z" ,
"footer" : {
"text" : "Powered by Webhook Manager"
}
}
]
}
Creating History Records
Successful Messages
When a message sends successfully (app/app/Controllers/WebhookController.php:321-328):
$webhook -> messageHistory () -> create ([
'user_id' => auth () -> id (),
'message_content' => $messageData ,
'sent_at' => now (),
'status' => 'success' ,
'response' => $result [ 'response' ] ?? null ,
]);
Failed Messages
Failed attempts are also logged (app/app/Controllers/WebhookController.php:335-341):
$webhook -> messageHistory () -> create ([
'user_id' => auth () -> id (),
'message_content' => $messageData ,
'sent_at' => now (),
'status' => 'failed' ,
'response' => $result [ 'response' ] ?? null ,
]);
Failed messages still appear in history. This helps you debug issues and track delivery problems.
History Display
History pages show 20 messages per page:
$messages = $webhook -> messageHistory ()
-> with ( 'user:id,name' )
-> latest ( 'sent_at' )
-> paginate ( 20 );
Code Reference : app/app/Controllers/WebhookController.php:355-358
Each history record includes the sender’s name:
This is useful for shared webhooks where multiple users send messages.
Analytics & Statistics
The webhook detail page calculates key metrics:
Total Messages
Success Rate
Error Count
Recent Activity
$totalMessages = $webhook -> messageHistory () -> count ();
Code Reference : app/app/Controllers/WebhookController.php:112-119
Time-Based Analysis
You can extend analytics by grouping messages by hour, day, or month to identify usage patterns.
Example query for daily message counts:
$dailyStats = MessageHistory :: where ( 'webhook_id' , $webhook -> id )
-> selectRaw ( 'DATE(sent_at) as date, COUNT(*) as count' )
-> groupBy ( 'date' )
-> orderBy ( 'date' , 'desc' )
-> limit ( 30 )
-> get ();
Permissions & Access Control
Message history respects webhook permissions:
View Permission
Users can view history if they can view the webhook (app/app/Controllers/WebhookController.php:353):
$this -> authorize ( 'view' , $webhook );
This allows:
Webhook owners
Collaborators with any permission level (admin, editor, viewer)
Privacy Considerations
All users with access to a webhook can see its complete message history, including messages sent by other users.
This is by design to enable team coordination, but be aware when sharing webhooks with sensitive content.
Discord API Responses
The response field stores Discord’s API response:
Success Response Example
{
"id" : "1234567890123456789" ,
"type" : 0 ,
"content" : "Hello, Discord!" ,
"channel_id" : "9876543210987654321" ,
"author" : {
"id" : "1111111111111111111" ,
"username" : "My Webhook" ,
"avatar" : null ,
"discriminator" : "0000" ,
"bot" : true
},
"attachments" : [],
"embeds" : [ ... ],
"mentions" : [],
"mention_roles" : [],
"pinned" : false ,
"mention_everyone" : false ,
"tts" : false ,
"timestamp" : "2026-03-06T12:00:00.000Z" ,
"edited_timestamp" : null ,
"flags" : 0
}
Error Response Example
{
"message" : "Invalid Webhook Token" ,
"code" : 10015
}
Common Discord error codes:
Code Meaning 10015 Unknown Webhook 50027 Invalid Webhook Token 50035 Invalid Form Body (validation error) 40005 Request entity too large (file too big)
Filtering and Search
By Status
Filter messages by delivery status:
// Only successful messages
$successful = $webhook -> messageHistory ()
-> where ( 'status' , 'success' )
-> get ();
// Only failed messages
$failed = $webhook -> messageHistory ()
-> where ( 'status' , 'failed' )
-> get ();
By Date Range
Find messages in a specific time period:
$messages = $webhook -> messageHistory ()
-> whereBetween ( 'sent_at' , [
Carbon :: parse ( '2026-03-01' ),
Carbon :: parse ( '2026-03-31' )
])
-> get ();
By User
For shared webhooks, filter by sender:
$userMessages = $webhook -> messageHistory ()
-> where ( 'user_id' , $userId )
-> get ();
Message History in Scheduled Messages
Scheduled messages also create history records when they send. The main difference is the user_id reflects who created the schedule, not who triggered the send (since it’s automated).
Identifying Scheduled Messages:
You can track whether a message was manually sent or scheduled by checking if it has a corresponding scheduled_message_id (if you extend the schema to include this relationship).
Exporting History
While not implemented in the base application, you can easily add CSV/JSON export functionality using Laravel’s response helpers.
Example export to CSV:
use Illuminate\Support\Facades\ Response ;
public function export ( Webhook $webhook )
{
$this -> authorize ( 'view' , $webhook );
$messages = $webhook -> messageHistory () -> get ();
$csv = Writer :: createFromString ( '' );
$csv -> insertOne ([ 'ID' , 'User' , 'Status' , 'Sent At' ]);
foreach ( $messages as $message ) {
$csv -> insertOne ([
$message -> id ,
$message -> user -> name ,
$message -> status ,
$message -> sent_at -> format ( 'Y-m-d H:i:s' ),
]);
}
return Response :: make ( $csv -> toString (), 200 , [
'Content-Type' => 'text/csv' ,
'Content-Disposition' => 'attachment; filename="history.csv"' ,
]);
}
Retention and Cleanup
Storage Considerations
Message history grows continuously. Consider implementing automatic cleanup:
// Delete history older than 90 days
MessageHistory :: where ( 'sent_at' , '<' , now () -> subDays ( 90 )) -> delete ();
You can run this as a scheduled command:
// app/Console/Kernel.php
$schedule -> call ( function () {
MessageHistory :: where ( 'sent_at' , '<' , now () -> subDays ( 90 )) -> delete ();
}) -> monthly ();
Important : Deleting history is permanent and cannot be undone. Implement this carefully based on your compliance and audit requirements.
Archive Strategy
For long-term retention with reduced storage:
Export old history to compressed JSON files
Store in S3 or cold storage
Delete from active database
Provide “restore from archive” functionality if needed
Debugging Failed Messages
Common Failure Patterns
Invalid Webhook URL:
{
"status" : "failed" ,
"response" : {
"message" : "Unknown Webhook" ,
"code" : 10015
}
}
Validation Errors:
{
"status" : "failed" ,
"response" : {
"message" : "Invalid Form Body" ,
"code" : 50035 ,
"errors" : {
"embeds" : {
"0" : {
"title" : {
"_errors" : [
{
"code" : "BASE_TYPE_MAX_LENGTH" ,
"message" : "Must be 256 or fewer in length."
}
]
}
}
}
}
}
}
Rate Limiting:
{
"status" : "failed" ,
"response" : {
"message" : "You are being rate limited." ,
"retry_after" : 64000 ,
"global" : false
}
}
Troubleshooting Steps
Check Error Response
Review the response field in the failed message record
Verify Webhook URL
Ensure the webhook still exists in Discord and hasn’t been deleted
Validate Content
Check that message content respects Discord limits:
Content: 2000 characters max
Embeds: 10 max per message
Embed title: 256 characters max
Embed description: 4096 characters max
Test Manually
Try sending a simple test message through the same webhook
Database Indexing
Ensure proper indexes for common queries:
CREATE INDEX idx_message_history_webhook_id ON message_history(webhook_id);
CREATE INDEX idx_message_history_sent_at ON message_history(sent_at);
CREATE INDEX idx_message_history_status ON message_history( status );
CREATE INDEX idx_message_history_user_id ON message_history(user_id);
Query Optimization
For large history tables, use chunking for bulk operations:
MessageHistory :: where ( 'webhook_id' , $webhookId )
-> chunk ( 1000 , function ( $messages ) {
foreach ( $messages as $message ) {
// Process each message
}
});
Eager Loading
Always eager load relationships to avoid N+1 queries:
$messages = $webhook -> messageHistory ()
-> with ([ 'user:id,name,email' ])
-> latest ()
-> paginate ( 20 );
Best Practices
Regular Review Periodically review failed messages to identify webhook issues or validation problems.
Set Retention Policy Define how long to keep history based on your compliance and storage constraints.
Monitor Success Rate Track delivery success rate over time to catch degraded performance early.
Use for Auditing Leverage history for compliance auditing and tracking who sent what.
Next Steps
Webhooks Learn more about webhook management
Scheduled Messages Automate message delivery