@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.
Files changed (234) hide show
  1. package/.claude/settings.local.json +12 -0
  2. package/.env.example +40 -0
  3. package/.env.test.example +45 -0
  4. package/CHANGELOG.md +1031 -0
  5. package/README.md +319 -15
  6. package/audit-formats.js +128 -0
  7. package/cakemail.rb +20 -0
  8. package/dist/cli.js +27 -10
  9. package/dist/cli.js.map +1 -1
  10. package/dist/client.d.ts +2 -0
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +16 -6
  13. package/dist/client.js.map +1 -1
  14. package/dist/commands/account.js +1 -1
  15. package/dist/commands/account.js.map +1 -1
  16. package/dist/commands/attributes.js +1 -1
  17. package/dist/commands/attributes.js.map +1 -1
  18. package/dist/commands/campaigns.d.ts.map +1 -1
  19. package/dist/commands/campaigns.js +103 -8
  20. package/dist/commands/campaigns.js.map +1 -1
  21. package/dist/commands/config.d.ts.map +1 -1
  22. package/dist/commands/config.js +63 -4
  23. package/dist/commands/config.js.map +1 -1
  24. package/dist/commands/contacts.d.ts.map +1 -1
  25. package/dist/commands/contacts.js +91 -12
  26. package/dist/commands/contacts.js.map +1 -1
  27. package/dist/commands/emails.js +1 -1
  28. package/dist/commands/emails.js.map +1 -1
  29. package/dist/commands/interests.d.ts +5 -0
  30. package/dist/commands/interests.d.ts.map +1 -0
  31. package/dist/commands/interests.js +172 -0
  32. package/dist/commands/interests.js.map +1 -0
  33. package/dist/commands/lists.d.ts.map +1 -1
  34. package/dist/commands/lists.js +6 -8
  35. package/dist/commands/lists.js.map +1 -1
  36. package/dist/commands/logs.d.ts +5 -0
  37. package/dist/commands/logs.d.ts.map +1 -0
  38. package/dist/commands/logs.js +237 -0
  39. package/dist/commands/logs.js.map +1 -0
  40. package/dist/commands/reports.js +1 -1
  41. package/dist/commands/reports.js.map +1 -1
  42. package/dist/commands/segments.js +1 -1
  43. package/dist/commands/segments.js.map +1 -1
  44. package/dist/commands/senders.d.ts.map +1 -1
  45. package/dist/commands/senders.js +11 -8
  46. package/dist/commands/senders.js.map +1 -1
  47. package/dist/commands/suppressed.js +1 -1
  48. package/dist/commands/suppressed.js.map +1 -1
  49. package/dist/commands/tags.d.ts +5 -0
  50. package/dist/commands/tags.d.ts.map +1 -0
  51. package/dist/commands/tags.js +124 -0
  52. package/dist/commands/tags.js.map +1 -0
  53. package/dist/commands/templates.js +1 -1
  54. package/dist/commands/templates.js.map +1 -1
  55. package/dist/commands/transactional-templates.d.ts +5 -0
  56. package/dist/commands/transactional-templates.d.ts.map +1 -0
  57. package/dist/commands/transactional-templates.js +354 -0
  58. package/dist/commands/transactional-templates.js.map +1 -0
  59. package/dist/commands/webhooks.js +1 -1
  60. package/dist/commands/webhooks.js.map +1 -1
  61. package/dist/utils/auth.d.ts +8 -1
  62. package/dist/utils/auth.d.ts.map +1 -1
  63. package/dist/utils/auth.js +39 -11
  64. package/dist/utils/auth.js.map +1 -1
  65. package/dist/utils/config-file.d.ts +7 -0
  66. package/dist/utils/config-file.d.ts.map +1 -1
  67. package/dist/utils/config-file.js +15 -0
  68. package/dist/utils/config-file.js.map +1 -1
  69. package/dist/utils/config.d.ts +2 -0
  70. package/dist/utils/config.d.ts.map +1 -1
  71. package/dist/utils/config.js +12 -4
  72. package/dist/utils/config.js.map +1 -1
  73. package/dist/utils/errors.js +1 -1
  74. package/dist/utils/errors.js.map +1 -1
  75. package/dist/utils/list-defaults.d.ts +33 -0
  76. package/dist/utils/list-defaults.d.ts.map +1 -0
  77. package/dist/utils/list-defaults.js +52 -0
  78. package/dist/utils/list-defaults.js.map +1 -0
  79. package/dist/utils/output.d.ts.map +1 -1
  80. package/dist/utils/output.js +36 -13
  81. package/dist/utils/output.js.map +1 -1
  82. package/dist/utils/progress.d.ts.map +1 -1
  83. package/dist/utils/progress.js +32 -4
  84. package/dist/utils/progress.js.map +1 -1
  85. package/dist/utils/spinner.d.ts +17 -0
  86. package/dist/utils/spinner.d.ts.map +1 -0
  87. package/dist/utils/spinner.js +43 -0
  88. package/dist/utils/spinner.js.map +1 -0
  89. package/docs/DOCUMENTATION-STANDARD.md +1068 -0
  90. package/docs/README.md +161 -0
  91. package/docs/developer/ARCHITECTURE.md +516 -0
  92. package/docs/developer/AUTH.md +204 -0
  93. package/docs/developer/CONTRIBUTING.md +227 -0
  94. package/docs/developer/DOCUMENTATION_SUMMARY.md +346 -0
  95. package/docs/developer/PROJECT_INDEX.md +365 -0
  96. package/docs/planning/API_COVERAGE.md +1045 -0
  97. package/docs/planning/BACKLOG.md +1159 -0
  98. package/docs/planning/PROFILE_SYSTEM_TASKS.md +287 -0
  99. package/docs/planning/UX_IMPLEMENTATION_PLAN.md +691 -0
  100. package/docs/planning/archive/RELEASE_CHECKLIST_v1.3.0.md +332 -0
  101. package/docs/planning/archive/RELEASE_v1.3.0.md +428 -0
  102. package/docs/planning/archive/cakemail-cli-ux-improvements.md +438 -0
  103. package/docs/planning/cakemail-profile-system-plan.md +1121 -0
  104. package/docs/testing/AI_USER_SIMULATION_DESIGN.md +1342 -0
  105. package/docs/testing/KENOGAMI_BIDIRECTIONAL_FLOW.md +1517 -0
  106. package/docs/testing/KENOGAMI_TRUTH_RECONCILIATION_SYSTEM.md +1369 -0
  107. package/docs/user-manual/.obsidian/app.json +1 -0
  108. package/docs/user-manual/.obsidian/appearance.json +1 -0
  109. package/docs/user-manual/.obsidian/core-plugins.json +33 -0
  110. package/docs/user-manual/.obsidian/workspace.json +167 -0
  111. package/docs/user-manual/01-getting-started/01-installation.md +214 -0
  112. package/docs/user-manual/01-getting-started/02-quick-start.md +432 -0
  113. package/docs/user-manual/01-getting-started/03-authentication.md +448 -0
  114. package/docs/user-manual/01-getting-started/04-configuration.md +430 -0
  115. package/docs/user-manual/01-getting-started/05-output-formats.md +447 -0
  116. package/docs/user-manual/02-core-concepts/01-accounts.md +514 -0
  117. package/docs/user-manual/02-core-concepts/02-profile-system.md +771 -0
  118. package/docs/user-manual/02-core-concepts/03-smart-defaults.md +485 -0
  119. package/docs/user-manual/02-core-concepts/04-authentication-methods.md +435 -0
  120. package/docs/user-manual/02-core-concepts/05-pagination-filtering.md +600 -0
  121. package/docs/user-manual/02-core-concepts/06-error-handling.md +718 -0
  122. package/docs/user-manual/02-core-concepts/07-api-coverage.md +483 -0
  123. package/docs/user-manual/03-email-operations/01-senders.md +490 -0
  124. package/docs/user-manual/03-email-operations/02-templates.md +444 -0
  125. package/docs/user-manual/03-email-operations/03-transactional-emails.md +706 -0
  126. package/docs/user-manual/03-email-operations/04-email-tracking.md +407 -0
  127. package/docs/user-manual/04-campaign-management/01-campaigns-basics.md +394 -0
  128. package/docs/user-manual/04-campaign-management/02-campaign-scheduling.md +630 -0
  129. package/docs/user-manual/04-campaign-management/03-campaign-testing.md +997 -0
  130. package/docs/user-manual/04-campaign-management/04-campaign-lifecycle.md +709 -0
  131. package/docs/user-manual/04-campaign-management/05-campaign-links.md +934 -0
  132. package/docs/user-manual/05-contact-management/01-lists.md +836 -0
  133. package/docs/user-manual/05-contact-management/02-contacts.md +1035 -0
  134. package/docs/user-manual/05-contact-management/03-custom-attributes.md +788 -0
  135. package/docs/user-manual/05-contact-management/04-segments.md +1028 -0
  136. package/docs/user-manual/05-contact-management/05-contact-import-export.md +1031 -0
  137. package/docs/user-manual/06-analytics-reporting/01-campaign-analytics.md +867 -0
  138. package/docs/user-manual/06-analytics-reporting/02-account-reports.md +227 -0
  139. package/docs/user-manual/07-integrations/01-webhooks-integration.md +259 -0
  140. package/docs/user-manual/07-integrations/02-automation.md +326 -0
  141. package/docs/user-manual/08-advanced-usage/01-scripting-patterns.md +672 -0
  142. package/docs/user-manual/08-advanced-usage/02-bulk-operations.md +932 -0
  143. package/docs/user-manual/08-advanced-usage/03-ci-cd-integration.md +892 -0
  144. package/docs/user-manual/08-advanced-usage/04-performance-optimization.md +766 -0
  145. package/docs/user-manual/09-command-reference/01-config.md +776 -0
  146. package/docs/user-manual/09-command-reference/02-account.md +652 -0
  147. package/docs/user-manual/09-command-reference/03-lists.md +958 -0
  148. package/docs/user-manual/09-command-reference/04-contacts.md +1408 -0
  149. package/docs/user-manual/09-command-reference/05-attributes.md +617 -0
  150. package/docs/user-manual/09-command-reference/06-segments.md +894 -0
  151. package/docs/user-manual/09-command-reference/07-senders.md +803 -0
  152. package/docs/user-manual/09-command-reference/08-templates.md +818 -0
  153. package/docs/user-manual/09-command-reference/09-campaigns.md +1250 -0
  154. package/docs/user-manual/09-command-reference/10-emails.md +807 -0
  155. package/docs/user-manual/09-command-reference/11-reports.md +1135 -0
  156. package/docs/user-manual/09-command-reference/12-webhooks.md +773 -0
  157. package/docs/user-manual/09-command-reference/13-suppressed.md +797 -0
  158. package/docs/user-manual/09-command-reference/14-interests.md +630 -0
  159. package/docs/user-manual/09-command-reference/15-tags.md +584 -0
  160. package/docs/user-manual/09-command-reference/16-logs.md +656 -0
  161. package/docs/user-manual/09-command-reference/17-transactional-templates.md +850 -0
  162. package/docs/user-manual/10-troubleshooting/01-common-errors.md +457 -0
  163. package/docs/user-manual/10-troubleshooting/02-authentication-issues.md +558 -0
  164. package/docs/user-manual/10-troubleshooting/03-connection-problems.md +634 -0
  165. package/docs/user-manual/10-troubleshooting/04-debugging.md +725 -0
  166. package/docs/user-manual/11-appendix/04-faq.md +484 -0
  167. package/docs/user-manual/11-appendix/05-glossary.md +250 -0
  168. package/docs/user-manual/README.md +0 -0
  169. package/package.json +13 -47
  170. package/src/cli.ts +125 -0
  171. package/src/client.ts +16 -0
  172. package/src/commands/account.ts +267 -0
  173. package/src/commands/accounts.ts +78 -0
  174. package/src/commands/actions.ts +249 -0
  175. package/src/commands/attributes.ts +139 -0
  176. package/src/commands/campaign-blueprints.ts +106 -0
  177. package/src/commands/campaigns.ts +469 -0
  178. package/src/commands/config.ts +77 -0
  179. package/src/commands/contacts.ts +612 -0
  180. package/src/commands/custom-attributes.ts +127 -0
  181. package/src/commands/dkims.ts +117 -0
  182. package/src/commands/domains.ts +82 -0
  183. package/src/commands/email-apis.ts +569 -0
  184. package/src/commands/emails.ts +197 -0
  185. package/src/commands/forms.ts +283 -0
  186. package/src/commands/interests.ts +155 -0
  187. package/src/commands/links.ts +38 -0
  188. package/src/commands/lists.ts +406 -0
  189. package/src/commands/logos.ts +71 -0
  190. package/src/commands/logs.ts +386 -0
  191. package/src/commands/reports.ts +306 -0
  192. package/src/commands/segments.ts +158 -0
  193. package/src/commands/senders.ts +204 -0
  194. package/src/commands/sub-accounts.ts +271 -0
  195. package/src/commands/suppressed-emails.ts +234 -0
  196. package/src/commands/suppressed.ts +198 -0
  197. package/src/commands/system-emails.ts +85 -0
  198. package/src/commands/tags.ts +146 -0
  199. package/src/commands/tasks.ts +116 -0
  200. package/src/commands/templates.ts +189 -0
  201. package/src/commands/tokens.ts +83 -0
  202. package/src/commands/transactional-emails.ts +374 -0
  203. package/src/commands/transactional-templates.ts +385 -0
  204. package/src/commands/users.ts +506 -0
  205. package/src/commands/webhooks.ts +172 -0
  206. package/src/commands/workflow-blueprints.ts +123 -0
  207. package/src/commands/workflows.ts +265 -0
  208. package/src/types/profile.ts +93 -0
  209. package/src/utils/auth.ts +272 -0
  210. package/src/utils/config-file.ts +96 -0
  211. package/src/utils/config.ts +134 -0
  212. package/src/utils/confirm.ts +32 -0
  213. package/src/utils/defaults.ts +99 -0
  214. package/src/utils/errors.ts +116 -0
  215. package/src/utils/interactive.ts +91 -0
  216. package/src/utils/list-defaults.ts +74 -0
  217. package/src/utils/output.ts +190 -0
  218. package/src/utils/progress.ts +320 -0
  219. package/src/utils/spinner.ts +22 -0
  220. package/tests/IMPLEMENTATION_STATUS.md +258 -0
  221. package/tests/PTY_SETUP.md +118 -0
  222. package/tests/PTY_TESTING_GUIDE.md +507 -0
  223. package/tests/README.md +244 -0
  224. package/tests/fixtures/api-responses/campaigns.json +34 -0
  225. package/tests/fixtures/test-config.json +13 -0
  226. package/tests/helpers/cli-runner.ts +128 -0
  227. package/tests/helpers/mock-server.ts +301 -0
  228. package/tests/helpers/pty-runner.ts +181 -0
  229. package/tests/integration/campaigns-real-api.test.ts +196 -0
  230. package/tests/integration/setup-integration.ts +50 -0
  231. package/tests/pty/campaigns.test.ts +241 -0
  232. package/tests/setup.ts +34 -0
  233. package/tsconfig.json +15 -0
  234. 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
+