mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Improve SMTP test email design
This commit is contained in:
@@ -1,36 +1,41 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=DM+Sans:wght@500;600&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Poppins:wght@500;600&display=swap">
|
||||
<style>
|
||||
.main a {
|
||||
color: currentColor;
|
||||
}
|
||||
.main {
|
||||
body {
|
||||
padding: 32px;
|
||||
line-height: 1.5;
|
||||
color: #616b7c;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
font-family: "Inter", sans-serif;
|
||||
background-color: #ffffff;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
a {
|
||||
color: currentColor;
|
||||
word-break: break-all;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-spacing: 0;
|
||||
border-spacing: 0 !important;
|
||||
}
|
||||
table,
|
||||
tr,
|
||||
th,
|
||||
td {
|
||||
table, tr, th, td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
td {
|
||||
vertical-align: top;
|
||||
}
|
||||
.main {
|
||||
max-width: 650px;
|
||||
margin: 0 auto;
|
||||
margin-top: 32px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 22px;
|
||||
margin-bottom: 0px;
|
||||
@@ -42,8 +47,7 @@
|
||||
font-weight: 600;
|
||||
color: #373b4d;
|
||||
}
|
||||
h3,
|
||||
td h3 {
|
||||
h3 {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #373b4d;
|
||||
@@ -63,7 +67,9 @@
|
||||
border: none;
|
||||
border-top: 1px solid #e8e9f0;
|
||||
}
|
||||
.main a.button {
|
||||
</style>
|
||||
<style>
|
||||
a.button {
|
||||
display: inline-block;
|
||||
background: #fd366e;
|
||||
color: #ffffff;
|
||||
@@ -80,50 +86,14 @@
|
||||
margin-right: 24px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.main a.button:hover,
|
||||
.main a.button:focus {
|
||||
a.button:hover,
|
||||
a.button:focus {
|
||||
opacity: 0.8;
|
||||
}
|
||||
.main a.button.is-reverse {
|
||||
background: #fff;
|
||||
color: #fd366e;
|
||||
}
|
||||
.fs12 {
|
||||
font-size: 12px;
|
||||
}
|
||||
.ta-right {
|
||||
text-align: right !important;
|
||||
}
|
||||
.ta-left {
|
||||
text-align: left !important;
|
||||
}
|
||||
.ff-dmsans {
|
||||
font-family: "DM Sans", sans-serif !important;
|
||||
}
|
||||
.ff-inter {
|
||||
font-family: "Inter", sans-serif !important;
|
||||
}
|
||||
.w500 {
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
.w400 {
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
.w600 {
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
.tc-accent {
|
||||
color: #da1a5b;
|
||||
}
|
||||
.pt-16 {
|
||||
padding-top: 16px !important;
|
||||
}
|
||||
.pt-32 {
|
||||
padding-top: 32px !important;
|
||||
}
|
||||
.divider {
|
||||
padding-top: 32px;
|
||||
border-bottom: solid 1px #d8d8db;
|
||||
@media only screen and (max-width: 600px) {
|
||||
.button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.social-icon {
|
||||
border-radius: 6px;
|
||||
@@ -135,21 +105,14 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.social-icon > img {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
.button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="background-color: #ffffff; margin: 0; padding: 0;>
|
||||
<div class="main" style="max-width: 650px; margin: 0 auto">
|
||||
<body>
|
||||
<div class="main">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
@@ -169,9 +132,11 @@
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="margin-top: 40px">
|
||||
<table style="margin-top: 32px">
|
||||
<tr>
|
||||
<td>{{message}}</td>
|
||||
<td>
|
||||
{{body}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -1,67 +1,92 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Poppins:wght@500;600&display=swap">
|
||||
<style>
|
||||
body {
|
||||
padding: 32px;
|
||||
line-height: 1.5;
|
||||
color: #616b7c;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
font-family: "Inter", sans-serif;
|
||||
background-color: #ffffff;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
a {
|
||||
color: currentColor;
|
||||
word-break: break-all;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-spacing: 0 !important;
|
||||
}
|
||||
table, tr, th, td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
td {
|
||||
vertical-align: top;
|
||||
}
|
||||
.main {
|
||||
max-width: 650px;
|
||||
margin: 0 auto;
|
||||
margin-top: 32px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 22px;
|
||||
margin-bottom: 0px;
|
||||
margin-top: 0px;
|
||||
color: #373b4d;
|
||||
}
|
||||
h2 {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #373b4d;
|
||||
}
|
||||
h3 {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #373b4d;
|
||||
line-height: 21px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
h4 {
|
||||
font-family: "DM Sans", sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
color: #4f5769;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid #e8e9f0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<head>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Poppins:wght@500;600&display=swap"
|
||||
rel="stylesheet">
|
||||
<style>
|
||||
a { color:currentColor; word-break: break-all; }
|
||||
body {
|
||||
padding: 32px;
|
||||
color: #616B7C;
|
||||
font-size: 15px;
|
||||
font-family: 'Inter', sans-serif;
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-spacing: 0 !important;
|
||||
}
|
||||
|
||||
table,
|
||||
tr,
|
||||
th,
|
||||
td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
h* {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid #E8E9F0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="direction: {{direction}}">
|
||||
|
||||
<div style="max-width:650px; word-wrap: break-word; overflow-wrap: break-word;
|
||||
word-break: normal; margin:0 auto;">
|
||||
<table style="margin-top: 32px">
|
||||
<tr>
|
||||
<td>
|
||||
{{body}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
<body>
|
||||
<div class="main">
|
||||
<table style="margin-top: 32px">
|
||||
<tr>
|
||||
<td>
|
||||
<h1>{{subject}}</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="margin-top: 32px">
|
||||
<tr>
|
||||
<td>
|
||||
{{body}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
<p style="margin-block-start: 0;">Hello,</p>
|
||||
|
||||
<p>This email ensures your custom SMTP configuration is working correctly. Please review your sender Information details:</p>
|
||||
|
||||
<p style="margin-block-end: 0;">From: <strong>{{from}}</strong></p>
|
||||
<p style="margin-block-start: 0;">Reply-To: <strong>{{replyTo}}</strong></p>
|
||||
|
||||
<p>If this email landed in your spam folder, ensure your SMTP server is set up correctly. A common mistake is overlooking some DNS configuration.</p>
|
||||
<p>If you have trouble with the sender's image, ensure it is set in the <a href="https://gravatar.com/">Gravatar database</a>.</p>
|
||||
|
||||
<p style="margin-block-end: 0;">Best regards,</p>
|
||||
<p style="margin-block-start: 0;">Appwrtite team</p>
|
||||
@@ -1,7 +0,0 @@
|
||||
<p>Hello,</p>
|
||||
|
||||
<p>You're good to go! If you see this email, SMTP settings you provided are valid.</p>
|
||||
|
||||
<p>Thanks</p>
|
||||
|
||||
<p>Appwrite Team</p>
|
||||
@@ -1661,9 +1661,13 @@ App::post('/v1/projects/:projectId/smtp/tests')
|
||||
throw new Exception(Exception::PROJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$subject = 'Custom SMTP email from Appwrite';
|
||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-test.tpl');
|
||||
$body = $message->render();
|
||||
$replyToEmail = !empty($replyTo) ? $replyTo : $senderEmail;
|
||||
|
||||
$subject = 'Custom SMTP email sample';
|
||||
$template = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-smtp-test.tpl');
|
||||
$template
|
||||
->setParam('{{from}}', "{$senderName} ({$senderEmail})")
|
||||
->setParam('{{replyTo}}', "{$senderName} ({$replyToEmail})");
|
||||
|
||||
foreach ($emails as $email) {
|
||||
$queueForMails
|
||||
@@ -1677,7 +1681,8 @@ App::post('/v1/projects/:projectId/smtp/tests')
|
||||
->setSmtpSenderName($senderName)
|
||||
->setRecipient($email)
|
||||
->setName('')
|
||||
->setBody($body)
|
||||
->setbodyTemplate(__DIR__ . '/../../config/locale/templates/email-base-styled.tpl')
|
||||
->setBody($template->render())
|
||||
->setVariables([])
|
||||
->setSubject($subject)
|
||||
->trigger();
|
||||
|
||||
@@ -13,6 +13,7 @@ class Mail extends Event
|
||||
protected string $body = '';
|
||||
protected array $smtp = [];
|
||||
protected array $variables = [];
|
||||
protected string $bodyTemplate = '';
|
||||
|
||||
public function __construct(protected Connection $connection)
|
||||
{
|
||||
@@ -115,6 +116,29 @@ class Mail extends Event
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets bodyTemplate for the mail event.
|
||||
*
|
||||
* @param string $bodyTemplate
|
||||
* @return self
|
||||
*/
|
||||
public function setbodyTemplate(string $bodyTemplate): self
|
||||
{
|
||||
$this->bodyTemplate = $bodyTemplate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns subject for the mail event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getbodyTemplate(): string
|
||||
{
|
||||
return $this->bodyTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SMTP Host
|
||||
*
|
||||
@@ -327,6 +351,7 @@ class Mail extends Event
|
||||
'recipient' => $this->recipient,
|
||||
'name' => $this->name,
|
||||
'subject' => $this->subject,
|
||||
'bodyTemplate' => $this->bodyTemplate,
|
||||
'body' => $this->body,
|
||||
'smtp' => $this->smtp,
|
||||
'variables' => $this->variables,
|
||||
|
||||
@@ -63,7 +63,15 @@ class Mails extends Action
|
||||
$name = $payload['name'];
|
||||
$body = $payload['body'];
|
||||
|
||||
$bodyTemplate = Template::fromFile(__DIR__ . '/../../../../app/config/locale/templates/email-base.tpl');
|
||||
$variables['subject'] = $subject;
|
||||
$variables['year'] = date("Y");
|
||||
|
||||
$bodyTemplate = $payload['bodyTemplate'];
|
||||
if (empty($bodyTemplate)) {
|
||||
$bodyTemplate = __DIR__ . '/../../../../app/config/locale/templates/email-base.tpl';
|
||||
}
|
||||
|
||||
$bodyTemplate = Template::fromFile($bodyTemplate);
|
||||
$bodyTemplate->setParam('{{body}}', $body);
|
||||
foreach ($variables as $key => $value) {
|
||||
$bodyTemplate->setParam('{{' . $key . '}}', $value);
|
||||
@@ -101,12 +109,8 @@ class Mails extends Action
|
||||
$replyToName = \urldecode(App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server'));
|
||||
|
||||
if (!empty($smtp)) {
|
||||
if (!empty($smtp['replyTo'])) {
|
||||
$replyTo = $smtp['replyTo'];
|
||||
}
|
||||
if (!empty($smtp['senderName'])) {
|
||||
$replyToName = $smtp['senderName'];
|
||||
}
|
||||
$replyTo = !empty($smtp['replyTo']) ? $smtp['replyTo'] : $smtp['senderEmail'];
|
||||
$replyToName = $smtp['senderName'];
|
||||
}
|
||||
|
||||
$mail->addReplyTo($replyTo, $replyToName);
|
||||
|
||||
@@ -606,9 +606,11 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$this->assertEquals('Custom Mailer', $emails[0]['from'][0]['name']);
|
||||
$this->assertEquals('reply@appwrite.io', $emails[0]['replyTo'][0]['address']);
|
||||
$this->assertEquals('Custom Mailer', $emails[0]['replyTo'][0]['name']);
|
||||
$this->assertEquals('Custom SMTP email from Appwrite', $emails[0]['subject']);
|
||||
$this->assertStringContainsStringIgnoringCase('good to go', $emails[0]['text']);
|
||||
$this->assertStringContainsStringIgnoringCase('good to go', $emails[0]['html']);
|
||||
$this->assertEquals('Custom SMTP email sample', $emails[0]['subject']);
|
||||
$this->assertStringContainsStringIgnoringCase('working correctly', $emails[0]['text']);
|
||||
$this->assertStringContainsStringIgnoringCase('working correctly', $emails[0]['html']);
|
||||
$this->assertStringContainsStringIgnoringCase('251 Little Falls Drive', $emails[0]['text']);
|
||||
$this->assertStringContainsStringIgnoringCase('251 Little Falls Drive', $emails[0]['html']);
|
||||
|
||||
$to = [
|
||||
$emails[0]['to'][0]['address'],
|
||||
|
||||
Reference in New Issue
Block a user