@cakemail-org/cakemail-cli 1.5.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 +319 -15
- package/audit-formats.js +128 -0
- package/cakemail.rb +20 -0
- package/dist/cli.js +27 -10
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +16 -6
- 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.d.ts.map +1 -1
- package/dist/commands/campaigns.js +103 -8
- package/dist/commands/campaigns.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +63 -4
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/contacts.d.ts.map +1 -1
- package/dist/commands/contacts.js +91 -12
- 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.d.ts +5 -0
- package/dist/commands/interests.d.ts.map +1 -0
- package/dist/commands/interests.js +172 -0
- package/dist/commands/interests.js.map +1 -0
- package/dist/commands/lists.d.ts.map +1 -1
- package/dist/commands/lists.js +6 -8
- package/dist/commands/lists.js.map +1 -1
- package/dist/commands/logs.d.ts +5 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +237 -0
- package/dist/commands/logs.js.map +1 -0
- 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.d.ts.map +1 -1
- package/dist/commands/senders.js +11 -8
- 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.d.ts +5 -0
- package/dist/commands/tags.d.ts.map +1 -0
- package/dist/commands/tags.js +124 -0
- package/dist/commands/tags.js.map +1 -0
- package/dist/commands/templates.js +1 -1
- package/dist/commands/templates.js.map +1 -1
- package/dist/commands/transactional-templates.d.ts +5 -0
- package/dist/commands/transactional-templates.d.ts.map +1 -0
- package/dist/commands/transactional-templates.js +354 -0
- package/dist/commands/transactional-templates.js.map +1 -0
- package/dist/commands/webhooks.js +1 -1
- package/dist/commands/webhooks.js.map +1 -1
- package/dist/utils/auth.d.ts +8 -1
- package/dist/utils/auth.d.ts.map +1 -1
- package/dist/utils/auth.js +39 -11
- package/dist/utils/auth.js.map +1 -1
- package/dist/utils/config-file.d.ts +7 -0
- package/dist/utils/config-file.d.ts.map +1 -1
- package/dist/utils/config-file.js +15 -0
- package/dist/utils/config-file.js.map +1 -1
- package/dist/utils/config.d.ts +2 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +12 -4
- 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/list-defaults.d.ts +33 -0
- package/dist/utils/list-defaults.d.ts.map +1 -0
- package/dist/utils/list-defaults.js +52 -0
- package/dist/utils/list-defaults.js.map +1 -0
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +36 -13
- package/dist/utils/output.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 -47
- 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,326 @@
|
|
|
1
|
+
# Automation & Scripting
|
|
2
|
+
|
|
3
|
+
Automate email marketing workflows with shell scripts and CI/CD integration.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Automation enables:
|
|
8
|
+
- Scheduled campaign sending
|
|
9
|
+
- Automated list management
|
|
10
|
+
- Batch contact imports
|
|
11
|
+
- Regular reporting
|
|
12
|
+
- Integration with existing workflows
|
|
13
|
+
|
|
14
|
+
## Quick Start Automation
|
|
15
|
+
|
|
16
|
+
### Daily Newsletter Script
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
#!/bin/bash
|
|
20
|
+
# daily-newsletter.sh
|
|
21
|
+
|
|
22
|
+
DATE=$(date +%Y-%m-%d)
|
|
23
|
+
LIST_ID=123
|
|
24
|
+
SENDER_ID=101
|
|
25
|
+
|
|
26
|
+
# Create campaign
|
|
27
|
+
CAMPAIGN_ID=$(cakemail campaigns create \
|
|
28
|
+
-n "Daily News - $DATE" \
|
|
29
|
+
-l $LIST_ID \
|
|
30
|
+
-s $SENDER_ID \
|
|
31
|
+
--template 201 \
|
|
32
|
+
--subject "Today's Top Stories" \
|
|
33
|
+
-f json | jq -r '.id')
|
|
34
|
+
|
|
35
|
+
# Send test
|
|
36
|
+
cakemail campaigns test $CAMPAIGN_ID -e editor@company.com
|
|
37
|
+
|
|
38
|
+
# Schedule for 8 AM
|
|
39
|
+
cakemail campaigns schedule $CAMPAIGN_ID --when "$(date +%Y-%m-%d) 08:00:00"
|
|
40
|
+
|
|
41
|
+
echo "Newsletter scheduled: $CAMPAIGN_ID"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Schedule with cron:**
|
|
45
|
+
```bash
|
|
46
|
+
# Run daily at 6 AM
|
|
47
|
+
0 6 * * * /path/to/daily-newsletter.sh >> /var/log/newsletter.log 2>&1
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Cron Integration
|
|
51
|
+
|
|
52
|
+
### Common Cron Patterns
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Daily at 2 AM
|
|
56
|
+
0 2 * * * /path/to/backup-contacts.sh
|
|
57
|
+
|
|
58
|
+
# Every Monday at 9 AM
|
|
59
|
+
0 9 * * 1 /path/to/weekly-report.sh
|
|
60
|
+
|
|
61
|
+
# First day of month at midnight
|
|
62
|
+
0 0 1 * * /path/to/monthly-cleanup.sh
|
|
63
|
+
|
|
64
|
+
# Every 6 hours
|
|
65
|
+
0 */6 * * * /path/to/sync-contacts.sh
|
|
66
|
+
|
|
67
|
+
# Weekdays at 8 AM
|
|
68
|
+
0 8 * * 1-5 /path/to/workday-newsletter.sh
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Automated Contact Sync
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
#!/bin/bash
|
|
75
|
+
# sync-contacts-from-crm.sh
|
|
76
|
+
|
|
77
|
+
LIST_ID=123
|
|
78
|
+
|
|
79
|
+
# Fetch from your CRM API
|
|
80
|
+
curl -s "https://api.yourcrm.com/contacts" | \
|
|
81
|
+
jq -r '.[] | [.email, .first_name, .last_name] | @csv' > contacts-temp.csv
|
|
82
|
+
|
|
83
|
+
# Import to Cakemail
|
|
84
|
+
cakemail contacts import $LIST_ID --file contacts-temp.csv
|
|
85
|
+
|
|
86
|
+
# Cleanup
|
|
87
|
+
rm contacts-temp.csv
|
|
88
|
+
|
|
89
|
+
echo "Contact sync complete: $(date)"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## CI/CD Integration
|
|
93
|
+
|
|
94
|
+
### GitHub Actions
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
# .github/workflows/email-campaign.yml
|
|
98
|
+
name: Deploy Email Campaign
|
|
99
|
+
|
|
100
|
+
on:
|
|
101
|
+
push:
|
|
102
|
+
branches: [main]
|
|
103
|
+
paths:
|
|
104
|
+
- 'campaigns/**'
|
|
105
|
+
|
|
106
|
+
jobs:
|
|
107
|
+
deploy:
|
|
108
|
+
runs-on: ubuntu-latest
|
|
109
|
+
|
|
110
|
+
steps:
|
|
111
|
+
- uses: actions/checkout@v2
|
|
112
|
+
|
|
113
|
+
- name: Install Cakemail CLI
|
|
114
|
+
run: npm install -g @cakemail-org/cakemail-cli
|
|
115
|
+
|
|
116
|
+
- name: Configure Cakemail
|
|
117
|
+
env:
|
|
118
|
+
CAKEMAIL_EMAIL: ${{ secrets.CAKEMAIL_EMAIL }}
|
|
119
|
+
CAKEMAIL_PASSWORD: ${{ secrets.CAKEMAIL_PASSWORD }}
|
|
120
|
+
run: |
|
|
121
|
+
echo "CAKEMAIL_EMAIL=$CAKEMAIL_EMAIL" > .env
|
|
122
|
+
echo "CAKEMAIL_PASSWORD=$CAKEMAIL_PASSWORD" >> .env
|
|
123
|
+
|
|
124
|
+
- name: Create Campaign
|
|
125
|
+
run: |
|
|
126
|
+
cakemail campaigns create \
|
|
127
|
+
-n "Automated Campaign" \
|
|
128
|
+
-l 123 \
|
|
129
|
+
-s 101 \
|
|
130
|
+
--html-file campaigns/latest.html \
|
|
131
|
+
--subject "$(cat campaigns/subject.txt)"
|
|
132
|
+
|
|
133
|
+
- name: Send Test
|
|
134
|
+
run: cakemail campaigns test $CAMPAIGN_ID -e test@company.com
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### GitLab CI
|
|
138
|
+
|
|
139
|
+
```yaml
|
|
140
|
+
# .gitlab-ci.yml
|
|
141
|
+
deploy_campaign:
|
|
142
|
+
stage: deploy
|
|
143
|
+
only:
|
|
144
|
+
- main
|
|
145
|
+
script:
|
|
146
|
+
- npm install -g @cakemail-org/cakemail-cli
|
|
147
|
+
- echo "CAKEMAIL_EMAIL=$CAKEMAIL_EMAIL" > .env
|
|
148
|
+
- echo "CAKEMAIL_PASSWORD=$CAKEMAIL_PASSWORD" >> .env
|
|
149
|
+
- |
|
|
150
|
+
cakemail campaigns create \
|
|
151
|
+
-n "Production Campaign" \
|
|
152
|
+
-l 123 \
|
|
153
|
+
-s 101 \
|
|
154
|
+
--html-file campaign.html
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Advanced Automation
|
|
158
|
+
|
|
159
|
+
### Conditional Campaign Sending
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
#!/bin/bash
|
|
163
|
+
# conditional-send.sh
|
|
164
|
+
|
|
165
|
+
# Only send if segment has enough contacts
|
|
166
|
+
SEGMENT_ID=456
|
|
167
|
+
MIN_CONTACTS=100
|
|
168
|
+
|
|
169
|
+
COUNT=$(cakemail segments get 123 $SEGMENT_ID -f json | jq -r '.contact_count')
|
|
170
|
+
|
|
171
|
+
if [ $COUNT -ge $MIN_CONTACTS ]; then
|
|
172
|
+
echo "Segment has $COUNT contacts - proceeding"
|
|
173
|
+
|
|
174
|
+
CAMPAIGN_ID=$(cakemail campaigns create \
|
|
175
|
+
-n "Targeted Campaign" \
|
|
176
|
+
-l 123 \
|
|
177
|
+
-s 101 \
|
|
178
|
+
--segment $SEGMENT_ID \
|
|
179
|
+
-f json | jq -r '.id')
|
|
180
|
+
|
|
181
|
+
cakemail campaigns schedule $CAMPAIGN_ID
|
|
182
|
+
else
|
|
183
|
+
echo "Segment too small ($COUNT contacts) - skipping"
|
|
184
|
+
fi
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Error Handling
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
#!/bin/bash
|
|
191
|
+
# robust-automation.sh
|
|
192
|
+
|
|
193
|
+
set -e # Exit on error
|
|
194
|
+
|
|
195
|
+
LOG_FILE="/var/log/cakemail-automation.log"
|
|
196
|
+
ERROR_EMAIL="admin@company.com"
|
|
197
|
+
|
|
198
|
+
log() {
|
|
199
|
+
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
error_exit() {
|
|
203
|
+
log "ERROR: $1"
|
|
204
|
+
echo "Automation failed: $1" | mail -s "Cakemail Error" "$ERROR_EMAIL"
|
|
205
|
+
exit 1
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
log "Starting campaign creation..."
|
|
209
|
+
|
|
210
|
+
CAMPAIGN_ID=$(cakemail campaigns create \
|
|
211
|
+
-n "Daily Update" \
|
|
212
|
+
-l 123 \
|
|
213
|
+
-s 101 \
|
|
214
|
+
-f json | jq -r '.id') || error_exit "Campaign creation failed"
|
|
215
|
+
|
|
216
|
+
log "Campaign created: $CAMPAIGN_ID"
|
|
217
|
+
|
|
218
|
+
cakemail campaigns test $CAMPAIGN_ID -e test@company.com || \
|
|
219
|
+
error_exit "Test email failed"
|
|
220
|
+
|
|
221
|
+
log "Test sent successfully"
|
|
222
|
+
|
|
223
|
+
cakemail campaigns schedule $CAMPAIGN_ID || \
|
|
224
|
+
error_exit "Scheduling failed"
|
|
225
|
+
|
|
226
|
+
log "Campaign scheduled successfully"
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Makefile Integration
|
|
230
|
+
|
|
231
|
+
```makefile
|
|
232
|
+
# Makefile for email campaigns
|
|
233
|
+
|
|
234
|
+
.PHONY: test send-newsletter backup-contacts
|
|
235
|
+
|
|
236
|
+
test:
|
|
237
|
+
@echo "Sending test campaign..."
|
|
238
|
+
@cakemail campaigns test 790 -e test@company.com
|
|
239
|
+
|
|
240
|
+
send-newsletter:
|
|
241
|
+
@echo "Creating newsletter..."
|
|
242
|
+
@./scripts/create-newsletter.sh
|
|
243
|
+
@echo "Done!"
|
|
244
|
+
|
|
245
|
+
backup-contacts:
|
|
246
|
+
@echo "Backing up contacts..."
|
|
247
|
+
@./scripts/backup-contacts.sh
|
|
248
|
+
@echo "Backup complete"
|
|
249
|
+
|
|
250
|
+
deploy: test
|
|
251
|
+
@echo "Deploying campaign..."
|
|
252
|
+
@cakemail campaigns schedule 790
|
|
253
|
+
@echo "Campaign scheduled"
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Monitoring & Alerting
|
|
257
|
+
|
|
258
|
+
### Slack Notifications
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
#!/bin/bash
|
|
262
|
+
# notify-slack.sh
|
|
263
|
+
|
|
264
|
+
SLACK_WEBHOOK="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
|
|
265
|
+
MESSAGE="$1"
|
|
266
|
+
|
|
267
|
+
curl -X POST $SLACK_WEBHOOK \
|
|
268
|
+
-H 'Content-Type: application/json' \
|
|
269
|
+
-d "{\"text\": \"$MESSAGE\"}"
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
# In automation script
|
|
274
|
+
./notify-slack.sh "✅ Campaign 790 sent successfully"
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Email Alerts
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
#!/bin/bash
|
|
281
|
+
# Send email alert on failure
|
|
282
|
+
|
|
283
|
+
if ! cakemail campaigns schedule 790; then
|
|
284
|
+
echo "Campaign scheduling failed" | \
|
|
285
|
+
mail -s "Cakemail Alert" admin@company.com
|
|
286
|
+
fi
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Best Practices
|
|
290
|
+
|
|
291
|
+
1. **Use Environment Variables**
|
|
292
|
+
```bash
|
|
293
|
+
export CAKEMAIL_EMAIL="your@email.com"
|
|
294
|
+
export CAKEMAIL_PASSWORD="password"
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
2. **Log Everything**
|
|
298
|
+
```bash
|
|
299
|
+
exec 1> >(tee -a script.log)
|
|
300
|
+
exec 2>&1
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
3. **Implement Retries**
|
|
304
|
+
```bash
|
|
305
|
+
retry() {
|
|
306
|
+
local n=1
|
|
307
|
+
local max=3
|
|
308
|
+
while true; do
|
|
309
|
+
"$@" && break || {
|
|
310
|
+
if [[ $n -lt $max ]]; then
|
|
311
|
+
((n++))
|
|
312
|
+
sleep 5
|
|
313
|
+
else
|
|
314
|
+
return 1
|
|
315
|
+
fi
|
|
316
|
+
}
|
|
317
|
+
done
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
retry cakemail campaigns create -n "Test"
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
4. **Test in Staging First**
|
|
324
|
+
5. **Monitor Execution**
|
|
325
|
+
6. **Handle Failures Gracefully**
|
|
326
|
+
|