fix pricing + limits email + redis

This commit is contained in:
Emily
2024-09-07 15:47:13 +02:00
parent 30b3ed80e2
commit 73739dde9d
15 changed files with 361 additions and 482 deletions

View File

@@ -11,15 +11,63 @@ if (process.env.EMAIL_SERVICE) {
export async function checkLimitsForEmail(projectCounts: TProjectLimit) { export async function checkLimitsForEmail(projectCounts: TProjectLimit) {
if ((projectCounts.visits + projectCounts.events) >= (projectCounts.limit / 2)) { console.log('CHECK LIMIT EMAIL');
const notify = await LimitNotifyModel.findOne({ project_id: projectCounts._id });
if (notify && notify.limit1 === true) return; const project_id = projectCounts.project_id;
const project = await ProjectModel.findById(projectCounts.project_id); const hasNotifyEntry = await LimitNotifyModel.findOne({ project_id });
if (!project) return; if (!hasNotifyEntry) {
const owner = await UserModel.findById(project.owner); await LimitNotifyModel.create({ project_id, limit1: false, limit2: false, limit3: false })
if (!owner) return;
if (process.env.EMAIL_SERVICE) await EmailService.sendLimitEmail50(owner.email);
await LimitNotifyModel.updateOne({ project_id: projectCounts._id }, { limit1: true, limit2: false, limit3: false }, { upsert: true });
} }
} if ((projectCounts.visits + projectCounts.events) >= (projectCounts.limit)) {
console.log('LIMIT 3');
const notify = await LimitNotifyModel.findOne({ project_id });
if (notify && notify.limit3 === true) return;
const project = await ProjectModel.findById(project_id);
if (!project) return;
const owner = await UserModel.findById(project.owner);
if (!owner) return;
if (process.env.EMAIL_SERVICE) await EmailService.sendLimitEmailMax(owner.email, project.name);
await LimitNotifyModel.updateOne({ project_id: projectCounts.project_id }, { limit1: true, limit2: true, limit3: true });
} else if ((projectCounts.visits + projectCounts.events) >= (projectCounts.limit * 0.9)) {
console.log('LIMIT 2');
const notify = await LimitNotifyModel.findOne({ project_id });
if (notify && notify.limit2 === true) return;
const project = await ProjectModel.findById(project_id);
if (!project) return;
const owner = await UserModel.findById(project.owner);
if (!owner) return;
if (process.env.EMAIL_SERVICE) await EmailService.sendLimitEmail90(owner.email, project.name);
await LimitNotifyModel.updateOne({ project_id: projectCounts.project_id }, { limit1: true, limit2: true, limit3: false });
} else if ((projectCounts.visits + projectCounts.events) >= (projectCounts.limit * 0.5)) {
console.log('LIMIT 1');
const notify = await LimitNotifyModel.findOne({ project_id });
if (notify && notify.limit1 === true) return;
const project = await ProjectModel.findById(project_id);
if (!project) return;
const owner = await UserModel.findById(project.owner);
if (!owner) return;
if (process.env.EMAIL_SERVICE) await EmailService.sendLimitEmail50(owner.email, project.name);
await LimitNotifyModel.updateOne({ project_id: projectCounts.project_id }, { limit1: true, limit2: false, limit3: false });
}
}

View File

@@ -213,7 +213,7 @@ async function onLifetimeUpgradeClick() {
<span class="text-lyx-primary font-semibold text-[1.4rem]"> <span class="text-lyx-primary font-semibold text-[1.4rem]">
LIFETIME DEAL LIFETIME DEAL
</span> </span>
<span class="text-lyx-text-dark text-[.8rem]"> (Growh plan) </span> <span class="text-lyx-text-dark text-[.8rem]"> (Growth plan) </span>
</div> </div>
<div class="text-[2rem]"> 2.399,00 </div> <div class="text-[2rem]"> 2.399,00 </div>
<div> Up to 500.000 visits/events per month </div> <div> Up to 500.000 visits/events per month </div>
@@ -245,7 +245,7 @@ async function onLifetimeUpgradeClick() {
</div> </div>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<img class="h-6" :src="'/check.png'" alt="Check"> <img class="h-6" :src="'/check.png'" alt="Check">
<div> Data retention: 1 Year </div> <div> Data retention: 5 Years </div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -129,9 +129,9 @@ export default defineEventHandler(async event => {
const firstEventDate = await EventModel.findOne({ project_id: project._id }, { created_at: 1 }, { sort: { created_at: 1 } }); const firstEventDate = await EventModel.findOne({ project_id: project._id }, { created_at: 1 }, { sort: { created_at: 1 } });
const firstViewDate = await VisitModel.findOne({ project_id: project._id }, { created_at: 1 }, { sort: { created_at: 1 } }); const firstViewDate = await VisitModel.findOne({ project_id: project._id }, { created_at: 1 }, { sort: { created_at: 1 } });
if (!firstEventDate || !firstViewDate) { // if (!firstEventDate || !firstViewDate) {
return setResponseStatus(event, 400, 'Not enough data to generate report'); // return setResponseStatus(event, 400, 'Not enough data to generate report');
} // }
const avgEventsDay = () => { const avgEventsDay = () => {
const days = (Date.now() - (firstEventDate?.created_at.getTime() || 0)) / 1000 / 60 / 60 / 24; const days = (Date.now() - (firstEventDate?.created_at.getTime() || 0)) / 1000 / 60 / 60 / 24;

View File

@@ -189,7 +189,7 @@ const slidePricings: PricingCardProp[] = [
<span class="text-lyx-primary font-semibold text-[1.4rem]"> <span class="text-lyx-primary font-semibold text-[1.4rem]">
LIFETIME DEAL LIFETIME DEAL
</span> </span>
<span class="text-lyx-text-dark text-[.8rem]"> (Growh plan) </span> <span class="text-lyx-text-dark text-[.8rem]"> (Growth plan) </span>
</div> </div>
<div class="text-[2rem]"> 2.399,00 </div> <div class="text-[2rem]"> 2.399,00 </div>
<div> Up to 500.000 visits/events per month </div> <div> Up to 500.000 visits/events per month </div>
@@ -221,7 +221,7 @@ const slidePricings: PricingCardProp[] = [
</div> </div>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<img class="h-6" :src="'/check.png'" alt="Check"> <img class="h-6" :src="'/check.png'" alt="Check">
<div> Data retention: 1 Year </div> <div> Data retention: 5 Years </div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,5 +1,5 @@
// Default: 1.1 // Default: 1.01
// ((events + visits) * VALUE) > limit // ((events + visits) * VALUE) > limit
export const EVENT_LOG_LIMIT_PERCENT = 1.1; export const EVENT_LOG_LIMIT_PERCENT = 1.01;

View File

@@ -1,6 +1,8 @@
import { TransactionalEmailsApi, SendSmtpEmail } from '@getbrevo/brevo'; import { TransactionalEmailsApi, SendSmtpEmail } from '@getbrevo/brevo';
import { WELCOME_EMAIL } from './email_templates/WelcomeEmail'; import { WELCOME_EMAIL } from './email_templates/WelcomeEmail';
import { LIMIT_50_EMAIL } from './email_templates/Limit50Email'; import { LIMIT_50_EMAIL } from './email_templates/Limit50Email';
import { LIMIT_90_EMAIL } from './email_templates/Limit90Email';
import { LIMIT_MAX_EMAIL } from './email_templates/LimitMaxEmail';
class EmailService { class EmailService {
@@ -11,13 +13,51 @@ class EmailService {
this.apiInstance.setApiKey(0, apiKey); this.apiInstance.setApiKey(0, apiKey);
} }
async sendLimitEmail50(target: string) { async sendLimitEmail50(target: string, projectName: string) {
try { try {
const sendSmtpEmail = new SendSmtpEmail(); const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "Litlyx project limit 50%"; sendSmtpEmail.subject = "You've reached 50% limit on Litlyx";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "no-reply@litlyx.com" }; sendSmtpEmail.sender = { "name": "Litlyx", "email": "no-reply@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }]; sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = LIMIT_50_EMAIL;
sendSmtpEmail.htmlContent = LIMIT_50_EMAIL
.replace(/\[Project Name\]/, projectName)
.toString();
await this.apiInstance.sendTransacEmail(sendSmtpEmail);
return true;
} catch (ex) {
console.error('ERROR SENDING EMAIL', ex);
return false;
}
}
async sendLimitEmail90(target: string, projectName: string) {
try {
const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "You've reached 90% limit on Litlyx";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "no-reply@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = LIMIT_90_EMAIL
.replace(/\[Project Name\]/, projectName)
.toString();
await this.apiInstance.sendTransacEmail(sendSmtpEmail);
return true;
} catch (ex) {
console.error('ERROR SENDING EMAIL', ex);
return false;
}
}
async sendLimitEmailMax(target: string, projectName: string) {
try {
const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "You've reached your limit on Litlyx!";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "no-reply@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = LIMIT_MAX_EMAIL
.replace(/\[Project Name\]/, projectName)
.toString();
await this.apiInstance.sendTransacEmail(sendSmtpEmail); await this.apiInstance.sendTransacEmail(sendSmtpEmail);
return true; return true;
} catch (ex) { } catch (ex) {
@@ -28,9 +68,8 @@ class EmailService {
async sendWelcomeEmail(target: string) { async sendWelcomeEmail(target: string) {
try { try {
console.log('SENDING WELCOME EMAIL_EMAIL SERVICE')
const sendSmtpEmail = new SendSmtpEmail(); const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "Welcome to Litlyx"; sendSmtpEmail.subject = "Welcome to Litlyx!";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "no-reply@litlyx.com" }; sendSmtpEmail.sender = { "name": "Litlyx", "email": "no-reply@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }]; sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = WELCOME_EMAIL; sendSmtpEmail.htmlContent = WELCOME_EMAIL;

View File

@@ -25,10 +25,7 @@ export class RedisStreamService {
static async connect() { static async connect() {
console.log('RedisStreamService DEV_MODE=', process.env.DEV_MODE === 'true'); console.log('RedisStreamService DEV_MODE=', process.env.DEV_MODE === 'true');
await this.client.connect(); await this.client.connect();
setInterval(() => {
console.log('Processed:', (RedisStreamService.processed / 30).toFixed(), '/s');
RedisStreamService.processed = 0;
}, 30_000)
} }
@@ -48,6 +45,11 @@ export class RedisStreamService {
static async startReadingLoop(options: ReadingLoopOptions, processFunction: (content: Record<string, string>) => Promise<any>) { static async startReadingLoop(options: ReadingLoopOptions, processFunction: (content: Record<string, string>) => Promise<any>) {
setInterval(() => {
console.log('Processed:', (RedisStreamService.processed / 30).toFixed(), '/s');
RedisStreamService.processed = 0;
}, 30_000)
try { try {
console.log('Start reading loop'); console.log('Start reading loop');
await this.client.xGroupCreate(options.streamName, 'broker', '0', { MKSTREAM: true, }); await this.client.xGroupCreate(options.streamName, 'broker', '0', { MKSTREAM: true, });

View File

@@ -1,101 +1,31 @@
export const LIMIT_50_EMAIL = ` export const LIMIT_50_EMAIL = `<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LitLyx Limit Reached Email</title> <title>Youve reached 50% limit on Litlyx</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700&display=swap');
body {
font-family: 'Poppins', sans-serif;
background-color: #0a0a0a;
color: #ffffff;
margin: 0;
padding: 0;
}
.container {
width: 100%;
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
.header {
text-align: center;
padding: 20px 0;
}
.header h1 {
font-size: 36px;
font-weight: 700;
margin: 0;
}
.step {
margin: 20px 0;
text-align: center;
}
.step h2 {
font-size: 24px;
font-weight: 600;
margin: 0 0 10px 0;
}
.step p {
font-size: 16px;
font-weight: 300;
margin: 0 0 20px 0;
}
.button {
display: inline-block;
padding: 10px 20px;
font-size: 16px;
font-weight: 600;
color: #ffffff;
background-color: #1a73e8;
text-decoration: none;
border-radius: 5px;
}
.footer {
text-align: center;
padding: 20px 0;
font-size: 14px;
font-weight: 300;
}
</style>
</head> </head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<p>Dear User,</p>
<p>We wanted to let you know that <strong>[Project Name]</strong> on <strong>Litlyx</strong> has reached 50% of its data collection limit for this month.</p>
<p>To avoid losing precious data, please remember to monitor your usage on the <strong>Litlyx Dashboard</strong>. You can find your current usage details under <strong>Settings > Billing Tab</strong>.</p>
<p>If you need more data collection storage, you may consider upgrading your plan to get additional benefits and ensure uninterrupted data collection.</p>
<p>Feel free to reply to this email or contact us at <a href="mailto:help@litlyx.com" style="color: #FF5733; text-decoration: none;">help@litlyx.com</a> if you have any questions or need assistance.</p>
<p>Thank you for choosing Litlyx every day as your analytics tool.</p>
<p>Have a nice day!</p>
<p>Antonio,</p>
<p>CEO | Litlyx</p>
<body>
<div class="container">
<div class="header">
<h1>⚠ Limit for project ⚠</h1>
</div>
<div class="header">
<p>Hey there! We found that one of your projects is at 50% of the <strong>limit of the plan.</strong> In order to continue to log visits & events, you should upgrade the plan of your project!</p>
</div>
<div class="step" style="margin-top: 4rem;">
<h2>How can I upgrade the plan?</h2>
<p>We offer different plans, each of them follows the stage of your project, so based on the reach, you should upgrade to the most appropriate one for your web platform.<strong> It takes 1 minute to upgrade the plan!</strong> You can find everything in the "Billing" section in the left menu of your dashboard.</p>
<a href="https://dashboard.litlyx.com" class="button">Visit your dashboard</a>
</div>
<div class="step" style="margin-top: 4rem;">
<h2>We are in early phases!</h2>
<p>Want to become an early adopter? Book a demo with me! I'm Antonio & I'll guide you through all the features and benefits of LitLyx.<strong> A big discount is waiting for you❗</strong></p>
<a href="https://cal.com/litlyx/30min" class="button">Book a Demo with Me!</a>
</div>
<div class="footer">
<p>Thank you for choosing LitLyx each day to keep track of your business KPIs!</p>
<p>Made with ❤️ in Italy</p>
</div>
</div>
</body> </body>
</html> </html>
` `

View File

@@ -0,0 +1,31 @@
export const LIMIT_90_EMAIL = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Youve reached 90% limit on Litlyx</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<p>Dear User,</p>
<p>We wanted to let you know that <strong>[Project Name]</strong> on <strong>Litlyx</strong> has reached 90% of its data collection limit for this month.</p>
<p>To avoid losing precious data, please remember to monitor your usage on the <strong>Litlyx Dashboard</strong>. You can find your current usage details under <strong>Settings > Billing Tab</strong>.</p>
<p>If you need more data collection storage, you may consider upgrading your plan to get additional benefits and ensure uninterrupted data collection.</p>
<p>Feel free to reply to this email or contact us at <a href="mailto:help@litlyx.com" style="color: #FF0000; text-decoration: none;">help@litlyx.com</a> if you have any questions or need assistance.</p>
<p>Thank you for choosing Litlyx every day as your analytics tool.</p>
<p>Have a nice day!</p>
<p>Antonio,</p>
<p>CEO | Litlyx</p>
</body>
</html>
`

View File

@@ -0,0 +1,32 @@
export const LIMIT_MAX_EMAIL = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>❗️ Youve reached your limit on Litlyx!</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<p>Dear User,</p>
<p>We wanted to let you know that <strong>[Project Name]</strong> on <strong>Litlyx</strong> has reached the limit of your current plan.</p>
<p>To avoid losing precious data, please remember to monitor your usage on the <strong>Litlyx Dashboard</strong>. You can find your current usage details under <strong>Settings > Billing Tab</strong>.</p>
<p>If you need more data collection storage, you may consider upgrading your plan to get additional benefits and ensure uninterrupted data collection.</p>
<p>Feel free to reply to this email or contact us at <a href="mailto:help@litlyx.com" style="color: #D32F2F; text-decoration: none;">help@litlyx.com</a> if you have any questions or need assistance.</p>
<p>Thank you for choosing Litlyx every day as your analytics tool.</p>
<p>Have a nice day!</p>
<p>Antonio,</p>
<p>CEO | Litlyx</p>
</body>
</html>
`

View File

@@ -1,378 +1,39 @@
export const WELCOME_EMAIL = ` export const WELCOME_EMAIL = `
<!doctype html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Welcome to Litlyx!</title>
<title>Welcome Email Litlyx</title> </head>
<style media="all" type="text/css"> <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
/* -------------------------------------
GLOBAL RESETS
------------------------------------- */
body { <p>Were happy to have you onboard,</p>
font-family: Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
font-size: 16px;
line-height: 1.3;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
table { <p>At Litlyx, were committed to creating the best analytics collection experience for everybody, starting from developers.</p>
border-collapse: separate;
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
width: 100%;
}
table td { <p>Here are a few things you can do to get started tracking analytics today:</p>
font-family: Helvetica, sans-serif;
font-size: 16px;
vertical-align: top;
}
/* -------------------------------------
BODY & CONTAINER
------------------------------------- */
body { <ol>
/* background-color: #f4f5f6; */ <li><strong><a href="https://dashboard.litlyx.com" style="color: #007BFF; text-decoration: none;">Create a new project</a></strong> by just naming it</li>
background-color: #181818; <li><strong><a style="color: #0a0a0a; text-decoration: none;">Copy the universal Script</a></strong> we provide you the snippets to copy in your index.html file and start instantly to track metrics on your website or web app.</li>
margin: 0; <li><strong><a style="color: #0a0a0a; text-decoration: none;">Third Step</a></strong> Encourage engagement or interaction.</li>
padding: 0; </ol>
}
.body { <p>If you have any questions or need support, visit <a href="http://docs.litlyx.com" style="color: #007BFF;">docs.litlyx.com</a>.</p>
/* background-color: #f4f5f6; */
background-color: #181818;
width: 100%;
}
.container { <p>Feel free to reply to this email or reach out to our team at <a href="mailto:help@litlyx.com" style="color: #007BFF;">help@litlyx.com</a>. Were here to help!</p>
margin: 0 auto !important;
max-width: 600px;
padding: 0;
padding-top: 24px;
width: 600px;
}
.content { <p>Link to Discord for developer support: <a href="https://discord.com/invite/9cQykjsmWX" style="color: #007BFF;">https://discord.com/invite/9cQykjsmWX</a></p>
box-sizing: border-box;
display: block;
margin: 0 auto;
max-width: 600px;
padding: 0;
}
/* -------------------------------------
HEADER, FOOTER, MAIN
------------------------------------- */
.main { <p>Thank you for joining us, and we look forward to seeing you around.</p>
background: #f7f7f7;
border: 1px solid #eaebed;
border-radius: 16px;
width: 100%;
}
.wrapper { <p>We want to make analytics the freshest thing on the web.</p>
box-sizing: border-box;
padding: 24px;
}
.footer { <p>Antonio,</p>
clear: both; <p>CEO | Litlyx</p>
padding-top: 24px;
text-align: center;
width: 100%;
}
.footer td, </body>
.footer p,
.footer span,
.footer a {
color: #9a9ea6;
font-size: 16px;
text-align: center;
}
/* -------------------------------------
TYPOGRAPHY
------------------------------------- */
p {
font-family: Helvetica, sans-serif;
font-size: 16px;
font-weight: normal;
margin: 0;
margin-bottom: 16px;
}
a {
color: #0867ec;
text-decoration: underline;
}
/* -------------------------------------
BUTTONS
------------------------------------- */
.btn {
box-sizing: border-box;
min-width: 100% !important;
width: 100%;
}
.btn > tbody > tr > td {
padding-bottom: 16px;
}
.btn table {
width: auto;
}
.btn table td {
background-color: #ffffff;
border-radius: 4px;
text-align: center;
}
.btn a {
background-color: #ffffff;
border: solid 2px #0867ec;
border-radius: 4px;
box-sizing: border-box;
color: #0867ec;
cursor: pointer;
display: inline-block;
font-size: 16px;
font-weight: bold;
margin: 0;
padding: 12px 24px;
text-decoration: none;
text-transform: capitalize;
}
.btn-primary table td {
background-color: #0867ec;
}
.btn-primary a {
background-color: #0867ec;
border-color: #0867ec;
color: #ffffff;
}
@media all {
.btn-primary table td:hover {
background-color: #006aff !important;
}
.btn-primary a:hover {
background-color: #006aff !important;
border-color: #006aff !important;
}
}
/* -------------------------------------
OTHER STYLES THAT MIGHT BE USEFUL
------------------------------------- */
.last {
margin-bottom: 0;
}
.first {
margin-top: 0;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
.align-left {
text-align: left;
}
.text-link {
color: #0867ec !important;
text-decoration: underline !important;
}
.clear {
clear: both;
}
.mt0 {
margin-top: 0;
}
.mb0 {
margin-bottom: 0;
}
.preheader {
color: transparent;
display: none;
height: 0;
max-height: 0;
max-width: 0;
opacity: 0;
overflow: hidden;
mso-hide: all;
visibility: hidden;
width: 0;
}
.powered-by a {
text-decoration: none;
}
/* -------------------------------------
RESPONSIVE AND MOBILE FRIENDLY STYLES
------------------------------------- */
@media only screen and (max-width: 640px) {
.main p,
.main td,
.main span {
font-size: 16px !important;
}
.wrapper {
padding: 8px !important;
}
.content {
padding: 0 !important;
}
.container {
padding: 0 !important;
padding-top: 8px !important;
width: 100% !important;
}
.main {
border-left-width: 0 !important;
border-radius: 0 !important;
border-right-width: 0 !important;
}
.btn table {
max-width: 100% !important;
width: 100% !important;
}
.btn a {
font-size: 16px !important;
max-width: 100% !important;
width: 100% !important;
}
}
/* -------------------------------------
PRESERVE THESE STYLES IN THE HEAD
------------------------------------- */
@media all {
.ExternalClass {
width: 100%;
}
.ExternalClass,
.ExternalClass p,
.ExternalClass span,
.ExternalClass font,
.ExternalClass td,
.ExternalClass div {
line-height: 100%;
}
.apple-link a {
color: inherit !important;
font-family: inherit !important;
font-size: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
text-decoration: none !important;
}
#MessageViewBody a {
color: inherit;
text-decoration: none;
font-size: inherit;
font-family: inherit;
font-weight: inherit;
line-height: inherit;
}
}
</style>
</head>
<body>
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body">
<tr>
<td>&nbsp;</td>
<td class="container">
<div class="content">
<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader">This is preheader text. Some clients will show this text as a preview.</span>
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="main">
<!-- START MAIN CONTENT AREA -->
<tr>
<td class="wrapper">
<p>Hi 👋 Welcome to <strong>Litlyx!</strong></p>
<p>We value your time so we will keep this simple.
We are happy to have you onboard! 🎊</p>
<p>We leave you a super fast video tutorial, just 1 minute where our CEO, Antonio, explain the very basics of Litlyx and will guide you to start logging analytics today for your website or web app!</p>
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
<tbody>
<tr>
<td align="left">
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td> <a href="https://youtube.com" target="_blank">Super Fast Video Tutorial</a> </td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<p>Good luck! Enjoy your KPIs in real-time. Start now visiting the dashboard!</p>
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
<tbody>
<tr>
<td align="left">
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td> <a href="https://dashboard.litlyx.com" target="_blank">Go to Litlyx Dashboard</a> </td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<p>If you have any question, you can find us at: help@litlyx.com, we will respond in less than a work day.</p>
</td>
</tr>
<!-- END MAIN CONTENT AREA -->
</table>
<!-- START FOOTER -->
<div class="footer">
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="content-block">
<span class="apple-link">&copy; 2024 Litlyx All right reserved. Made with ❤ in Italy </span>
</td>
</tr>
</table>
</div>
<!-- END FOOTER -->
<!-- END CENTERED WHITE CONTAINER --></div>
</td>
<td>&nbsp;</td>
</tr>
</table>
</body>
</html> </html>
` `

View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Youve reached 50% limit on Litlyx</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<!-- Email Content -->
<h2 style="color: #FF5733;">Youve reached 50% limit on Litlyx</h2>
<p>Dear User,</p>
<p>We wanted to let you know that <strong>[Project Name]</strong> on <strong>Litlyx</strong> has reached 50% of its data collection limit for this month.</p>
<p>To avoid losing precious data, please remember to monitor your usage on the <strong>Litlyx Dashboard</strong>. You can find your current usage details under <strong>Settings > Billing Tab</strong>.</p>
<p>If you need more data collection storage, you may consider upgrading your plan to get additional benefits and ensure uninterrupted data collection.</p>
<p>Feel free to reply to this email or contact us at <a href="mailto:help@litlyx.com" style="color: #FF5733; text-decoration: none;">help@litlyx.com</a> if you have any questions or need assistance.</p>
<p>Thank you for choosing Litlyx every day as your analytics tool.</p>
<p>Have a nice day!</p>
<p>Antonio,</p>
<p>CEO | Litlyx</p>
</body>
</html>

View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Youve reached 90% limit on Litlyx</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<!-- Email Content -->
<h2 style="color: #FF0000;">Youve reached 90% limit on Litlyx</h2>
<p>Dear User,</p>
<p>We wanted to let you know that <strong>[Project Name]</strong> on <strong>Litlyx</strong> has reached 90% of its data collection limit for this month.</p>
<p>To avoid losing precious data, please remember to monitor your usage on the <strong>Litlyx Dashboard</strong>. You can find your current usage details under <strong>Settings > Billing Tab</strong>.</p>
<p>If you need more data collection storage, you may consider upgrading your plan to get additional benefits and ensure uninterrupted data collection.</p>
<p>Feel free to reply to this email or contact us at <a href="mailto:help@litlyx.com" style="color: #FF0000; text-decoration: none;">help@litlyx.com</a> if you have any questions or need assistance.</p>
<p>Thank you for choosing Litlyx every day as your analytics tool.</p>
<p>Have a nice day!</p>
<p>Antonio,</p>
<p>CEO | Litlyx</p>
</body>
</html>

View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>❗️ Youve reached your limit on Litlyx!</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<!-- Email Content -->
<h2 style="color: #D32F2F;">❗️ Youve reached your limit on Litlyx!</h2>
<p>Dear User,</p>
<p>We wanted to let you know that <strong>[Project Name]</strong> on <strong>Litlyx</strong> has reached the limit of your current plan.</p>
<p>To avoid losing precious data, please remember to monitor your usage on the <strong>Litlyx Dashboard</strong>. You can find your current usage details under <strong>Settings > Billing Tab</strong>.</p>
<p>If you need more data collection storage, you may consider upgrading your plan to get additional benefits and ensure uninterrupted data collection.</p>
<p>Feel free to reply to this email or contact us at <a href="mailto:help@litlyx.com" style="color: #D32F2F; text-decoration: none;">help@litlyx.com</a> if you have any questions or need assistance.</p>
<p>Thank you for choosing Litlyx every day as your analytics tool.</p>
<p>Have a nice day!</p>
<p>Antonio,</p>
<p>CEO | Litlyx</p>
</body>
</html>

View File

@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome to Litlyx!</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<!-- Subject -->
<h2 style="color: #007BFF;">Welcome to Litlyx!</h2>
<p>Were happy to have you onboard,</p>
<p>At Litlyx, were committed to creating the best analytics collection experience for everybody, starting from developers.</p>
<p>Here are a few things you can do to get started tracking analytics today:</p>
<ol>
<li><strong><a href="https://dashboard.litlyx.com" style="color: #007BFF; text-decoration: none;">Create a new project</a></strong> by just naming it</li>
<li><strong><a style="color: #0a0a0a; text-decoration: none;">Copy the universal Script</a></strong> we provide you the snippets to copy in your index.html file and start instantly to track metrics on your website or web app.</li>
<li><strong><a style="color: #0a0a0a; text-decoration: none;">Third Step</a></strong> Encourage engagement or interaction.</li>
</ol>
<p>If you have any questions or need support, visit <a href="http://docs.litlyx.com" style="color: #007BFF;">docs.litlyx.com</a>.</p>
<p>Feel free to reply to this email or reach out to our team at <a href="mailto:help@litlyx.com" style="color: #007BFF;">help@litlyx.com</a>. Were here to help!</p>
<p>Link to Discord for developer support: <a href="https://discord.com/invite/9cQykjsmWX" style="color: #007BFF;">https://discord.com/invite/9cQykjsmWX</a></p>
<p>Thank you for joining us, and we look forward to seeing you around.</p>
<p>We want to make analytics the freshest thing on the web.</p>
<p>Antonio,</p>
<p>CEO | Litlyx</p>
</body>
</html>