Replace Discord webhook notifications with Matrix (hookshot)
- Add helpers/NotificationHelper.php: shared Matrix webhook sender that reads MATRIX_WEBHOOK_URL and MATRIX_NOTIFY_USERS from config - Remove sendDiscordWebhook() from TicketController; call NotificationHelper::sendTicketNotification() instead - Replace 60-line Discord embed block in create_ticket_api.php with a single NotificationHelper call - config/config.php: DISCORD_WEBHOOK_URL → MATRIX_WEBHOOK_URL + new MATRIX_NOTIFY_USERS key (comma-separated Matrix user IDs) - .env.example: updated env var names and comments Payload sent to hookshot includes notify_users array so the JS transform can build proper @mention links for each user. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ require_once dirname(__DIR__) . '/models/UserModel.php';
|
||||
require_once dirname(__DIR__) . '/models/WorkflowModel.php';
|
||||
require_once dirname(__DIR__) . '/models/TemplateModel.php';
|
||||
require_once dirname(__DIR__) . '/helpers/UrlHelper.php';
|
||||
require_once dirname(__DIR__) . '/helpers/NotificationHelper.php';
|
||||
|
||||
class TicketController {
|
||||
private $ticketModel;
|
||||
@@ -110,8 +111,8 @@ class TicketController {
|
||||
$GLOBALS['auditLog']->logTicketCreate($userId, $result['ticket_id'], $ticketData);
|
||||
}
|
||||
|
||||
// Send Discord webhook notification for new ticket
|
||||
$this->sendDiscordWebhook($result['ticket_id'], $ticketData);
|
||||
// Send Matrix notification for new ticket
|
||||
NotificationHelper::sendTicketNotification($result['ticket_id'], $ticketData, 'manual');
|
||||
|
||||
// Redirect to the new ticket
|
||||
header("Location: " . $GLOBALS['config']['BASE_URL'] . "/ticket/" . $result['ticket_id']);
|
||||
@@ -195,107 +196,5 @@ class TicketController {
|
||||
}
|
||||
}
|
||||
|
||||
private function sendDiscordWebhook($ticketId, $ticketData) {
|
||||
$webhookUrl = $GLOBALS['config']['DISCORD_WEBHOOK_URL'] ?? null;
|
||||
if (empty($webhookUrl)) {
|
||||
error_log("Discord webhook URL not configured, skipping webhook for ticket creation");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create ticket URL using validated host
|
||||
$ticketUrl = UrlHelper::ticketUrl($ticketId);
|
||||
|
||||
// Map priorities to Discord colors (matching API endpoint)
|
||||
$priorityColors = [
|
||||
1 => 0xDC3545, // P1 Critical - Red
|
||||
2 => 0xFD7E14, // P2 High - Orange
|
||||
3 => 0x0DCAF0, // P3 Medium - Cyan
|
||||
4 => 0x198754, // P4 Low - Green
|
||||
5 => 0x6C757D // P5 Info - Gray
|
||||
];
|
||||
|
||||
// Priority labels for display
|
||||
$priorityLabels = [
|
||||
1 => "P1 - Critical",
|
||||
2 => "P2 - High",
|
||||
3 => "P3 - Medium",
|
||||
4 => "P4 - Low",
|
||||
5 => "P5 - Info"
|
||||
];
|
||||
|
||||
$priority = (int)($ticketData['priority'] ?? 4);
|
||||
$color = $priorityColors[$priority] ?? 0x6C757D;
|
||||
$priorityLabel = $priorityLabels[$priority] ?? "P{$priority}";
|
||||
|
||||
$title = $ticketData['title'] ?? 'Untitled';
|
||||
$category = $ticketData['category'] ?? 'General';
|
||||
$type = $ticketData['type'] ?? 'Issue';
|
||||
$status = $ticketData['status'] ?? 'Open';
|
||||
|
||||
// Extract hostname from title for cleaner display
|
||||
preg_match('/^\[([^\]]+)\]/', $title, $hostnameMatch);
|
||||
$sourceHost = $hostnameMatch[1] ?? 'Manual';
|
||||
|
||||
$embed = [
|
||||
'title' => 'New Ticket Created',
|
||||
'description' => "**#{$ticketId}** - {$title}",
|
||||
'url' => $ticketUrl,
|
||||
'color' => $color,
|
||||
'fields' => [
|
||||
[
|
||||
'name' => 'Priority',
|
||||
'value' => $priorityLabel,
|
||||
'inline' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Category',
|
||||
'value' => $category,
|
||||
'inline' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Type',
|
||||
'value' => $type,
|
||||
'inline' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Status',
|
||||
'value' => $status,
|
||||
'inline' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Source',
|
||||
'value' => $sourceHost,
|
||||
'inline' => true
|
||||
]
|
||||
],
|
||||
'footer' => [
|
||||
'text' => 'Tinker Tickets | Manual Entry'
|
||||
],
|
||||
'timestamp' => date('c')
|
||||
];
|
||||
|
||||
$payload = [
|
||||
'embeds' => [$embed]
|
||||
];
|
||||
|
||||
// Send webhook
|
||||
$ch = curl_init($webhookUrl);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
|
||||
$webhookResult = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curlError = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($curlError) {
|
||||
error_log("Discord webhook cURL error: {$curlError}");
|
||||
} elseif ($httpCode !== 204 && $httpCode !== 200) {
|
||||
error_log("Discord webhook failed for ticket #{$ticketId}. HTTP Code: {$httpCode}");
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user