Notification Queue
The nine endpoints that watch, rescue and clear the e-mails and messages waiting to go out.
Overview
E-mails and text messages are not sent straight away; they go into a queue and are worked through in the background. These nine endpoints watch that queue, rescue what got stuck and clear what piled up.
The message itself is stored encrypted and comes back from no endpoint. What you get here is the subject, the recipient and the status. To read a message that went out, the place is the activity logs.
The shape is almost the same as the module queue, but two endpoints differ. Retry here also accepts queued items, while sending now accepts only queued ones.
Reference
Listing the Queue
Returns the e-mails and text messages waiting to go out.
mail or sms.pending is queued, processing is going out, sent went, failed did not.curl -G 'https://panel.example.com/api/v1/admin/tools/notification-queue' \
-H "Authorization: Bearer $API_KEY" \
-d status=failed \
-d channel=mailconst url = new URL('https://panel.example.com/api/v1/admin/tools/notification-queue');
url.searchParams.set('status', 'failed');
url.searchParams.set('channel', 'mail');
const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
const body = await res.json();$url = 'https://panel.example.com/api/v1/admin/tools/notification-queue?' . http_build_query([
'status' => 'failed',
'channel' => 'mail',
]);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The message itself comes back from NO endpoint; beyond the subject and recipient there is no content.
$failed = Api::Tools()->GetNotificationQueue([], ['status' => 'failed'])['data'];The Queue Counters
Returns how many notices are waiting and how many went out.
curl 'https://panel.example.com/api/v1/admin/tools/notification-queue/stats' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tools/notification-queue/stats', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/notification-queue/stats');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// A pending count that keeps growing is the sign that the sending pipeline has stopped.
$stats = Api::Tools()->GetNotificationQueueStats()['data'];Item Detail
Returns one notice together with the record of its sending attempts.
mail or sms.pending is queued, processing is going out, sent went, failed did not.curl 'https://panel.example.com/api/v1/admin/tools/notification-queue/201' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tools/notification-queue/201', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/notification-queue/201');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Even the detail does NOT carry the body: to read a sent message, look in the activity log.
$item = Api::Tools()->GetNotificationQueueItem(['id' => 201])['data'];
$why = end($item['process_logs']);Retrying an Item
Puts a notice back in line to be sent.
curl -X POST 'https://panel.example.com/api/v1/admin/tools/notification-queue/201/retry' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tools/notification-queue/201/retry', {
method: 'POST',
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/notification-queue/201/retry');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The retry also accepts QUEUED items, which is how you move one up the line.
Api::Tools()->RetryNotificationQueueItem(['id' => 201]);Sending an Item Now
Sends the notice there and then, without waiting for the background worker, and returns the outcome.
curl -X POST 'https://panel.example.com/api/v1/admin/tools/notification-queue/201/run' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tools/notification-queue/201/run', {
method: 'POST',
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/notification-queue/201/run');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// A failed notice cannot be sent directly: retry it into the queue first, then run it.
Api::Tools()->RetryNotificationQueueItem(['id' => 201]);
$result = Api::Tools()->RunNotificationQueueItem(['id' => 201])['data'];
if (!$result['task_success']) {
$why = $result['task_message'];
}Deleting an Item
Takes a notice out of the queue. One that had not gone never goes.
curl -X DELETE 'https://panel.example.com/api/v1/admin/tools/notification-queue/201' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tools/notification-queue/201', {
method: 'DELETE',
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/notification-queue/201');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// A notice already going out CANNOT be deleted; wait until the send finishes.
Api::Tools()->DeleteNotificationQueueItem(['id' => 201]);Deleting in Bulk
Takes several notices out of the queue.
curl -X POST 'https://panel.example.com/api/v1/admin/tools/notification-queue/bulk-delete' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"ids":[201,202]}'const res = await fetch('https://panel.example.com/api/v1/admin/tools/notification-queue/bulk-delete', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ ids: [201, 202] }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/notification-queue/bulk-delete');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['ids' => [201, 202]]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Ones going out are skipped quietly: compare the deleted count with what you sent.
$ids = [201, 202];
$response = Api::Tools()->BulkDeleteNotificationQueue(['ids' => $ids]);
$skipped = count($ids) - $response['data']['count'];Retrying Everything That Failed
Puts every failed notice in the queue back in line.
curl -X POST 'https://panel.example.com/api/v1/admin/tools/notification-queue/retry-all-failed' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tools/notification-queue/retry-all-failed', {
method: 'POST',
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/notification-queue/retry-all-failed');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Unlike the module queue, this endpoint does return a COUNT.
$count = Api::Tools()->RetryAllFailedNotificationQueue()['data']['retried'];Clearing What Was Sent
Deletes the sent notices from the queue.
curl -X POST 'https://panel.example.com/api/v1/admin/tools/notification-queue/clear-sent' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tools/notification-queue/clear-sent', {
method: 'POST',
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/notification-queue/clear-sent');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Clearing the queue does not delete the SENT RECORD: what went out stays in the activity log.
Api::Tools()->ClearSentNotificationQueue();Pitfalls
The queue endpoints give the subject, the recipient and the status. The body is stored encrypted and is absent even from the detail. To see what a client was actually sent, look in the activity logs rather than the queue.
The retry takes both failed and queued notices; sending now takes only queued ones. So sending a failed notice immediately means retrying it into the queue first and running it after. Trying it in one step answers not_pending.
A notice currently going out cannot be deleted and is skipped quietly in a bulk delete. The gap between how many ids you sent and the count you get back is what was skipped. Without checking it, a notice you thought you cancelled may already be on its way.
On the notification queue the retry-all endpoint returns how many notices were queued again. The same endpoint on the module queue does not. Writing one helper for both queues means accounting for that.
Clearing the sent notices removes queue rows only. What was sent stays in the activity logs, so no history is lost. Confusing the two leads to treating data as gone when it is not.
Related Articles
Vielen Dank für Ihre Rückmeldung!
Unser Support-Team ist rund um die Uhr für Sie da, wenn Sie oben nicht fündig werden.