Integrations
CI/CD Integration
Integrate Emailens into your continuous integration pipeline beyond GitHub Actions.
Generic CI (curl-based)
Any CI system can call the Emailens API:
#!/bin/bash
THRESHOLD=70
API_KEY="${EMAILENS_API_KEY}"
for file in emails/*.html; do
HTML=$(cat "$file")
RESPONSE=$(curl -s -X POST https://emailens.dev/api/preview \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d "{\"html\": $(echo "$HTML" | jq -Rs .)}")
OVERALL=$(echo "$RESPONSE" | jq '.overallScore')
if [ "$OVERALL" -lt "$THRESHOLD" ]; then
echo "FAIL: $file scored $OVERALL (threshold: $THRESHOLD)"
exit 1
fi
echo "PASS: $file scored $OVERALL"
doneGitLab CI
email-check:
stage: test
image: curlimages/curl:latest
script:
- |
for file in emails/*.html; do
HTML=$(cat "$file")
SCORE=$(curl -s -X POST https://emailens.dev/api/preview \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $EMAILENS_API_KEY" \
-d "{\"html\": $(echo "$HTML" | jq -Rs .)}" | jq '.overallScore')
echo "$file: $SCORE/100"
[ "$SCORE" -lt 70 ] && exit 1
done
only:
changes:
- emails/**/*.htmlUsing the engine directly
For faster CI (no API calls), install @emailens/engine and run analysis locally:
import { analyzeEmail, generateCompatibilityScore } from "@emailens/engine";
import { readFileSync, readdirSync } from "fs";
const files = readdirSync("emails").filter((f) => f.endsWith(".html"));
let failed = false;
for (const file of files) {
const html = readFileSync(`emails/${file}`, "utf-8");
const warnings = analyzeEmail(html);
const scores = generateCompatibilityScore(warnings);
const overall =
Object.values(scores).reduce((sum, s) => sum + s.score, 0) /
Object.values(scores).length;
if (overall < 70) {
console.error(`FAIL: ${file} scored ${Math.round(overall)}`);
failed = true;
} else {
console.log(`PASS: ${file} scored ${Math.round(overall)}`);
}
}
if (failed) process.exit(1);This approach is faster since it runs locally without network calls, but doesn't include screenshots.