176 lines
6.6 KiB
JavaScript
176 lines
6.6 KiB
JavaScript
const archiver = require('archiver');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
async function assemblePacket(config, clientDir) {
|
|
const zipPath = path.join(clientDir, 'compliance-packet.zip');
|
|
const output = fs.createWriteStream(zipPath);
|
|
const archive = archiver('zip', { zlib: { level: 9 } });
|
|
|
|
return new Promise((resolve, reject) => {
|
|
output.on('close', () => {
|
|
console.log(` → Zip created: ${archive.pointer()} bytes`);
|
|
resolve(zipPath);
|
|
});
|
|
|
|
archive.on('error', (err) => reject(err));
|
|
archive.pipe(output);
|
|
|
|
// Add screenshots
|
|
const screenshotsDir = path.join(clientDir, 'screenshots');
|
|
if (fs.existsSync(screenshotsDir)) {
|
|
archive.directory(screenshotsDir, 'screenshots');
|
|
}
|
|
|
|
// Create compliance packet text file
|
|
const packetText = generatePacketText(config);
|
|
archive.append(packetText, { name: 'compliance-packet.txt' });
|
|
|
|
// Create a formatted HTML version
|
|
const packetHtml = generatePacketHtml(config);
|
|
archive.append(packetHtml, { name: 'compliance-packet.html' });
|
|
|
|
// Add config
|
|
archive.append(JSON.stringify(config, null, 2), { name: 'config.json' });
|
|
|
|
archive.finalize();
|
|
});
|
|
}
|
|
|
|
function generatePacketText(config) {
|
|
const p = config.a2pPacket;
|
|
const siteUrl = config.siteUrl;
|
|
|
|
return `═══════════════════════════════════════════════════════
|
|
A2P 10DLC COMPLIANCE PACKET
|
|
${config.businessName}
|
|
Generated: ${new Date().toLocaleDateString()}
|
|
═══════════════════════════════════════════════════════
|
|
|
|
CAMPAIGN DESCRIPTION
|
|
─────────────────────
|
|
${p.campaignDescription}
|
|
|
|
SAMPLE MESSAGES
|
|
─────────────────────
|
|
Message 1:
|
|
${p.sampleMessages[0]}
|
|
|
|
Message 2:
|
|
${p.sampleMessages[1]}
|
|
|
|
Message 3:
|
|
${p.sampleMessages[2]}
|
|
|
|
OPT-IN FLOW DESCRIPTION
|
|
─────────────────────
|
|
${p.optInFlowDescription}
|
|
|
|
Website URL: ${siteUrl}
|
|
Contact/Opt-in Page: ${siteUrl}/contact
|
|
Privacy Policy: ${siteUrl}/privacy-policy
|
|
Terms of Service: ${siteUrl}/terms
|
|
|
|
OPT-IN CONFIRMATION MESSAGE
|
|
─────────────────────
|
|
${p.optInConfirmation}
|
|
|
|
OPT-OUT CONFIRMATION MESSAGE
|
|
─────────────────────
|
|
${p.optOutConfirmation}
|
|
|
|
HELP MESSAGE
|
|
─────────────────────
|
|
${p.helpMessage}
|
|
|
|
KEYWORDS
|
|
─────────────────────
|
|
Opt-in Keywords: ${p.optInKeywords}
|
|
Opt-out Keywords: ${p.optOutKeywords}
|
|
Help Keywords: ${p.helpKeywords}
|
|
|
|
CONSENT TEXT (on website form)
|
|
─────────────────────
|
|
${p.consentText}
|
|
|
|
SCREENSHOTS INCLUDED
|
|
─────────────────────
|
|
1. homepage.png - Full homepage screenshot
|
|
2. contact-optin.png - Opt-in form with consent checkbox
|
|
3. privacy-policy.png - Privacy Policy page
|
|
4. terms-of-service.png - Terms of Service page
|
|
|
|
═══════════════════════════════════════════════════════
|
|
Generated by A2P Compliance Wizard
|
|
═══════════════════════════════════════════════════════
|
|
`;
|
|
}
|
|
|
|
function generatePacketHtml(config) {
|
|
const p = config.a2pPacket;
|
|
const siteUrl = config.siteUrl;
|
|
|
|
return `<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>A2P Compliance Packet - ${config.businessName}</title>
|
|
<style>
|
|
body { font-family: -apple-system, system-ui, sans-serif; max-width: 800px; margin: 40px auto; padding: 20px; color: #1a1a2e; line-height: 1.6; }
|
|
h1 { color: #2563EB; border-bottom: 3px solid #2563EB; padding-bottom: 10px; }
|
|
h2 { color: #1e3a5f; margin-top: 30px; border-bottom: 1px solid #e2e8f0; padding-bottom: 8px; }
|
|
.field { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px; padding: 16px; margin: 12px 0; }
|
|
.field-label { font-weight: 700; color: #475569; font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; }
|
|
.field-value { color: #1e293b; }
|
|
.message-box { background: #eff6ff; border-left: 4px solid #2563EB; padding: 12px 16px; margin: 8px 0; border-radius: 0 6px 6px 0; }
|
|
a { color: #2563EB; }
|
|
.meta { color: #64748b; font-size: 14px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>A2P 10DLC Compliance Packet</h1>
|
|
<p class="meta"><strong>${config.businessName}</strong> · Generated ${new Date().toLocaleDateString()}</p>
|
|
|
|
<h2>Campaign Description</h2>
|
|
<div class="field"><div class="field-value">${p.campaignDescription}</div></div>
|
|
|
|
<h2>Sample Messages</h2>
|
|
<div class="message-box">${p.sampleMessages[0]}</div>
|
|
<div class="message-box">${p.sampleMessages[1]}</div>
|
|
<div class="message-box">${p.sampleMessages[2]}</div>
|
|
|
|
<h2>Opt-In Flow Description</h2>
|
|
<div class="field"><div class="field-value">${p.optInFlowDescription}</div></div>
|
|
|
|
<h2>Website URLs</h2>
|
|
<div class="field">
|
|
<div class="field-label">Homepage</div><div class="field-value"><a href="${siteUrl}">${siteUrl}</a></div>
|
|
<div class="field-label" style="margin-top:8px;">Contact/Opt-in</div><div class="field-value"><a href="${siteUrl}/contact">${siteUrl}/contact</a></div>
|
|
<div class="field-label" style="margin-top:8px;">Privacy Policy</div><div class="field-value"><a href="${siteUrl}/privacy-policy">${siteUrl}/privacy-policy</a></div>
|
|
<div class="field-label" style="margin-top:8px;">Terms of Service</div><div class="field-value"><a href="${siteUrl}/terms">${siteUrl}/terms</a></div>
|
|
</div>
|
|
|
|
<h2>Opt-In Confirmation Message</h2>
|
|
<div class="message-box">${p.optInConfirmation}</div>
|
|
|
|
<h2>Opt-Out Confirmation Message</h2>
|
|
<div class="message-box">${p.optOutConfirmation}</div>
|
|
|
|
<h2>Help Message</h2>
|
|
<div class="message-box">${p.helpMessage}</div>
|
|
|
|
<h2>Keywords</h2>
|
|
<div class="field">
|
|
<div class="field-label">Opt-in</div><div class="field-value">${p.optInKeywords}</div>
|
|
<div class="field-label" style="margin-top:8px;">Opt-out</div><div class="field-value">${p.optOutKeywords}</div>
|
|
<div class="field-label" style="margin-top:8px;">Help</div><div class="field-value">${p.helpKeywords}</div>
|
|
</div>
|
|
|
|
<h2>Consent Text</h2>
|
|
<div class="field"><div class="field-value">${p.consentText}</div></div>
|
|
</body>
|
|
</html>`;
|
|
}
|
|
|
|
module.exports = { assemblePacket };
|