@cakemail-org/cakemail-cli 1.7.0 → 2.0.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/.claude/settings.local.json +12 -0
- package/.env.example +40 -0
- package/.env.test.example +45 -0
- package/CHANGELOG.md +1031 -0
- package/README.md +41 -37
- package/audit-formats.js +128 -0
- package/cakemail.rb +20 -0
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/commands/account.js +1 -1
- package/dist/commands/account.js.map +1 -1
- package/dist/commands/attributes.js +1 -1
- package/dist/commands/attributes.js.map +1 -1
- package/dist/commands/campaigns.js +1 -1
- package/dist/commands/campaigns.js.map +1 -1
- package/dist/commands/contacts.js +1 -1
- package/dist/commands/contacts.js.map +1 -1
- package/dist/commands/emails.js +1 -1
- package/dist/commands/emails.js.map +1 -1
- package/dist/commands/interests.js +1 -1
- package/dist/commands/interests.js.map +1 -1
- package/dist/commands/lists.js +1 -1
- package/dist/commands/lists.js.map +1 -1
- package/dist/commands/logs.js +1 -1
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/reports.js +1 -1
- package/dist/commands/reports.js.map +1 -1
- package/dist/commands/segments.js +1 -1
- package/dist/commands/segments.js.map +1 -1
- package/dist/commands/senders.js +1 -1
- package/dist/commands/senders.js.map +1 -1
- package/dist/commands/suppressed.js +1 -1
- package/dist/commands/suppressed.js.map +1 -1
- package/dist/commands/tags.js +1 -1
- package/dist/commands/tags.js.map +1 -1
- package/dist/commands/templates.js +1 -1
- package/dist/commands/templates.js.map +1 -1
- package/dist/commands/transactional-templates.js +1 -1
- package/dist/commands/transactional-templates.js.map +1 -1
- package/dist/commands/webhooks.js +1 -1
- package/dist/commands/webhooks.js.map +1 -1
- package/dist/utils/config.js +2 -2
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/errors.js +1 -1
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/progress.d.ts.map +1 -1
- package/dist/utils/progress.js +32 -4
- package/dist/utils/progress.js.map +1 -1
- package/dist/utils/spinner.d.ts +17 -0
- package/dist/utils/spinner.d.ts.map +1 -0
- package/dist/utils/spinner.js +43 -0
- package/dist/utils/spinner.js.map +1 -0
- package/docs/DOCUMENTATION-STANDARD.md +1068 -0
- package/docs/README.md +161 -0
- package/docs/developer/ARCHITECTURE.md +516 -0
- package/docs/developer/AUTH.md +204 -0
- package/docs/developer/CONTRIBUTING.md +227 -0
- package/docs/developer/DOCUMENTATION_SUMMARY.md +346 -0
- package/docs/developer/PROJECT_INDEX.md +365 -0
- package/docs/planning/API_COVERAGE.md +1045 -0
- package/docs/planning/BACKLOG.md +1159 -0
- package/docs/planning/PROFILE_SYSTEM_TASKS.md +287 -0
- package/docs/planning/UX_IMPLEMENTATION_PLAN.md +691 -0
- package/docs/planning/archive/RELEASE_CHECKLIST_v1.3.0.md +332 -0
- package/docs/planning/archive/RELEASE_v1.3.0.md +428 -0
- package/docs/planning/archive/cakemail-cli-ux-improvements.md +438 -0
- package/docs/planning/cakemail-profile-system-plan.md +1121 -0
- package/docs/testing/AI_USER_SIMULATION_DESIGN.md +1342 -0
- package/docs/testing/KENOGAMI_BIDIRECTIONAL_FLOW.md +1517 -0
- package/docs/testing/KENOGAMI_TRUTH_RECONCILIATION_SYSTEM.md +1369 -0
- package/docs/user-manual/.obsidian/app.json +1 -0
- package/docs/user-manual/.obsidian/appearance.json +1 -0
- package/docs/user-manual/.obsidian/core-plugins.json +33 -0
- package/docs/user-manual/.obsidian/workspace.json +167 -0
- package/docs/user-manual/01-getting-started/01-installation.md +214 -0
- package/docs/user-manual/01-getting-started/02-quick-start.md +432 -0
- package/docs/user-manual/01-getting-started/03-authentication.md +448 -0
- package/docs/user-manual/01-getting-started/04-configuration.md +430 -0
- package/docs/user-manual/01-getting-started/05-output-formats.md +447 -0
- package/docs/user-manual/02-core-concepts/01-accounts.md +514 -0
- package/docs/user-manual/02-core-concepts/02-profile-system.md +771 -0
- package/docs/user-manual/02-core-concepts/03-smart-defaults.md +485 -0
- package/docs/user-manual/02-core-concepts/04-authentication-methods.md +435 -0
- package/docs/user-manual/02-core-concepts/05-pagination-filtering.md +600 -0
- package/docs/user-manual/02-core-concepts/06-error-handling.md +718 -0
- package/docs/user-manual/02-core-concepts/07-api-coverage.md +483 -0
- package/docs/user-manual/03-email-operations/01-senders.md +490 -0
- package/docs/user-manual/03-email-operations/02-templates.md +444 -0
- package/docs/user-manual/03-email-operations/03-transactional-emails.md +706 -0
- package/docs/user-manual/03-email-operations/04-email-tracking.md +407 -0
- package/docs/user-manual/04-campaign-management/01-campaigns-basics.md +394 -0
- package/docs/user-manual/04-campaign-management/02-campaign-scheduling.md +630 -0
- package/docs/user-manual/04-campaign-management/03-campaign-testing.md +997 -0
- package/docs/user-manual/04-campaign-management/04-campaign-lifecycle.md +709 -0
- package/docs/user-manual/04-campaign-management/05-campaign-links.md +934 -0
- package/docs/user-manual/05-contact-management/01-lists.md +836 -0
- package/docs/user-manual/05-contact-management/02-contacts.md +1035 -0
- package/docs/user-manual/05-contact-management/03-custom-attributes.md +788 -0
- package/docs/user-manual/05-contact-management/04-segments.md +1028 -0
- package/docs/user-manual/05-contact-management/05-contact-import-export.md +1031 -0
- package/docs/user-manual/06-analytics-reporting/01-campaign-analytics.md +867 -0
- package/docs/user-manual/06-analytics-reporting/02-account-reports.md +227 -0
- package/docs/user-manual/07-integrations/01-webhooks-integration.md +259 -0
- package/docs/user-manual/07-integrations/02-automation.md +326 -0
- package/docs/user-manual/08-advanced-usage/01-scripting-patterns.md +672 -0
- package/docs/user-manual/08-advanced-usage/02-bulk-operations.md +932 -0
- package/docs/user-manual/08-advanced-usage/03-ci-cd-integration.md +892 -0
- package/docs/user-manual/08-advanced-usage/04-performance-optimization.md +766 -0
- package/docs/user-manual/09-command-reference/01-config.md +776 -0
- package/docs/user-manual/09-command-reference/02-account.md +652 -0
- package/docs/user-manual/09-command-reference/03-lists.md +958 -0
- package/docs/user-manual/09-command-reference/04-contacts.md +1408 -0
- package/docs/user-manual/09-command-reference/05-attributes.md +617 -0
- package/docs/user-manual/09-command-reference/06-segments.md +894 -0
- package/docs/user-manual/09-command-reference/07-senders.md +803 -0
- package/docs/user-manual/09-command-reference/08-templates.md +818 -0
- package/docs/user-manual/09-command-reference/09-campaigns.md +1250 -0
- package/docs/user-manual/09-command-reference/10-emails.md +807 -0
- package/docs/user-manual/09-command-reference/11-reports.md +1135 -0
- package/docs/user-manual/09-command-reference/12-webhooks.md +773 -0
- package/docs/user-manual/09-command-reference/13-suppressed.md +797 -0
- package/docs/user-manual/09-command-reference/14-interests.md +630 -0
- package/docs/user-manual/09-command-reference/15-tags.md +584 -0
- package/docs/user-manual/09-command-reference/16-logs.md +656 -0
- package/docs/user-manual/09-command-reference/17-transactional-templates.md +850 -0
- package/docs/user-manual/10-troubleshooting/01-common-errors.md +457 -0
- package/docs/user-manual/10-troubleshooting/02-authentication-issues.md +558 -0
- package/docs/user-manual/10-troubleshooting/03-connection-problems.md +634 -0
- package/docs/user-manual/10-troubleshooting/04-debugging.md +725 -0
- package/docs/user-manual/11-appendix/04-faq.md +484 -0
- package/docs/user-manual/11-appendix/05-glossary.md +250 -0
- package/docs/user-manual/README.md +0 -0
- package/package.json +13 -61
- package/src/cli.ts +125 -0
- package/src/client.ts +16 -0
- package/src/commands/account.ts +267 -0
- package/src/commands/accounts.ts +78 -0
- package/src/commands/actions.ts +249 -0
- package/src/commands/attributes.ts +139 -0
- package/src/commands/campaign-blueprints.ts +106 -0
- package/src/commands/campaigns.ts +469 -0
- package/src/commands/config.ts +77 -0
- package/src/commands/contacts.ts +612 -0
- package/src/commands/custom-attributes.ts +127 -0
- package/src/commands/dkims.ts +117 -0
- package/src/commands/domains.ts +82 -0
- package/src/commands/email-apis.ts +569 -0
- package/src/commands/emails.ts +197 -0
- package/src/commands/forms.ts +283 -0
- package/src/commands/interests.ts +155 -0
- package/src/commands/links.ts +38 -0
- package/src/commands/lists.ts +406 -0
- package/src/commands/logos.ts +71 -0
- package/src/commands/logs.ts +386 -0
- package/src/commands/reports.ts +306 -0
- package/src/commands/segments.ts +158 -0
- package/src/commands/senders.ts +204 -0
- package/src/commands/sub-accounts.ts +271 -0
- package/src/commands/suppressed-emails.ts +234 -0
- package/src/commands/suppressed.ts +198 -0
- package/src/commands/system-emails.ts +85 -0
- package/src/commands/tags.ts +146 -0
- package/src/commands/tasks.ts +116 -0
- package/src/commands/templates.ts +189 -0
- package/src/commands/tokens.ts +83 -0
- package/src/commands/transactional-emails.ts +374 -0
- package/src/commands/transactional-templates.ts +385 -0
- package/src/commands/users.ts +506 -0
- package/src/commands/webhooks.ts +172 -0
- package/src/commands/workflow-blueprints.ts +123 -0
- package/src/commands/workflows.ts +265 -0
- package/src/types/profile.ts +93 -0
- package/src/utils/auth.ts +272 -0
- package/src/utils/config-file.ts +96 -0
- package/src/utils/config.ts +134 -0
- package/src/utils/confirm.ts +32 -0
- package/src/utils/defaults.ts +99 -0
- package/src/utils/errors.ts +116 -0
- package/src/utils/interactive.ts +91 -0
- package/src/utils/list-defaults.ts +74 -0
- package/src/utils/output.ts +190 -0
- package/src/utils/progress.ts +320 -0
- package/src/utils/spinner.ts +22 -0
- package/tests/IMPLEMENTATION_STATUS.md +258 -0
- package/tests/PTY_SETUP.md +118 -0
- package/tests/PTY_TESTING_GUIDE.md +507 -0
- package/tests/README.md +244 -0
- package/tests/fixtures/api-responses/campaigns.json +34 -0
- package/tests/fixtures/test-config.json +13 -0
- package/tests/helpers/cli-runner.ts +128 -0
- package/tests/helpers/mock-server.ts +301 -0
- package/tests/helpers/pty-runner.ts +181 -0
- package/tests/integration/campaigns-real-api.test.ts +196 -0
- package/tests/integration/setup-integration.ts +50 -0
- package/tests/pty/campaigns.test.ts +241 -0
- package/tests/setup.ts +34 -0
- package/tsconfig.json +15 -0
- package/vitest.config.ts +28 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
# Email Tracking
|
|
2
|
+
|
|
3
|
+
Track opens, clicks, and engagement metrics for transactional emails and campaigns.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Email tracking provides insights into recipient behavior:
|
|
8
|
+
- **Open tracking** - When recipients open emails
|
|
9
|
+
- **Click tracking** - Which links recipients click
|
|
10
|
+
- **Engagement metrics** - Overall performance data
|
|
11
|
+
|
|
12
|
+
## How Tracking Works
|
|
13
|
+
|
|
14
|
+
### Open Tracking
|
|
15
|
+
|
|
16
|
+
**Mechanism:**
|
|
17
|
+
- Invisible 1x1 pixel image embedded in email
|
|
18
|
+
- When email is opened, pixel loads from server
|
|
19
|
+
- Server logs the open event with timestamp
|
|
20
|
+
|
|
21
|
+
**Limitations:**
|
|
22
|
+
- Requires HTML email (doesn't work with plain text)
|
|
23
|
+
- Some email clients block images by default
|
|
24
|
+
- Privacy-focused clients may prevent tracking
|
|
25
|
+
|
|
26
|
+
### Click Tracking
|
|
27
|
+
|
|
28
|
+
**Mechanism:**
|
|
29
|
+
- Original links replaced with tracking URLs
|
|
30
|
+
- When recipient clicks, they're redirected through tracking server
|
|
31
|
+
- Server logs click event, then redirects to original URL
|
|
32
|
+
- Happens seamlessly (recipient doesn't notice)
|
|
33
|
+
|
|
34
|
+
**Example:**
|
|
35
|
+
```
|
|
36
|
+
Original: https://example.com/product
|
|
37
|
+
Tracked: https://track.cakemail.com/c/abc123/xyz789
|
|
38
|
+
→ Logs click → Redirects to original URL
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Enabling Tracking
|
|
42
|
+
|
|
43
|
+
### For Transactional Emails
|
|
44
|
+
|
|
45
|
+
Add `--tracking` flag:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
cakemail emails send \
|
|
49
|
+
-t recipient@example.com \
|
|
50
|
+
-s "Newsletter" \
|
|
51
|
+
--html-file newsletter.html \
|
|
52
|
+
--tracking
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### For Campaigns
|
|
56
|
+
|
|
57
|
+
Tracking is typically enabled by default for campaigns. Check campaign settings or enable during creation.
|
|
58
|
+
|
|
59
|
+
## Viewing Tracking Data
|
|
60
|
+
|
|
61
|
+
### Get Email Details
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
cakemail emails get <email-id>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Output with tracking data:**
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"id": "email_abc123",
|
|
71
|
+
"to": "recipient@example.com",
|
|
72
|
+
"subject": "Newsletter",
|
|
73
|
+
"status": "delivered",
|
|
74
|
+
"tracking": {
|
|
75
|
+
"opened": true,
|
|
76
|
+
"opened_at": "2024-06-15T10:30:00Z",
|
|
77
|
+
"opens_count": 3,
|
|
78
|
+
"clicked": true,
|
|
79
|
+
"clicks_count": 2,
|
|
80
|
+
"last_click_at": "2024-06-15T10:35:00Z"
|
|
81
|
+
},
|
|
82
|
+
"delivered_at": "2024-06-15T10:00:00Z"
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Filter Email Logs
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Emails that were opened
|
|
90
|
+
cakemail emails logs --status delivered | jq '.data[] | select(.tracking.opened==true)'
|
|
91
|
+
|
|
92
|
+
# Emails with clicks
|
|
93
|
+
cakemail emails logs --status delivered | jq '.data[] | select(.tracking.clicked==true)'
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Campaign Analytics
|
|
97
|
+
|
|
98
|
+
For campaign-level tracking:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
cakemail reports campaign <campaign-id>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Output:**
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"campaign_id": 12345,
|
|
108
|
+
"delivered": 1000,
|
|
109
|
+
"opened": 350,
|
|
110
|
+
"clicked": 120,
|
|
111
|
+
"bounced": 10,
|
|
112
|
+
"open_rate": 0.35,
|
|
113
|
+
"click_rate": 0.12,
|
|
114
|
+
"click_to_open_rate": 0.34
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Link-Level Tracking
|
|
119
|
+
|
|
120
|
+
See which specific links were clicked:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
cakemail reports campaign-links <campaign-id>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Output:**
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"links": [
|
|
130
|
+
{
|
|
131
|
+
"url": "https://example.com/product-1",
|
|
132
|
+
"clicks": 45,
|
|
133
|
+
"unique_clicks": 38
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"url": "https://example.com/product-2",
|
|
137
|
+
"clicks": 30,
|
|
138
|
+
"unique_clicks": 28
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Tracking Metrics Explained
|
|
145
|
+
|
|
146
|
+
### Opens
|
|
147
|
+
|
|
148
|
+
**Unique Opens:**
|
|
149
|
+
- Number of recipients who opened at least once
|
|
150
|
+
- Multiple opens from same recipient counted once
|
|
151
|
+
|
|
152
|
+
**Total Opens:**
|
|
153
|
+
- Total number of times email was opened
|
|
154
|
+
- Includes multiple opens from same recipient
|
|
155
|
+
|
|
156
|
+
**Open Rate:**
|
|
157
|
+
```
|
|
158
|
+
Open Rate = (Unique Opens / Delivered) × 100
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Clicks
|
|
162
|
+
|
|
163
|
+
**Unique Clicks:**
|
|
164
|
+
- Number of recipients who clicked at least once
|
|
165
|
+
- Multiple clicks from same recipient counted once
|
|
166
|
+
|
|
167
|
+
**Total Clicks:**
|
|
168
|
+
- Total number of clicks across all links
|
|
169
|
+
- Includes multiple clicks from same recipient
|
|
170
|
+
|
|
171
|
+
**Click Rate:**
|
|
172
|
+
```
|
|
173
|
+
Click Rate = (Unique Clicks / Delivered) × 100
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Click-to-Open Rate (CTOR):**
|
|
177
|
+
```
|
|
178
|
+
CTOR = (Unique Clicks / Unique Opens) × 100
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Best Practices
|
|
182
|
+
|
|
183
|
+
### 1. Always Enable Tracking
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# ✅ Track everything
|
|
187
|
+
cakemail emails send ... --tracking
|
|
188
|
+
|
|
189
|
+
# ❌ Missing insights
|
|
190
|
+
cakemail emails send ...
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### 2. Provide Plain Text Alternative
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# ✅ HTML + text (tracking works on HTML)
|
|
197
|
+
cakemail emails send \
|
|
198
|
+
--html-file email.html \
|
|
199
|
+
--text-file email.txt \
|
|
200
|
+
--tracking
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 3. Use Descriptive Link Text
|
|
204
|
+
|
|
205
|
+
```html
|
|
206
|
+
<!-- ✅ Clear call-to-action -->
|
|
207
|
+
<a href="https://example.com/signup">Sign Up Now</a>
|
|
208
|
+
|
|
209
|
+
<!-- ❌ Generic -->
|
|
210
|
+
<a href="https://example.com/signup">Click here</a>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### 4. Test Email Rendering
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# Render email to verify tracking pixel
|
|
217
|
+
cakemail emails render <email-id> --tracking > test.html
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### 5. Monitor Engagement
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
#!/bin/bash
|
|
224
|
+
# Check engagement daily
|
|
225
|
+
|
|
226
|
+
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)
|
|
227
|
+
TODAY=$(date +%Y-%m-%d)
|
|
228
|
+
|
|
229
|
+
STATS=$(cakemail -f json emails logs --from $YESTERDAY --to $TODAY)
|
|
230
|
+
SENT=$(echo "$STATS" | jq '.total')
|
|
231
|
+
OPENED=$(echo "$STATS" | jq '[.data[] | select(.tracking.opened==true)] | length')
|
|
232
|
+
CLICKED=$(echo "$STATS" | jq '[.data[] | select(.tracking.clicked==true)] | length')
|
|
233
|
+
|
|
234
|
+
echo "Daily Email Stats:"
|
|
235
|
+
echo " Sent: $SENT"
|
|
236
|
+
echo " Opened: $OPENED"
|
|
237
|
+
echo " Clicked: $CLICKED"
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Privacy Considerations
|
|
241
|
+
|
|
242
|
+
### Respecting Privacy
|
|
243
|
+
|
|
244
|
+
**Best practices:**
|
|
245
|
+
1. **Inform recipients** - Include tracking disclosure in privacy policy
|
|
246
|
+
2. **Provide opt-out** - Allow users to disable tracking
|
|
247
|
+
3. **Secure data** - Tracking data is encrypted and secure
|
|
248
|
+
4. **Comply with regulations** - Follow GDPR, CAN-SPAM, CASL
|
|
249
|
+
|
|
250
|
+
### GDPR Compliance
|
|
251
|
+
|
|
252
|
+
If sending to EU recipients:
|
|
253
|
+
- Disclose tracking in privacy policy
|
|
254
|
+
- Obtain consent where required
|
|
255
|
+
- Provide easy opt-out mechanism
|
|
256
|
+
- Honor data deletion requests
|
|
257
|
+
|
|
258
|
+
## Troubleshooting
|
|
259
|
+
|
|
260
|
+
### Opens Not Being Tracked
|
|
261
|
+
|
|
262
|
+
**Possible causes:**
|
|
263
|
+
1. **Images blocked** - Email client blocks images
|
|
264
|
+
2. **Plain text only** - Recipient viewing plain text version
|
|
265
|
+
3. **Preview pane** - Some clients don't count preview as open
|
|
266
|
+
4. **Privacy protection** - Client using privacy features
|
|
267
|
+
|
|
268
|
+
**Not always a problem:**
|
|
269
|
+
- Some opens won't be tracked (that's normal)
|
|
270
|
+
- Focus on trends, not individual opens
|
|
271
|
+
|
|
272
|
+
### Clicks Not Being Tracked
|
|
273
|
+
|
|
274
|
+
**Check:**
|
|
275
|
+
1. **Tracking enabled** - Verify `--tracking` flag used
|
|
276
|
+
2. **HTML email** - Tracking requires HTML
|
|
277
|
+
3. **Valid links** - Ensure links in email are correct
|
|
278
|
+
|
|
279
|
+
**Debug:**
|
|
280
|
+
```bash
|
|
281
|
+
# Render email with tracking
|
|
282
|
+
cakemail emails render <email-id> --tracking > debug.html
|
|
283
|
+
|
|
284
|
+
# Inspect links (should be tracking URLs)
|
|
285
|
+
grep -o 'href="[^"]*"' debug.html
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Tracking Data Missing
|
|
289
|
+
|
|
290
|
+
**Verify tracking was enabled:**
|
|
291
|
+
```bash
|
|
292
|
+
# Check email details
|
|
293
|
+
cakemail emails get <email-id>
|
|
294
|
+
|
|
295
|
+
# Look for tracking object in response
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**If missing:**
|
|
299
|
+
- Email was sent without `--tracking` flag
|
|
300
|
+
- Resend with tracking enabled
|
|
301
|
+
|
|
302
|
+
## Analytics Best Practices
|
|
303
|
+
|
|
304
|
+
### 1. Segment Analysis
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
# Compare performance by tag
|
|
308
|
+
cakemail emails logs --tag "welcome" --from 2024-06-01
|
|
309
|
+
cakemail emails logs --tag "newsletter" --from 2024-06-01
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### 2. Time-Based Analysis
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
# Weekly comparison
|
|
316
|
+
cakemail emails logs --from 2024-06-01 --to 2024-06-07
|
|
317
|
+
cakemail emails logs --from 2024-06-08 --to 2024-06-14
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### 3. A/B Testing
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
# Send variant A
|
|
324
|
+
cakemail emails send ... --tags "test-a,subject-variant-1" --tracking
|
|
325
|
+
|
|
326
|
+
# Send variant B
|
|
327
|
+
cakemail emails send ... --tags "test-b,subject-variant-2" --tracking
|
|
328
|
+
|
|
329
|
+
# Compare results
|
|
330
|
+
cakemail emails logs --tag "test-a"
|
|
331
|
+
cakemail emails logs --tag "test-b"
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### 4. Track Campaign Performance
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
# Campaign overview
|
|
338
|
+
cakemail reports campaign <campaign-id>
|
|
339
|
+
|
|
340
|
+
# Link performance
|
|
341
|
+
cakemail reports campaign-links <campaign-id>
|
|
342
|
+
|
|
343
|
+
# Export for analysis
|
|
344
|
+
cakemail reports campaign <campaign-id> > campaign-stats.json
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Practical Examples
|
|
348
|
+
|
|
349
|
+
### Example 1: Daily Engagement Report
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
#!/bin/bash
|
|
353
|
+
# daily-report.sh
|
|
354
|
+
|
|
355
|
+
DATE=$(date +%Y-%m-%d)
|
|
356
|
+
REPORT="report-$DATE.txt"
|
|
357
|
+
|
|
358
|
+
echo "Email Engagement Report - $DATE" > $REPORT
|
|
359
|
+
echo "=================================" >> $REPORT
|
|
360
|
+
echo "" >> $REPORT
|
|
361
|
+
|
|
362
|
+
# Get stats
|
|
363
|
+
STATS=$(cakemail -f json emails logs --from $DATE --to $DATE)
|
|
364
|
+
|
|
365
|
+
# Parse data
|
|
366
|
+
TOTAL=$(echo "$STATS" | jq '.total')
|
|
367
|
+
DELIVERED=$(echo "$STATS" | jq '[.data[] | select(.status=="delivered")] | length')
|
|
368
|
+
OPENED=$(echo "$STATS" | jq '[.data[] | select(.tracking.opened==true)] | length')
|
|
369
|
+
CLICKED=$(echo "$STATS" | jq '[.data[] | select(.tracking.clicked==true)] | length')
|
|
370
|
+
|
|
371
|
+
# Calculate rates
|
|
372
|
+
OPEN_RATE=$(echo "scale=2; $OPENED * 100 / $DELIVERED" | bc)
|
|
373
|
+
CLICK_RATE=$(echo "scale=2; $CLICKED * 100 / $DELIVERED" | bc)
|
|
374
|
+
|
|
375
|
+
# Write report
|
|
376
|
+
echo "Total Sent: $TOTAL" >> $REPORT
|
|
377
|
+
echo "Delivered: $DELIVERED" >> $REPORT
|
|
378
|
+
echo "Opened: $OPENED ($OPEN_RATE%)" >> $REPORT
|
|
379
|
+
echo "Clicked: $CLICKED ($CLICK_RATE%)" >> $REPORT
|
|
380
|
+
|
|
381
|
+
cat $REPORT
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Example 2: Link Performance Analysis
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
#!/bin/bash
|
|
388
|
+
# analyze-links.sh
|
|
389
|
+
|
|
390
|
+
CAMPAIGN_ID=$1
|
|
391
|
+
|
|
392
|
+
if [ -z "$CAMPAIGN_ID" ]; then
|
|
393
|
+
echo "Usage: ./analyze-links.sh <campaign-id>"
|
|
394
|
+
exit 1
|
|
395
|
+
fi
|
|
396
|
+
|
|
397
|
+
echo "Analyzing campaign $CAMPAIGN_ID..."
|
|
398
|
+
echo ""
|
|
399
|
+
|
|
400
|
+
# Get link data
|
|
401
|
+
LINKS=$(cakemail -f json reports campaign-links $CAMPAIGN_ID)
|
|
402
|
+
|
|
403
|
+
# Display top links
|
|
404
|
+
echo "Top 5 Links by Clicks:"
|
|
405
|
+
echo "$LINKS" | jq -r '.links | sort_by(-.clicks) | .[:5][] | "\(.clicks) clicks - \(.url)"'
|
|
406
|
+
```
|
|
407
|
+
|