backend-manager 5.11.7 → 5.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/ai-library.md +3 -1
- package/docs/email-system.md +4 -2
- package/docs/usage-rate-limiting.md +2 -0
- package/package.json +1 -1
- package/src/manager/functions/core/actions/api/admin/send-email.js +0 -8
- package/src/manager/helpers/usage.js +9 -2
- package/src/manager/libraries/ai/providers/test.js +15 -1
- package/src/manager/libraries/email/data/disposable-domains.json +342 -1
- package/src/manager/libraries/email/generators/lib/templates/plain.js +1 -2
- package/src/manager/libraries/email/prepare.js +3 -12
- package/src/manager/routes/user/signup/post.js +10 -28
- package/src/test/fixtures/firebase-project/.temp/newsletter/run-2026-08-05T01-21-40/metadata.json +14 -0
- package/src/test/fixtures/firebase-project/.temp/newsletter/run-2026-08-05T01-21-40/newsletter.html +486 -0
- package/src/test/fixtures/firebase-project/.temp/newsletter/run-2026-08-05T01-21-40/newsletter.md +41 -0
- package/src/test/fixtures/firebase-project/.temp/newsletter/run-2026-08-05T01-21-40/newsletter.mjml +97 -0
- package/src/test/fixtures/firebase-project/.temp/newsletter/run-2026-08-05T01-21-40/structure.json +42 -0
- package/src/test/fixtures/firebase-project/.temp/newsletter/run-2026-08-05T01-21-40/summary.md +1 -0
- package/src/test/fixtures/firebase-project/.temp/test-mode.json +1 -1
- package/src/test/fixtures/firebase-project/database-debug.log +8 -8
- package/src/test/fixtures/firebase-project/firestore-debug.log +61 -55
- package/src/test/fixtures/firebase-project/pubsub-debug.log +3 -3
- package/test/helpers/ai-test-provider.js +24 -0
- package/test/helpers/usage-limits.js +85 -0
|
@@ -32,8 +32,7 @@ function build({ data }) {
|
|
|
32
32
|
|
|
33
33
|
// Signoff
|
|
34
34
|
const signoffGreeting = content.signoff || 'Best';
|
|
35
|
-
const signoffName = signoffData.name
|
|
36
|
-
|| (signoffData.type === 'personal' ? 'Ian Wiedenman, CEO' : `The ${brandName} Team`);
|
|
35
|
+
const signoffName = signoffData.name || `The ${brandName} Team`;
|
|
37
36
|
|
|
38
37
|
// Hidden tags
|
|
39
38
|
const hiddenAsm = `<div style="display:none;max-height:0;overflow:hidden;mso-hide:all;"><a href="<%asm_group_unsubscribe_raw_url%>">unsubscribe</a><a href="<%asm_preferences_raw_url%>">preferences</a></div>`;
|
|
@@ -100,23 +100,14 @@ function renderContent({ content, html }, utmOptions) {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
|
-
* Build signoff defaults.
|
|
103
|
+
* Build signoff defaults. Personal signoffs render only with caller-provided
|
|
104
|
+
* details (name/image/url) — there are no built-in personal defaults.
|
|
104
105
|
*
|
|
105
106
|
* @param {object} [signoff] - Caller-provided signoff (or empty)
|
|
106
107
|
* @returns {object} Complete signoff object
|
|
107
108
|
*/
|
|
108
109
|
function resolveSignoff(signoff) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (resolved.type === 'personal') {
|
|
112
|
-
resolved.image = resolved.image
|
|
113
|
-
|| 'https://cdn.itwcreativeworks.com/assets/ian-wiedenman/images/website/ian-wiedenman-headshot-2021-color-1024x1024.jpg';
|
|
114
|
-
resolved.name = resolved.name || 'Ian Wiedenman, CEO';
|
|
115
|
-
resolved.url = resolved.url || 'https://ianwiedenman.com';
|
|
116
|
-
resolved.urlText = resolved.urlText || '@ianwieds';
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return resolved;
|
|
110
|
+
return { type: 'team', ...signoff };
|
|
120
111
|
}
|
|
121
112
|
|
|
122
113
|
/**
|
|
@@ -414,24 +414,18 @@ function sendWelcomeEmail(assistant, uid, firstName) {
|
|
|
414
414
|
copy: false,
|
|
415
415
|
data: {
|
|
416
416
|
email: {
|
|
417
|
-
preview: `Welcome aboard!
|
|
417
|
+
preview: `Welcome aboard! We're here to ensure your journey with ${Manager.config.brand.name} gets off to a great start.`,
|
|
418
418
|
},
|
|
419
419
|
content: {
|
|
420
420
|
title: `Welcome to ${Manager.config.brand.name}!`,
|
|
421
421
|
message: `${greeting} aboard!
|
|
422
422
|
|
|
423
|
-
|
|
423
|
+
We're thrilled to have you with us at **${Manager.config.brand.name}**. Your journey begins today, and we are committed to supporting you every step of the way.
|
|
424
424
|
|
|
425
425
|
We are dedicated to ensuring your experience is exceptional. Feel free to reply directly to this email with any questions you may have.
|
|
426
426
|
|
|
427
427
|
Thank you for choosing **${Manager.config.brand.name}**. Here's to new beginnings!`,
|
|
428
428
|
},
|
|
429
|
-
signoff: {
|
|
430
|
-
type: 'personal',
|
|
431
|
-
name: 'Ian Wiedenman, CEO',
|
|
432
|
-
url: 'https://ianwiedenman.com',
|
|
433
|
-
urlText: '@ianwieds',
|
|
434
|
-
},
|
|
435
429
|
},
|
|
436
430
|
})
|
|
437
431
|
.then((result) => {
|
|
@@ -463,8 +457,8 @@ function sendDiscountNudgeEmail(assistant, uid, firstName) {
|
|
|
463
457
|
const mailer = Manager.Email(assistant);
|
|
464
458
|
const greeting = firstName ? `Hey ${firstName}` : 'Hey there';
|
|
465
459
|
const subject = firstName
|
|
466
|
-
? `${firstName},
|
|
467
|
-
: `
|
|
460
|
+
? `${firstName}, we've got something for you 🎁`
|
|
461
|
+
: `We've got something for you 🎁`;
|
|
468
462
|
|
|
469
463
|
return mailer.send({
|
|
470
464
|
to: uid,
|
|
@@ -476,25 +470,19 @@ function sendDiscountNudgeEmail(assistant, uid, firstName) {
|
|
|
476
470
|
sendAt: moment().add(24, 'hours').unix(),
|
|
477
471
|
data: {
|
|
478
472
|
email: {
|
|
479
|
-
preview: `Just checking in from ${Manager.config.brand.name} — and
|
|
473
|
+
preview: `Just checking in from ${Manager.config.brand.name} — and we've got a little thank-you for you.`,
|
|
480
474
|
},
|
|
481
475
|
content: {
|
|
482
476
|
title: `How's it going?`,
|
|
483
477
|
message: `${greeting},
|
|
484
478
|
|
|
485
|
-
It's
|
|
479
|
+
It's the team at **${Manager.config.brand.name}**.
|
|
486
480
|
|
|
487
|
-
As a thank-you for giving us a try,
|
|
481
|
+
As a thank-you for giving us a try, we'd love to send you a code for a **premium upgrade**.
|
|
488
482
|
|
|
489
|
-
**Just reply to this email** and
|
|
483
|
+
**Just reply to this email** and we'll get one over to you.
|
|
490
484
|
|
|
491
|
-
|
|
492
|
-
},
|
|
493
|
-
signoff: {
|
|
494
|
-
type: 'personal',
|
|
495
|
-
name: 'Ian Wiedenman, CEO',
|
|
496
|
-
url: 'https://ianwiedenman.com',
|
|
497
|
-
urlText: '@ianwieds',
|
|
485
|
+
We read every reply and we're looking forward to hearing from you!`,
|
|
498
486
|
},
|
|
499
487
|
},
|
|
500
488
|
})
|
|
@@ -528,7 +516,7 @@ function sendCheckupEmail(assistant, uid, firstName) {
|
|
|
528
516
|
title: `How's everything going?`,
|
|
529
517
|
message: `${greeting},
|
|
530
518
|
|
|
531
|
-
It's
|
|
519
|
+
It's the team at **${Manager.config.brand.name}** again. Just checking in to see how things are going for you.
|
|
532
520
|
|
|
533
521
|
Have you had a chance to explore all our features? Any questions or feedback for us?
|
|
534
522
|
|
|
@@ -536,12 +524,6 @@ We're always here to help, so don't hesitate to reach out. Just reply to this em
|
|
|
536
524
|
|
|
537
525
|
Thank you for choosing **${Manager.config.brand.name}**. Here's to new beginnings!`,
|
|
538
526
|
},
|
|
539
|
-
signoff: {
|
|
540
|
-
type: 'personal',
|
|
541
|
-
name: 'Ian Wiedenman, CEO',
|
|
542
|
-
url: 'https://ianwiedenman.com',
|
|
543
|
-
urlText: '@ianwieds',
|
|
544
|
-
},
|
|
545
527
|
},
|
|
546
528
|
})
|
|
547
529
|
.then((result) => {
|
package/src/test/fixtures/firebase-project/.temp/newsletter/run-2026-08-05T01-21-40/newsletter.html
ADDED
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="und" dir="auto" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
|
3
|
+
<head>
|
|
4
|
+
<title>Identity is the new growth lever</title>
|
|
5
|
+
<!--[if !mso]><!-->
|
|
6
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
7
|
+
<!--<![endif]-->
|
|
8
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
9
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
10
|
+
<style type="text/css">
|
|
11
|
+
#outlook a { padding:0; }
|
|
12
|
+
body { margin:0;padding:0;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%; }
|
|
13
|
+
table, td { border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt; }
|
|
14
|
+
img { border:0;height:auto;line-height:100%; outline:none;text-decoration:none;-ms-interpolation-mode:bicubic; }
|
|
15
|
+
p { display:block;margin:13px 0; }
|
|
16
|
+
</style>
|
|
17
|
+
<!--[if mso]>
|
|
18
|
+
<noscript>
|
|
19
|
+
<xml>
|
|
20
|
+
<o:OfficeDocumentSettings>
|
|
21
|
+
<o:AllowPNG/>
|
|
22
|
+
<o:PixelsPerInch>96</o:PixelsPerInch>
|
|
23
|
+
</o:OfficeDocumentSettings>
|
|
24
|
+
</xml>
|
|
25
|
+
</noscript>
|
|
26
|
+
<![endif]-->
|
|
27
|
+
<!--[if lte mso 11]>
|
|
28
|
+
<style type="text/css">
|
|
29
|
+
.mj-outlook-group-fix { width:100% !important; }
|
|
30
|
+
</style>
|
|
31
|
+
<![endif]-->
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
<style type="text/css">
|
|
35
|
+
@media only screen and (min-width:480px) {
|
|
36
|
+
.mj-column-per-100 { width:100% !important; max-width: 100%; }
|
|
37
|
+
}
|
|
38
|
+
</style>
|
|
39
|
+
<style media="screen and (min-width:480px)">
|
|
40
|
+
.moz-text-html .mj-column-per-100 { width:100% !important; max-width: 100%; }
|
|
41
|
+
</style>
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
<style type="text/css">
|
|
48
|
+
h1, h2, h3 { color: #1E1E2A; margin: 0 0 12px; }
|
|
49
|
+
h2 { font-size: 22px; line-height: 1.3; }
|
|
50
|
+
a { color: #5B5BFF; }
|
|
51
|
+
p { margin: 0 0 12px; }
|
|
52
|
+
</style>
|
|
53
|
+
|
|
54
|
+
</head>
|
|
55
|
+
|
|
56
|
+
<body style="word-spacing:normal;background-color:#F6F7FB;">
|
|
57
|
+
|
|
58
|
+
<div style="display:none;font-size:1px;color:#ffffff;line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;">Three platform shifts to lock in this week.</div>
|
|
59
|
+
|
|
60
|
+
<div
|
|
61
|
+
aria-label="Identity is the new growth lever" aria-roledescription="email" role="article" lang="und" dir="auto" style="word-spacing:normal;background-color:#F6F7FB;"
|
|
62
|
+
>
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
<!--[if mso | IE]><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]-->
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
<div style="background:#ffffff;background-color:#ffffff;margin:0px auto;max-width:600px;">
|
|
69
|
+
|
|
70
|
+
<table
|
|
71
|
+
align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#ffffff;background-color:#ffffff;width:100%;"
|
|
72
|
+
>
|
|
73
|
+
<tbody>
|
|
74
|
+
<tr>
|
|
75
|
+
<td
|
|
76
|
+
style="direction:ltr;font-size:0px;padding:32px 32px 16px 32px;text-align:center;"
|
|
77
|
+
>
|
|
78
|
+
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:536px;" ><![endif]-->
|
|
79
|
+
|
|
80
|
+
<div
|
|
81
|
+
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%;"
|
|
82
|
+
>
|
|
83
|
+
|
|
84
|
+
<table
|
|
85
|
+
border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"
|
|
86
|
+
>
|
|
87
|
+
<tbody>
|
|
88
|
+
|
|
89
|
+
<tr>
|
|
90
|
+
<td
|
|
91
|
+
align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;"
|
|
92
|
+
>
|
|
93
|
+
|
|
94
|
+
<div
|
|
95
|
+
style="font-family:Inter, system-ui, sans-serif;font-size:20px;font-weight:700;line-height:1.6;text-align:left;color:#5B5BFF;"
|
|
96
|
+
><a href="https://example.com/?utm_source=backend_manager&utm_medium=email&utm_campaign=fixture_clean&utm_content=marketing" style="color: #5B5BFF; text-decoration: none;">BEM Fixture</a></div>
|
|
97
|
+
|
|
98
|
+
</td>
|
|
99
|
+
</tr>
|
|
100
|
+
|
|
101
|
+
</tbody>
|
|
102
|
+
</table>
|
|
103
|
+
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<!--[if mso | IE]></td></tr></table><![endif]-->
|
|
107
|
+
</td>
|
|
108
|
+
</tr>
|
|
109
|
+
</tbody>
|
|
110
|
+
</table>
|
|
111
|
+
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
<!--[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]-->
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
<div style="background:#ffffff;background-color:#ffffff;margin:0px auto;max-width:600px;">
|
|
119
|
+
|
|
120
|
+
<table
|
|
121
|
+
align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#ffffff;background-color:#ffffff;width:100%;"
|
|
122
|
+
>
|
|
123
|
+
<tbody>
|
|
124
|
+
<tr>
|
|
125
|
+
<td
|
|
126
|
+
style="direction:ltr;font-size:0px;padding:0 32px 24px 32px;text-align:center;"
|
|
127
|
+
>
|
|
128
|
+
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:536px;" ><![endif]-->
|
|
129
|
+
|
|
130
|
+
<div
|
|
131
|
+
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%;"
|
|
132
|
+
>
|
|
133
|
+
|
|
134
|
+
<table
|
|
135
|
+
border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"
|
|
136
|
+
>
|
|
137
|
+
<tbody>
|
|
138
|
+
|
|
139
|
+
<tr>
|
|
140
|
+
<td
|
|
141
|
+
align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;"
|
|
142
|
+
>
|
|
143
|
+
|
|
144
|
+
<div
|
|
145
|
+
style="font-family:Inter, system-ui, sans-serif;font-size:16px;line-height:1.6;text-align:left;color:#1E1E2A;"
|
|
146
|
+
><p>Identity matters because trust is the new growth lever. Teams that handle this well will spend less time cleaning up later.</p></div>
|
|
147
|
+
|
|
148
|
+
</td>
|
|
149
|
+
</tr>
|
|
150
|
+
|
|
151
|
+
</tbody>
|
|
152
|
+
</table>
|
|
153
|
+
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<!--[if mso | IE]></td></tr></table><![endif]-->
|
|
157
|
+
</td>
|
|
158
|
+
</tr>
|
|
159
|
+
</tbody>
|
|
160
|
+
</table>
|
|
161
|
+
|
|
162
|
+
</div>
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
<!--[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]-->
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
<div style="background:#ffffff;background-color:#ffffff;margin:0px auto;max-width:600px;">
|
|
169
|
+
|
|
170
|
+
<table
|
|
171
|
+
align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#ffffff;background-color:#ffffff;width:100%;"
|
|
172
|
+
>
|
|
173
|
+
<tbody>
|
|
174
|
+
<tr>
|
|
175
|
+
<td
|
|
176
|
+
style="direction:ltr;font-size:0px;padding:24px 32px 8px 32px;text-align:center;"
|
|
177
|
+
>
|
|
178
|
+
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:536px;" ><![endif]-->
|
|
179
|
+
|
|
180
|
+
<div
|
|
181
|
+
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%;"
|
|
182
|
+
>
|
|
183
|
+
|
|
184
|
+
<table
|
|
185
|
+
border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"
|
|
186
|
+
>
|
|
187
|
+
<tbody>
|
|
188
|
+
|
|
189
|
+
<tr>
|
|
190
|
+
<td
|
|
191
|
+
align="left" style="font-size:0px;padding:20px 0 0 0;word-break:break-word;"
|
|
192
|
+
>
|
|
193
|
+
|
|
194
|
+
<div
|
|
195
|
+
style="font-family:Inter, system-ui, sans-serif;font-size:16px;line-height:1.6;text-align:left;color:#1E1E2A;"
|
|
196
|
+
><h2>LinkedIn ships verified-profile gates for business accounts</h2>
|
|
197
|
+
<p>LinkedIn now requires verified identity attestations on any business profile claiming more than 500 followers. Accounts with documented attribution histories sail through verification in under twelve hours. The practical implication is to lock down your attribution log this week, not next.</p></div>
|
|
198
|
+
|
|
199
|
+
</td>
|
|
200
|
+
</tr>
|
|
201
|
+
|
|
202
|
+
</tbody>
|
|
203
|
+
</table>
|
|
204
|
+
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
<!--[if mso | IE]></td></tr></table><![endif]-->
|
|
208
|
+
</td>
|
|
209
|
+
</tr>
|
|
210
|
+
</tbody>
|
|
211
|
+
</table>
|
|
212
|
+
|
|
213
|
+
</div>
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
<!--[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]-->
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
<div style="background:#ffffff;background-color:#ffffff;margin:0px auto;max-width:600px;">
|
|
220
|
+
|
|
221
|
+
<table
|
|
222
|
+
align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#ffffff;background-color:#ffffff;width:100%;"
|
|
223
|
+
>
|
|
224
|
+
<tbody>
|
|
225
|
+
<tr>
|
|
226
|
+
<td
|
|
227
|
+
style="direction:ltr;font-size:0px;padding:24px 32px 8px 32px;text-align:center;"
|
|
228
|
+
>
|
|
229
|
+
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:536px;" ><![endif]-->
|
|
230
|
+
|
|
231
|
+
<div
|
|
232
|
+
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%;"
|
|
233
|
+
>
|
|
234
|
+
|
|
235
|
+
<table
|
|
236
|
+
border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"
|
|
237
|
+
>
|
|
238
|
+
<tbody>
|
|
239
|
+
|
|
240
|
+
<tr>
|
|
241
|
+
<td
|
|
242
|
+
align="left" style="font-size:0px;padding:20px 0 0 0;word-break:break-word;"
|
|
243
|
+
>
|
|
244
|
+
|
|
245
|
+
<div
|
|
246
|
+
style="font-family:Inter, system-ui, sans-serif;font-size:16px;line-height:1.6;text-align:left;color:#1E1E2A;"
|
|
247
|
+
><h2>Documentation is the new operator moat</h2>
|
|
248
|
+
<p>Operator playbooks are now the difference between an account that recovers from a flag and one that gets permanently restricted. Teams running documented processes recover in days. The ones without burn weeks negotiating with support queues.</p></div>
|
|
249
|
+
|
|
250
|
+
</td>
|
|
251
|
+
</tr>
|
|
252
|
+
|
|
253
|
+
</tbody>
|
|
254
|
+
</table>
|
|
255
|
+
|
|
256
|
+
</div>
|
|
257
|
+
|
|
258
|
+
<!--[if mso | IE]></td></tr></table><![endif]-->
|
|
259
|
+
</td>
|
|
260
|
+
</tr>
|
|
261
|
+
</tbody>
|
|
262
|
+
</table>
|
|
263
|
+
|
|
264
|
+
</div>
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
<!--[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]-->
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
<div style="background:#ffffff;background-color:#ffffff;margin:0px auto;max-width:600px;">
|
|
271
|
+
|
|
272
|
+
<table
|
|
273
|
+
align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#ffffff;background-color:#ffffff;width:100%;"
|
|
274
|
+
>
|
|
275
|
+
<tbody>
|
|
276
|
+
<tr>
|
|
277
|
+
<td
|
|
278
|
+
style="direction:ltr;font-size:0px;padding:24px 32px 8px 32px;text-align:center;"
|
|
279
|
+
>
|
|
280
|
+
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:536px;" ><![endif]-->
|
|
281
|
+
|
|
282
|
+
<div
|
|
283
|
+
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%;"
|
|
284
|
+
>
|
|
285
|
+
|
|
286
|
+
<table
|
|
287
|
+
border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"
|
|
288
|
+
>
|
|
289
|
+
<tbody>
|
|
290
|
+
|
|
291
|
+
<tr>
|
|
292
|
+
<td
|
|
293
|
+
align="left" style="font-size:0px;padding:20px 0 0 0;word-break:break-word;"
|
|
294
|
+
>
|
|
295
|
+
|
|
296
|
+
<div
|
|
297
|
+
style="font-family:Inter, system-ui, sans-serif;font-size:16px;line-height:1.6;text-align:left;color:#1E1E2A;"
|
|
298
|
+
><h2>YouTube tests creator-attribution metadata on uploads</h2>
|
|
299
|
+
<p>A subset of channels saw a new upload checkbox this week asking whether content was assisted by automation. The checkbox is optional today. Reading the room: it will not stay optional. Creators with clear internal workflows will adapt in an afternoon.</p></div>
|
|
300
|
+
|
|
301
|
+
</td>
|
|
302
|
+
</tr>
|
|
303
|
+
|
|
304
|
+
</tbody>
|
|
305
|
+
</table>
|
|
306
|
+
|
|
307
|
+
</div>
|
|
308
|
+
|
|
309
|
+
<!--[if mso | IE]></td></tr></table><![endif]-->
|
|
310
|
+
</td>
|
|
311
|
+
</tr>
|
|
312
|
+
</tbody>
|
|
313
|
+
</table>
|
|
314
|
+
|
|
315
|
+
</div>
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
<!--[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]-->
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
<div style="background:#ffffff;background-color:#ffffff;margin:0px auto;max-width:600px;">
|
|
322
|
+
|
|
323
|
+
<table
|
|
324
|
+
align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#ffffff;background-color:#ffffff;width:100%;"
|
|
325
|
+
>
|
|
326
|
+
<tbody>
|
|
327
|
+
<tr>
|
|
328
|
+
<td
|
|
329
|
+
style="direction:ltr;font-size:0px;padding:32px 32px 8px 32px;text-align:center;"
|
|
330
|
+
>
|
|
331
|
+
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:536px;" ><![endif]-->
|
|
332
|
+
|
|
333
|
+
<div
|
|
334
|
+
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%;"
|
|
335
|
+
>
|
|
336
|
+
|
|
337
|
+
<table
|
|
338
|
+
border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"
|
|
339
|
+
>
|
|
340
|
+
<tbody>
|
|
341
|
+
|
|
342
|
+
<tr>
|
|
343
|
+
<td
|
|
344
|
+
align="left" style="font-size:0px;padding:0;word-break:break-word;"
|
|
345
|
+
>
|
|
346
|
+
|
|
347
|
+
<div
|
|
348
|
+
style="font-family:Inter, system-ui, sans-serif;font-size:16px;line-height:1.6;text-align:left;color:#1E1E2A;"
|
|
349
|
+
><div style="color: #1E1E2A;">Best,<br/>The Somiibo Team</div></div>
|
|
350
|
+
|
|
351
|
+
</td>
|
|
352
|
+
</tr>
|
|
353
|
+
|
|
354
|
+
</tbody>
|
|
355
|
+
</table>
|
|
356
|
+
|
|
357
|
+
</div>
|
|
358
|
+
|
|
359
|
+
<!--[if mso | IE]></td></tr></table><![endif]-->
|
|
360
|
+
</td>
|
|
361
|
+
</tr>
|
|
362
|
+
</tbody>
|
|
363
|
+
</table>
|
|
364
|
+
|
|
365
|
+
</div>
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
<!--[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]-->
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
<div style="background:#ffffff;background-color:#ffffff;margin:0px auto;max-width:600px;">
|
|
372
|
+
|
|
373
|
+
<table
|
|
374
|
+
align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#ffffff;background-color:#ffffff;width:100%;"
|
|
375
|
+
>
|
|
376
|
+
<tbody>
|
|
377
|
+
<tr>
|
|
378
|
+
<td
|
|
379
|
+
style="direction:ltr;font-size:0px;padding:24px 32px 24px 32px;text-align:center;"
|
|
380
|
+
>
|
|
381
|
+
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:536px;" ><![endif]-->
|
|
382
|
+
|
|
383
|
+
<div
|
|
384
|
+
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%;"
|
|
385
|
+
>
|
|
386
|
+
|
|
387
|
+
<table
|
|
388
|
+
border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"
|
|
389
|
+
>
|
|
390
|
+
<tbody>
|
|
391
|
+
|
|
392
|
+
<tr>
|
|
393
|
+
<td
|
|
394
|
+
align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;"
|
|
395
|
+
>
|
|
396
|
+
|
|
397
|
+
<div
|
|
398
|
+
style="font-family:Inter, system-ui, sans-serif;font-size:12px;line-height:1.5;text-align:left;color:#1E1E2A;"
|
|
399
|
+
><div style="font-size: 11px; letter-spacing: 4px; text-transform: uppercase; font-weight: 700; color: #5B5BFF; margin-bottom: 12px;">Sources & data</div>
|
|
400
|
+
|
|
401
|
+
<div style="margin-bottom: 8px;">
|
|
402
|
+
<span style="font-weight: 600; color: #5B5BFF;">[1]</span>
|
|
403
|
+
<span style="color: #1E1E2A;"> LinkedIn flagged 12,000 impersonation attempts in the verified-profile beta.</span>
|
|
404
|
+
<span style="color: #888888;"> — Reported by LinkedIn product team, May 2026</span>
|
|
405
|
+
</div>
|
|
406
|
+
<div style="margin-bottom: 8px;">
|
|
407
|
+
<span style="font-weight: 600; color: #5B5BFF;">[2]</span>
|
|
408
|
+
<span style="color: #1E1E2A;"> Operator playbook adoption up 38% week-over-week in Q2.</span>
|
|
409
|
+
<span style="color: #888888;"> — Per platform analytics, May 2026</span>
|
|
410
|
+
</div></div>
|
|
411
|
+
|
|
412
|
+
</td>
|
|
413
|
+
</tr>
|
|
414
|
+
|
|
415
|
+
</tbody>
|
|
416
|
+
</table>
|
|
417
|
+
|
|
418
|
+
</div>
|
|
419
|
+
|
|
420
|
+
<!--[if mso | IE]></td></tr></table><![endif]-->
|
|
421
|
+
</td>
|
|
422
|
+
</tr>
|
|
423
|
+
</tbody>
|
|
424
|
+
</table>
|
|
425
|
+
|
|
426
|
+
</div>
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" bgcolor="transparent" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
<div style="background:transparent;background-color:transparent;margin:0px auto;max-width:600px;">
|
|
433
|
+
|
|
434
|
+
<table
|
|
435
|
+
align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:transparent;background-color:transparent;width:100%;"
|
|
436
|
+
>
|
|
437
|
+
<tbody>
|
|
438
|
+
<tr>
|
|
439
|
+
<td
|
|
440
|
+
style="direction:ltr;font-size:0px;padding:16px 32px 32px 32px;text-align:center;"
|
|
441
|
+
>
|
|
442
|
+
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:536px;" ><![endif]-->
|
|
443
|
+
|
|
444
|
+
<div
|
|
445
|
+
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%;"
|
|
446
|
+
>
|
|
447
|
+
|
|
448
|
+
<table
|
|
449
|
+
border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"
|
|
450
|
+
>
|
|
451
|
+
<tbody>
|
|
452
|
+
|
|
453
|
+
<tr>
|
|
454
|
+
<td
|
|
455
|
+
align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;"
|
|
456
|
+
>
|
|
457
|
+
|
|
458
|
+
<div
|
|
459
|
+
style="font-family:Inter, system-ui, sans-serif;font-size:12px;line-height:1.6;text-align:center;color:#888888;"
|
|
460
|
+
>You're receiving this because you subscribed to <a href="https://example.com/?utm_source=backend_manager&utm_medium=email&utm_campaign=fixture_clean&utm_content=marketing" style="color: #888888;">BEM Fixture</a>.</div>
|
|
461
|
+
|
|
462
|
+
</td>
|
|
463
|
+
</tr>
|
|
464
|
+
|
|
465
|
+
</tbody>
|
|
466
|
+
</table>
|
|
467
|
+
|
|
468
|
+
</div>
|
|
469
|
+
|
|
470
|
+
<!--[if mso | IE]></td></tr></table><![endif]-->
|
|
471
|
+
</td>
|
|
472
|
+
</tr>
|
|
473
|
+
</tbody>
|
|
474
|
+
</table>
|
|
475
|
+
|
|
476
|
+
</div>
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
<!--[if mso | IE]></td></tr></table><![endif]-->
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
</div>
|
|
483
|
+
</body>
|
|
484
|
+
|
|
485
|
+
</html>
|
|
486
|
+
|
package/src/test/fixtures/firebase-project/.temp/newsletter/run-2026-08-05T01-21-40/newsletter.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Identity is the new growth lever
|
|
2
|
+
|
|
3
|
+
_Three platform shifts to lock in this week._
|
|
4
|
+
|
|
5
|
+
Identity matters because trust is the new growth lever. Teams that handle this well will spend less time cleaning up later.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## LinkedIn ships verified-profile gates for business accounts
|
|
10
|
+
|
|
11
|
+
LinkedIn now requires verified identity attestations on any business profile claiming more than 500 followers. Accounts with documented attribution histories sail through verification in under twelve hours. The practical implication is to lock down your attribution log this week, not next.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Documentation is the new operator moat
|
|
16
|
+
|
|
17
|
+
Operator playbooks are now the difference between an account that recovers from a flag and one that gets permanently restricted. Teams running documented processes recover in days. The ones without burn weeks negotiating with support queues.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## YouTube tests creator-attribution metadata on uploads
|
|
22
|
+
|
|
23
|
+
A subset of channels saw a new upload checkbox this week asking whether content was assisted by automation. The checkbox is optional today. Reading the room: it will not stay optional. Creators with clear internal workflows will adapt in an afternoon.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
Best,
|
|
28
|
+
The Somiibo Team
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Notes
|
|
33
|
+
|
|
34
|
+
1. LinkedIn flagged 12,000 impersonation attempts in the verified-profile beta. — _Reported by LinkedIn product team, May 2026_
|
|
35
|
+
|
|
36
|
+
2. Operator playbook adoption up 38% week-over-week in Q2. — _Per platform analytics, May 2026_
|
|
37
|
+
|
|
38
|
+
_Tags: #linkedin #youtube #platform-policy #creator-economy #operator-tools_
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
_You're receiving this because you subscribed to [BEM Fixture](https://example.com)._
|