Notification Layout
The four endpoints managing the frame and logos every notification shares.
Overview
Every notification goes out inside a shared frame: a heading at the top, the template's own body in the middle and a sign-off at the bottom. This article manages that frame and the logos inside it.
The frame is kept per language, since its words and its direction follow the language. The template engine is one choice for the whole installation and decides which syntax the variables use.
The write call checks the frame before saving it: an unknown variable or broken syntax is turned down. A broken frame never takes every notification down with it.
Reference
Reading the Layout
Returns the frame every notification shares, along with the logos.
curl 'https://panel.example.com/api/v1/admin/notifications/settings' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/notifications/settings', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const { data } = await res.json();
const syntax = data.engine; // degiskenlerin yazimi buna bagli$ch = curl_init('https://panel.example.com/api/v1/admin/notifications/settings');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Changing the engine changes the variable syntax in EVERY template; read which one you are on first.
$cfg = Api::Notifications()->GetNotificationSettings()['data'];
$engine = $cfg['engine'];Writing the Layout
Changes the template engine and the frame pieces.
curl -X PUT 'https://panel.example.com/api/v1/admin/notifications/settings' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"engine":"twig","layout":{"en":{"header":"<header></header>","content":"{{ content }}","footer":"<footer></footer>"}}}'const res = await fetch('https://panel.example.com/api/v1/admin/notifications/settings', {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
engine: 'twig',
layout: { en: { header, content: '{{ content }}', footer } },
}),
});
if (res.status === 422) showSyntaxError(await res.json());$ch = curl_init('https://panel.example.com/api/v1/admin/notifications/settings');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['engine' => 'twig', 'layout' => $layout]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The check looks at the frame pieces ALONE: the templates' own bodies go unchecked when the engine changes.
Api::Notifications()->UpdateNotificationSettings([
'engine' => 'twig', 'layout' => $layout,
]);Uploading a Logo
Uploads the top or bottom logo of the notifications.
curl -X POST 'https://panel.example.com/api/v1/admin/notifications/logos/header' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"file":"data:image/png;base64,iVBORw0KGgo..."}'const res = await fetch(`https://panel.example.com/api/v1/admin/notifications/logos/${type}`, {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ file: dataUri }),
});
const { data } = await res.json();$uri = 'data:image/png;base64,' . base64_encode(file_get_contents($path));
$ch = curl_init('https://panel.example.com/api/v1/admin/notifications/logos/' . $type);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['file' => $uri]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// A new logo REMOVES the old one and there is no way back; download and keep the current file first.
$cur = Api::Notifications()->GetNotificationSettings()['data']['logos']['header'] ?? '';
if ($cur) file_put_contents('logo-backup.png', file_get_contents($cur));
Api::Notifications()->UploadNotificationLogo(['type' => 'header', 'file' => $uri]);Removing a Logo
Removes the top or bottom logo.
curl -X DELETE 'https://panel.example.com/api/v1/admin/notifications/logos/header' \
-H "Authorization: Bearer $API_KEY"const res = await fetch(`https://panel.example.com/api/v1/admin/notifications/logos/${type}`, {
method: 'DELETE',
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/notifications/logos/' . $type);
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);// Removing the logo DOES NOT remove the image tag in the layout: the frame can show a broken image.
Api::Notifications()->DeleteNotificationLogo(['type' => 'header']);
// clear the <img> line in the layout as wellPitfalls
The template engine is one setting for the whole installation, and changing it changes the variable syntax of every notification. The write call checks the frame you send and never checks the templates' own bodies. Confirm the template text matches the new syntax before switching.
Uploading a logo takes the old file off the server and no version history is kept. Uploading the wrong image loses the previous one for good. Download the current logo from its address and keep it before uploading.
Removing a logo deletes the file and the setting while leaving the image tag in the frame. A frame still pointing at that address shows a broken image in the e-mail the client receives. Edit the frame after removing the logo.
You write the frame pieces per language while the engine is one installation-wide setting. Writing one language's frame for the new engine and leaving the others behind shows raw variable text in the ones left. Move every language together when switching engines.
The write call checks the joined frame of every language you send in the body. The languages you leave out go unchecked and stay broken where they were. Send every language when you want the whole installation verified.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.