diff options
author | Bjørn Christian Seime <bjorn.christian@seime.no> | 2023-10-30 12:40:17 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-30 12:40:17 +0100 |
commit | 70cf1f41940b73b7db3cc219e6119030e094cf3f (patch) | |
tree | 2e574378490dc8c4a2fa9691c585cc3cd21236c5 | |
parent | 8c7f1f8febf12a5b8468819ba9ff1ede014143d1 (diff) | |
parent | 14cfb5a6e86846fd156367673379e819dd6a28d2 (diff) |
Merge pull request #29151 from vespa-engine/bjorncs/email-notification
Move trial notification emails to separate templates
13 files changed, 56 insertions, 704 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirer.java index 55428e80493..1e261f78db3 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirer.java @@ -30,7 +30,6 @@ import java.util.stream.Collectors; import static com.yahoo.vespa.hosted.controller.persistence.TrialNotifications.State.EXPIRED; import static com.yahoo.vespa.hosted.controller.persistence.TrialNotifications.State.EXPIRES_IMMEDIATELY; -import static com.yahoo.vespa.hosted.controller.persistence.TrialNotifications.State.EXPIRES_SOON; import static com.yahoo.vespa.hosted.controller.persistence.TrialNotifications.State.MID_CHECK_IN; import static com.yahoo.vespa.hosted.controller.persistence.TrialNotifications.State.SIGNED_UP; import static com.yahoo.vespa.hosted.controller.persistence.TrialNotifications.State.UNKNOWN; @@ -95,6 +94,14 @@ public class CloudTrialExpirer extends ControllerMaintainer { return tombstoneTenants(idleOldPlanTenants); } + + /* + * Trial plan notification states. Transition to a new state triggers a notification/email + * - SIGNED_UP: Tenant has signed up for trial + * - MID_CHECK_IN: Tenant is halfway through trial (7 days) + * - EXPIRES_IMMEDIATELY: Tenant has 1 day left of trial + * - EXPIRED: Tenant has expired + */ private boolean notifyTenants() { try { var currentStatus = controller().curator().readTrialNotifications() @@ -129,12 +136,8 @@ public class CloudTrialExpirer extends ControllerMaintainer { && !List.of(EXPIRES_IMMEDIATELY, EXPIRED).contains(state)) { updatedStatus.add(updatedStatus(tenant, now, EXPIRES_IMMEDIATELY)); notifyExpiresImmediately(tenant); - } else if ("trial".equals(plan) && ageInDays >= 12 - && !List.of(EXPIRES_SOON, EXPIRES_IMMEDIATELY, EXPIRED).contains(state)) { - updatedStatus.add(updatedStatus(tenant, now, EXPIRES_SOON)); - notifyExpiresSoon(tenant); } else if ("trial".equals(plan) && ageInDays >= 7 - && !List.of(MID_CHECK_IN, EXPIRES_SOON, EXPIRES_IMMEDIATELY, EXPIRED).contains(state)) { + && !List.of(MID_CHECK_IN, EXPIRES_IMMEDIATELY, EXPIRED).contains(state)) { updatedStatus.add(updatedStatus(tenant, now, MID_CHECK_IN)); notifyMidCheckIn(tenant); } else { @@ -152,44 +155,28 @@ public class CloudTrialExpirer extends ControllerMaintainer { private void notifySignup(Tenant tenant) { var consoleMsg = "Welcome to Vespa Cloud trial! [Manage plan](%s)".formatted(billingUrl(tenant)); - queueNotification(tenant, consoleMsg, "Welcome to Vespa Cloud", - "Welcome to Vespa Cloud! We hope you will enjoy your trial. " + - "Please reach out to us if you have any questions or feedback."); + queueNotification(tenant, consoleMsg, "Welcome to Vespa Cloud", MailTemplating.Template.TRIAL_SIGNED_UP); } private void notifyMidCheckIn(Tenant tenant) { var consoleMsg = "You're halfway through the **14 day** trial period. [Manage plan](%s)".formatted(billingUrl(tenant)); - queueNotification(tenant, consoleMsg, "How is your Vespa Cloud trial going?", - "How is your Vespa Cloud trial going? " + - "Please reach out to us if you have any questions or feedback."); - } - - private void notifyExpiresSoon(Tenant tenant) { - var consoleMsg = "Your Vespa Cloud trial expires in **2** days. [Manage plan](%s)".formatted(billingUrl(tenant)); - queueNotification(tenant, consoleMsg, "Your Vespa Cloud trial expires in 2 days", - "Your Vespa Cloud trial expires in 2 days. " + - "Please reach out to us if you have any questions or feedback."); + queueNotification(tenant, consoleMsg, "How is your Vespa Cloud trial going?", MailTemplating.Template.TRIAL_MIDWAY_CHECKIN); } private void notifyExpiresImmediately(Tenant tenant) { var consoleMsg = "Your Vespa Cloud trial expires **tomorrow**. [Manage plan](%s)".formatted(billingUrl(tenant)); - queueNotification(tenant, consoleMsg, "Your Vespa Cloud trial expires tomorrow", - "Your Vespa Cloud trial expires tomorrow. " + - "Please reach out to us if you have any questions or feedback."); + queueNotification(tenant, consoleMsg, "Your Vespa Cloud trial expires tomorrow", MailTemplating.Template.TRIAL_EXPIRES_IMMEDIATELY); } private void notifyExpired(Tenant tenant) { var consoleMsg = "Your Vespa Cloud trial has expired. [Upgrade plan](%s)".formatted(billingUrl(tenant)); - queueNotification(tenant, consoleMsg, "Your Vespa Cloud trial has expired", - "Your Vespa Cloud trial has expired. " + - "Please reach out to us if you have any questions or feedback."); + queueNotification(tenant, consoleMsg, "Your Vespa Cloud trial has expired", MailTemplating.Template.TRIAL_EXPIRED); } - private void queueNotification(Tenant tenant, String consoleMsg, String emailSubject, String emailMsg) { + private void queueNotification(Tenant tenant, String consoleMsg, String emailSubject, MailTemplating.Template template) { var mail = Optional.of(Notification.MailContent.fromTemplate(MailTemplating.Template.DEFAULT_MAIL_CONTENT) .subject(emailSubject) - .with("mailMessageTemplate", "cloud-trial-notification") - .with("cloudTrialMessage", emailMsg) + .with("mailMessageTemplate", template.getId()) .with("mailTitle", emailSubject) .with("consoleLink", controller().serviceRegistry().consoleUrls().tenantOverview(tenant.name())) .build()); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/MailTemplating.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/MailTemplating.java index 1c05330702e..642840bf2b3 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/MailTemplating.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/MailTemplating.java @@ -25,7 +25,9 @@ public class MailTemplating { public enum Template { MAIL("mail"), DEFAULT_MAIL_CONTENT("default-mail-content"), NOTIFICATION_MESSAGE("notification-message"), - CLOUD_TRIAL_NOTIFICATION("cloud-trial-notification"), MAIL_VERIFICATION("mail-verification"); + MAIL_VERIFICATION("mail-verification"), TRIAL_SIGNED_UP("trial-signed-up"), TRIAL_MIDWAY_CHECKIN("trial-midway-checkin"), + TRIAL_EXPIRES_IMMEDIATELY("trial-expires-immediately"), TRIAL_EXPIRED("trial-expired") + ; public static Optional<Template> fromId(String id) { return Arrays.stream(values()).filter(t -> t.id.equals(id)).findAny(); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/TrialNotifications.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/TrialNotifications.java index a205e6c4173..cf6923b1e2c 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/TrialNotifications.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/TrialNotifications.java @@ -21,7 +21,7 @@ public record TrialNotifications(List<Status> tenants) { public TrialNotifications { tenants = List.copyOf(tenants); } public record Status(TenantName tenant, State state, Instant lastUpdate) {} - public enum State { SIGNED_UP, MID_CHECK_IN, EXPIRES_SOON, EXPIRES_IMMEDIATELY, EXPIRED, UNKNOWN } + public enum State { SIGNED_UP, MID_CHECK_IN, EXPIRES_IMMEDIATELY, EXPIRED, UNKNOWN } public Slime toSlime() { var slime = new Slime(); diff --git a/controller-server/src/main/resources/mail/cloud-trial-notification.vm b/controller-server/src/main/resources/mail/cloud-trial-notification.vm deleted file mode 100644 index c1ba394bf8e..00000000000 --- a/controller-server/src/main/resources/mail/cloud-trial-notification.vm +++ /dev/null @@ -1,3 +0,0 @@ -<p> - $esc.html($cloudTrialMessage) -</p>
\ No newline at end of file diff --git a/controller-server/src/main/resources/mail/trial-expired.vm b/controller-server/src/main/resources/mail/trial-expired.vm new file mode 100644 index 00000000000..02d2aacd117 --- /dev/null +++ b/controller-server/src/main/resources/mail/trial-expired.vm @@ -0,0 +1,3 @@ +<p> + Your Vespa Cloud trial has expired. Please reach out to us if you have any questions or feedback. +</p>
\ No newline at end of file diff --git a/controller-server/src/main/resources/mail/trial-expires-immediately.vm b/controller-server/src/main/resources/mail/trial-expires-immediately.vm new file mode 100644 index 00000000000..79604cae2e5 --- /dev/null +++ b/controller-server/src/main/resources/mail/trial-expires-immediately.vm @@ -0,0 +1,3 @@ +<p> + Your Vespa Cloud trial expires tomorrow. Please reach out to us if you have any questions or feedback. +</p>
\ No newline at end of file diff --git a/controller-server/src/main/resources/mail/trial-midway-checkin.vm b/controller-server/src/main/resources/mail/trial-midway-checkin.vm new file mode 100644 index 00000000000..c29c2763ef1 --- /dev/null +++ b/controller-server/src/main/resources/mail/trial-midway-checkin.vm @@ -0,0 +1,3 @@ +<p> + How is your Vespa Cloud trial going? Please reach out to us if you have any questions or feedback. +</p>
\ No newline at end of file diff --git a/controller-server/src/main/resources/mail/trial-signed-up.vm b/controller-server/src/main/resources/mail/trial-signed-up.vm new file mode 100644 index 00000000000..20f1867b7bc --- /dev/null +++ b/controller-server/src/main/resources/mail/trial-signed-up.vm @@ -0,0 +1,3 @@ +<p> + Welcome to Vespa Cloud! We hope you will enjoy your trial. Please reach out to us if you have any questions or feedback. +</p>
\ No newline at end of file diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirerTest.java index 4056459c532..02d0a020cd2 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirerTest.java @@ -110,40 +110,41 @@ public class CloudTrialExpirerTest { .withBooleanFlag(Flags.CLOUD_TRIAL_NOTIFICATIONS.id(), true); registerTenant(tenant.value(), "trial", Duration.ZERO); assertEquals(0.0, expirer.maintain()); - var expected = "Welcome to Vespa Cloud trial! [Manage plan](https://console.tld/tenant/trial-tenant/account/billing)"; - assertEquals(expected, lastAccountLevelNotificationTitle(tenant)); - assertLastEmailEquals(mailer, "welcome.html"); - - expected = "You're halfway through the **14 day** trial period. [Manage plan](https://console.tld/tenant/trial-tenant/account/billing)"; + var expectedConsoleNotification = + "Welcome to Vespa Cloud trial! [Manage plan](https://console.tld/tenant/trial-tenant/account/billing)"; + var notification = lastAccountLevelNotification(tenant); + assertEquals(expectedConsoleNotification, notification.title()); + assertLastEmail(mailer, notification); + + expectedConsoleNotification = + "You're halfway through the **14 day** trial period. [Manage plan](https://console.tld/tenant/trial-tenant/account/billing)"; clock.advance(Duration.ofDays(7)); assertEquals(0.0, expirer.maintain()); - assertEquals(expected, lastAccountLevelNotificationTitle(tenant)); - assertLastEmailEquals(mailer, "trial-reminder.html"); - - expected = "Your Vespa Cloud trial expires in **2** days. [Manage plan](https://console.tld/tenant/trial-tenant/account/billing)"; - clock.advance(Duration.ofDays(5)); - assertEquals(0.0, expirer.maintain()); - assertEquals(expected, lastAccountLevelNotificationTitle(tenant)); - assertLastEmailEquals(mailer, "trial-expiring-soon.html"); + notification = lastAccountLevelNotification(tenant); + assertEquals(expectedConsoleNotification, notification.title()); + assertLastEmail(mailer, notification); - expected = "Your Vespa Cloud trial expires **tomorrow**. [Manage plan](https://console.tld/tenant/trial-tenant/account/billing)"; - clock.advance(Duration.ofDays(1)); + expectedConsoleNotification = "Your Vespa Cloud trial expires **tomorrow**. [Manage plan](https://console.tld/tenant/trial-tenant/account/billing)"; + clock.advance(Duration.ofDays(6)); assertEquals(0.0, expirer.maintain()); - assertEquals(expected, lastAccountLevelNotificationTitle(tenant)); - assertLastEmailEquals(mailer, "trial-expiring-immediately.html"); + notification = lastAccountLevelNotification(tenant); + assertEquals(expectedConsoleNotification, notification.title()); + assertLastEmail(mailer, notification); - expected = "Your Vespa Cloud trial has expired. [Upgrade plan](https://console.tld/tenant/trial-tenant/account/billing)"; + expectedConsoleNotification = "Your Vespa Cloud trial has expired. [Upgrade plan](https://console.tld/tenant/trial-tenant/account/billing)"; clock.advance(Duration.ofDays(2)); assertEquals(0.0, expirer.maintain()); - assertEquals(expected, lastAccountLevelNotificationTitle(tenant)); - assertLastEmailEquals(mailer, "trial-expired.html"); + notification = lastAccountLevelNotification(tenant); + assertEquals(expectedConsoleNotification, notification.title()); + assertLastEmail(mailer, notification); } - private void assertLastEmailEquals(MockMailer mailer, String expectedContentFile) throws IOException { + private void assertLastEmail(MockMailer mailer, Notification notification) throws IOException { var mails = mailer.inbox("dev-trial-tenant"); assertFalse(mails.isEmpty()); var content = mails.get(mails.size() - 1).htmlMessage().orElseThrow(); - var path = Paths.get("src/test/resources/mail/" + expectedContentFile); + var templateName = notification.mailContent().orElseThrow().values().get("mailMessageTemplate"); + var path = Paths.get("src/test/resources/mail/%s.html".formatted(templateName)); if (OVERWRITE_TEST_FILES) { Files.write(path, content.getBytes(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE); @@ -175,11 +176,10 @@ public class CloudTrialExpirerTest { assertEquals(planId, tester.serviceRegistry().billingController().getPlan(TenantName.from(tenant)).value()); } - private String lastAccountLevelNotificationTitle(TenantName tenant) { + private Notification lastAccountLevelNotification(TenantName tenant) { return tester.controller().notificationsDb() .listNotifications(NotificationSource.from(tenant), false).stream() - .filter(n -> n.type() == Notification.Type.account).map(Notification::title) + .filter(n -> n.type() == Notification.Type.account) .findFirst().orElseThrow(); } - } diff --git a/controller-server/src/test/resources/mail/trial-expiring-immediately.html b/controller-server/src/test/resources/mail/trial-expires-immediately.html index db89eca195a..db89eca195a 100644 --- a/controller-server/src/test/resources/mail/trial-expiring-immediately.html +++ b/controller-server/src/test/resources/mail/trial-expires-immediately.html diff --git a/controller-server/src/test/resources/mail/trial-expiring-soon.html b/controller-server/src/test/resources/mail/trial-expiring-soon.html deleted file mode 100644 index 17c59240cc4..00000000000 --- a/controller-server/src/test/resources/mail/trial-expiring-soon.html +++ /dev/null @@ -1,646 +0,0 @@ -<!DOCTYPE html> -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:v="urn:schemas-microsoft-com:vml" - xmlns:o="urn:schemas-microsoft-com:office:office" -> - <head> - <title></title> - <!--[if !mso]><!--> - <meta http-equiv="X-UA-Compatible" content="IE=edge" /> - <!--<![endif]--> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <meta name="viewport" content="width=device-width,initial-scale=1" /> - <style type="text/css"> - #outlook a { - padding: 0; - } - - body { - margin: 0; - padding: 0; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - } - - table, - td { - border-collapse: collapse; - mso-table-lspace: 0pt; - mso-table-rspace: 0pt; - } - - img { - border: 0; - height: auto; - line-height: 100%; - outline: none; - text-decoration: none; - -ms-interpolation-mode: bicubic; - } - - p { - display: block; - margin: 13px 0; - } - </style> - <!--[if mso]> - <noscript> - <xml> - <o:OfficeDocumentSettings> - <o:AllowPNG /> - <o:PixelsPerInch>96</o:PixelsPerInch> - </o:OfficeDocumentSettings> - </xml> - </noscript> - <![endif]--> - <!--[if lte mso 11]> - <style type="text/css"> - .mj-outlook-group-fix { - width: 100% !important; - } - </style> - <![endif]--> - <!--[if !mso]><!--> - <link - href="https://fonts.googleapis.com/css?family=Open Sans" - rel="stylesheet" - type="text/css" - /> - <style type="text/css"> - @import url(https://fonts.googleapis.com/css?family=Open Sans); - </style> - <!--<![endif]--> - <style type="text/css"> - @media only screen and (min-width: 480px) { - .mj-column-per-100 { - width: 100% !important; - max-width: 100%; - } - } - </style> - <style media="screen and (min-width:480px)"> - .moz-text-html .mj-column-per-100 { - width: 100% !important; - max-width: 100%; - } - </style> - <style type="text/css"> - [owa] .mj-column-per-100 { - width: 100% !important; - max-width: 100%; - } - </style> - <style type="text/css"> - @media only screen and (max-width: 480px) { - table.mj-full-width-mobile { - width: 100% !important; - } - - td.mj-full-width-mobile { - width: auto !important; - } - } - </style> - </head> - - <body style="word-spacing: normal; background-color: #f2f7fa"> - <div style="background-color: #f2f7fa"> - <!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--> - <div style="margin: 0px auto; max-width: 600px"> - <table - align="center" - border="0" - cellpadding="0" - cellspacing="0" - role="presentation" - style="width: 100%" - > - <tbody> - <tr> - <td - style=" - direction: ltr; - font-size: 0px; - padding: 20px 0px 20px 0px; - padding-bottom: 0px; - padding-top: 0px; - text-align: center; - " - > - <!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--> - <div - class="mj-column-per-100 mj-outlook-group-fix" - style=" - font-size: 0px; - text-align: left; - direction: ltr; - display: inline-block; - vertical-align: top; - width: 100%; - " - > - <table - border="0" - cellpadding="0" - cellspacing="0" - role="presentation" - style="vertical-align: top" - width="100%" - > - <tbody> - <tr> - <td - align="left" - style=" - font-size: 0px; - padding: 0px 0px 0px 25px; - padding-top: 0px; - padding-bottom: 0px; - word-break: break-word; - " - > - <div - style=" - font-family: Open Sans, Helvetica, Arial, - sans-serif; - font-size: 11px; - line-height: 22px; - text-align: left; - color: #797e82; - " - > - <br /> - </div> - </td> - </tr> - </tbody> - </table> - </div> - <!--[if mso | IE]></td></tr></table><![endif]--> - </td> - </tr> - </tbody> - </table> - </div> - <!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" bgcolor="#ffffff" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--> - <div - style=" - background: #ffffff; - background-color: #ffffff; - margin: 0px auto; - max-width: 600px; - " - > - <table - align="center" - border="0" - cellpadding="0" - cellspacing="0" - role="presentation" - style="background: #ffffff; background-color: #ffffff; width: 100%" - > - <tbody> - <tr> - <td - style=" - direction: ltr; - font-size: 0px; - padding: 20px 0; - padding-bottom: 0px; - padding-left: 0px; - padding-right: 0px; - padding-top: 0px; - text-align: center; - " - > - <!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--> - <div - class="mj-column-per-100 mj-outlook-group-fix" - style=" - font-size: 0px; - text-align: left; - direction: ltr; - display: inline-block; - vertical-align: top; - width: 100%; - " - > - <table - border="0" - cellpadding="0" - cellspacing="0" - role="presentation" - style="vertical-align: top" - width="100%" - > - <tbody> - <tr> - <td - align="center" - style=" - font-size: 0px; - padding: 10px 25px; - padding-top: 0px; - padding-right: 0px; - padding-bottom: 40px; - padding-left: 0px; - word-break: break-word; - " - > - <p - style=" - border-top: solid 8px #005a8e; - font-size: 1px; - margin: 0px auto; - width: 100%; - " - ></p> - <!--[if mso | IE - ]><table - align="center" - border="0" - cellpadding="0" - cellspacing="0" - style=" - border-top: solid 8px #005a8e; - font-size: 1px; - margin: 0px auto; - width: 600px; - " - role="presentation" - width="600px" - > - <tr> - <td style="height: 0; line-height: 0"> - - </td> - </tr> - </table><! - [endif]--> - </td> - </tr> - <tr> - <td - align="center" - style=" - font-size: 0px; - padding: 10px 25px; - padding-top: 0px; - padding-bottom: 0px; - word-break: break-word; - " - > - <table - border="0" - cellpadding="0" - cellspacing="0" - role="presentation" - style=" - border-collapse: collapse; - border-spacing: 0px; - " - > - <tbody> - <tr> - <td style="width: 121px"> - <img - alt="" - height="auto" - src="https://data.vespa.oath.cloud/assets/vespa-cloud-logo.png" - style=" - border: none; - display: block; - outline: none; - text-decoration: none; - height: auto; - width: 100%; - font-size: 13px; - " - width="121" - /> - </td> - </tr> - </tbody> - </table> - </td> - </tr> - </tbody> - </table> - </div> - <!--[if mso | IE]></td></tr></table><![endif]--> - </td> - </tr> - </tbody> - </table> - </div> - <!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" bgcolor="#ffffff" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--> - <div - style=" - background: #ffffff; - background-color: #ffffff; - margin: 0px auto; - max-width: 600px; - " - > - <table - align="center" - border="0" - cellpadding="0" - cellspacing="0" - role="presentation" - style="background: #ffffff; background-color: #ffffff; width: 100%" - > - <tbody> - <tr> - <td - style=" - direction: ltr; - font-size: 0px; - padding: 20px 0px 20px 0px; - padding-bottom: 70px; - padding-top: 30px; - text-align: center; - " - > - <!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--> - <div - class="mj-column-per-100 mj-outlook-group-fix" - style=" - font-size: 0px; - text-align: left; - direction: ltr; - display: inline-block; - vertical-align: top; - width: 100%; - " - > - <table - border="0" - cellpadding="0" - cellspacing="0" - role="presentation" - style="vertical-align: top" - width="100%" - > - -<tbody> -<tr> - <td - align="left" - style=" - font-size: 0px; - padding: 0px 25px 0px 25px; - padding-top: 0px; - padding-right: 50px; - padding-bottom: 0px; - padding-left: 50px; - word-break: break-word; - " - > - <div - style=" - font-family: Open Sans, Helvetica, Arial, - sans-serif; - font-size: 13px; - line-height: 22px; - text-align: left; - color: #797e82; - " - > - <h1 - style=" - text-align: center; - color: #000000; - line-height: 32px; - " - > - Your Vespa Cloud trial expires in 2 days - </h1> - </div> - </td> -</tr> -<tr> - <td - align="left" - style=" - font-size: 0px; - padding: 0px 25px 0px 25px; - padding-top: 0px; - padding-right: 50px; - padding-bottom: 0px; - padding-left: 50px; - word-break: break-word; - " - > - <div - style=" - font-family: Open Sans, Helvetica, Arial, - sans-serif; - font-size: 13px; - line-height: 22px; - text-align: left; - color: #797e82; - " - > - -<p> - Your Vespa Cloud trial expires in 2 days. Please reach out to us if you have any questions or feedback. -</p> - </div> - </td> -</tr> -<tr> - <td - align="center" - vertical-align="middle" - style=" - font-size: 0px; - padding: 10px 25px; - padding-top: 20px; - padding-bottom: 20px; - word-break: break-word; - " - > - <table - border="0" - cellpadding="0" - cellspacing="0" - role="presentation" - style="border-collapse: separate; line-height: 100%" - > - <tbody> - <tr> - <td - align="center" - bgcolor="#005A8E" - role="presentation" - style=" - border: none; - border-radius: 100px; - cursor: auto; - mso-padding-alt: 15px 25px 15px 25px; - background: #005a8e; - " - valign="middle" - > - <a - href="https://console.tld/tenant/trial-tenant" - style=" - display: inline-block; - background: #005a8e; - color: #ffffff; - font-family: Open Sans, Helvetica, Arial, - sans-serif; - font-size: 13px; - font-weight: normal; - line-height: 120%; - margin: 0; - text-decoration: none; - text-transform: none; - padding: 15px 25px 15px 25px; - mso-padding-alt: 0px; - border-radius: 100px; - " - target="_blank" - ><b style="font-weight: 700" - ><b style="font-weight: 700" - >Go to Console</b - ></b - ></a - > - </td> - </tr> - </tbody> - </table> - </td> -</tr> -</tbody> - </table> - </div> - <!--[if mso | IE]></td></tr></table><![endif]--> - </td> - </tr> - </tbody> - </table> - </div> - <!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--> - <div style="margin: 0px auto; max-width: 600px"> - <table - align="center" - border="0" - cellpadding="0" - cellspacing="0" - role="presentation" - style="width: 100%" - > - <tbody> - <tr> - <td - style=" - direction: ltr; - font-size: 0px; - padding: 20px 0px 20px 0px; - padding-bottom: 0px; - padding-top: 20px; - text-align: center; - " - > - <!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--> - <div - class="mj-column-per-100 mj-outlook-group-fix" - style=" - font-size: 0px; - text-align: left; - direction: ltr; - display: inline-block; - vertical-align: top; - width: 100%; - " - > - <table - border="0" - cellpadding="0" - cellspacing="0" - role="presentation" - style="vertical-align: top" - width="100%" - > - <tbody> - <tr> - <td - align="center" - style=" - font-size: 0px; - padding: 0px 20px 0px 20px; - padding-top: 0px; - padding-bottom: 0px; - word-break: break-word; - " - > - <div - style=" - font-family: Open Sans, Helvetica, Arial, - sans-serif; - font-size: 11px; - line-height: 22px; - text-align: center; - color: #797e82; - " - > - <p style="margin: 10px 0"> - <a - target="_blank" - rel="noopener noreferrer" - style="color: #005a8e" - href="https://legal.yahoo.com/xw/en/yahoo/privacy/topic/b2bprivacypolicy/index.html" - ><span style="color: #005a8e" - >Yahoo Privacy Policy</span - ></a - ><span style="color: #797e82" - > | </span - ><a - target="_blank" - rel="noopener noreferrer" - style="color: #005a8e" - href="https://console.tld/terms-of-service-trial.html" - ><span style="color: #005a8e" - >Terms of Service</span - ></a - ><span style="color: #797e82" - > | </span - ><a - target="_blank" - rel="noopener noreferrer" - style="color: #005a8e" - href="https://console.tld/support" - ><span style="color: #005a8e">Support</span></a - > - </p> - <p style="margin: 10px 0"> - <a - target="_blank" - rel="noopener noreferrer" - style="color: inherit; text-decoration: none" - href="https://console.tld/tenant/trial-tenant/account/notifications" - >Click - <span style="color: #005a8e"><u>here</u></span> - to manage your notifications setting.</a - ><br /> - </p> - </div> - </td> - </tr> - </tbody> - </table> - </div> - <!--[if mso | IE]></td></tr></table><![endif]--> - </td> - </tr> - </tbody> - </table> - </div> - <!--[if mso | IE]></td></tr></table><![endif]--> - </div> - </body> -</html> diff --git a/controller-server/src/test/resources/mail/trial-reminder.html b/controller-server/src/test/resources/mail/trial-midway-checkin.html index fbe0d573538..fbe0d573538 100644 --- a/controller-server/src/test/resources/mail/trial-reminder.html +++ b/controller-server/src/test/resources/mail/trial-midway-checkin.html diff --git a/controller-server/src/test/resources/mail/welcome.html b/controller-server/src/test/resources/mail/trial-signed-up.html index 2e652532db8..2e652532db8 100644 --- a/controller-server/src/test/resources/mail/welcome.html +++ b/controller-server/src/test/resources/mail/trial-signed-up.html |