Loading...
Loading...
Compare original and translation side by side
function processMessage(message, contact) {
// FIRST: Check for opt-out
if (isOptOut(message.content)) {
processOptOut(contact, message.channel)
return sendOptOutConfirmation(contact)
}
// THEN: Normal processing
return normalProcessing(message, contact)
}function processMessage(message, contact) {
// FIRST: Check for opt-out
if (isOptOut(message.content)) {
processOptOut(contact, message.channel)
return sendOptOutConfirmation(contact)
}
// THEN: Normal processing
return normalProcessing(message, contact)
}OPT_OUT_KEYWORDS = [
"STOP",
"UNSUBSCRIBE",
"CANCEL",
"END",
"QUIT",
"STOPALL",
"STOP ALL"
]
function isOptOut(message) {
normalized = message.toUpperCase().trim()
return OPT_OUT_KEYWORDS.includes(normalized) ||
containsOptOutPhrase(message)
}
function containsOptOutPhrase(message) {
phrases = [
"stop texting",
"stop messaging",
"remove me",
"take me off",
"opt out",
"opt-out"
]
lower = message.toLowerCase()
return phrases.some(p => lower.includes(p))
}OPT_OUT_KEYWORDS = [
"STOP",
"UNSUBSCRIBE",
"CANCEL",
"END",
"QUIT",
"STOPALL",
"STOP ALL"
]
function isOptOut(message) {
normalized = message.toUpperCase().trim()
return OPT_OUT_KEYWORDS.includes(normalized) ||
containsOptOutPhrase(message)
}
function containsOptOutPhrase(message) {
phrases = [
"stop texting",
"stop messaging",
"remove me",
"take me off",
"opt out",
"opt-out"
]
lower = message.toLowerCase()
return phrases.some(p => lower.includes(p))
}function processOptOut(contact, channel) {
// Record the opt-out
optOutRecord = {
contact_id: contact.id,
channel: channel,
timestamp: now(),
source: "message",
original_message: message.content
}
saveOptOut(optOutRecord)
// Update contact record
contact.opt_out_status[channel] = true
contact.opt_out_date[channel] = now()
saveContact(contact)
// Add to suppression list
addToSuppressionList(contact.phone || contact.email, channel)
// Cancel any scheduled messages
cancelScheduledMessages(contact.id, channel)
// Log for audit
auditLog("OPT_OUT", contact.id, channel, now())
}function processOptOut(contact, channel) {
// Record the opt-out
optOutRecord = {
contact_id: contact.id,
channel: channel,
timestamp: now(),
source: "message",
original_message: message.content
}
saveOptOut(optOutRecord)
// Update contact record
contact.opt_out_status[channel] = true
contact.opt_out_date[channel] = now()
saveContact(contact)
// Add to suppression list
addToSuppressionList(contact.phone || contact.email, channel)
// Cancel any scheduled messages
cancelScheduledMessages(contact.id, channel)
// Log for audit
auditLog("OPT_OUT", contact.id, channel, now())
}function canContact(contact, channel) {
// Check internal suppression
if (isOnInternalDNC(contact, channel)) {
return { allowed: false, reason: "internal_opt_out" }
}
// Check external registries
if (channel == "phone" || channel == "sms") {
if (isOnNationalDNC(contact.phone)) {
return { allowed: false, reason: "national_dnc" }
}
}
// Check consent status
if (!hasValidConsent(contact, channel)) {
return { allowed: false, reason: "no_consent" }
}
// Check contact frequency limits
if (exceedsFrequencyLimit(contact, channel)) {
return { allowed: false, reason: "frequency_limit" }
}
return { allowed: true }
}function canContact(contact, channel) {
// Check internal suppression
if (isOnInternalDNC(contact, channel)) {
return { allowed: false, reason: "internal_opt_out" }
}
// Check external registries
if (channel == "phone" || channel == "sms") {
if (isOnNationalDNC(contact.phone)) {
return { allowed: false, reason: "national_dnc" }
}
}
// Check consent status
if (!hasValidConsent(contact, channel)) {
return { allowed: false, reason: "no_consent" }
}
// Check contact frequency limits
if (exceedsFrequencyLimit(contact, channel)) {
return { allowed: false, reason: "frequency_limit" }
}
return { allowed: true }
}ConsentRecord = {
contact_id: string,
consent_type: "express" | "implied",
channel: "email" | "sms" | "phone",
granted_at: timestamp,
source: string, // "web_form", "verbal", "business_relationship"
proof: string, // Form submission ID, recording ID, etc.
scope: string, // What they consented to
expires: timestamp | null
}ConsentRecord = {
contact_id: string,
consent_type: "express" | "implied",
channel: "email" | "sms" | "phone",
granted_at: timestamp,
source: string, // "web_form", "verbal", "business_relationship"
proof: string, // Form submission ID, recording ID, etc.
scope: string, // What they consented to
expires: timestamp | null
}function hasValidConsent(contact, channel, purpose) {
consent = getConsentRecord(contact.id, channel)
if (!consent) return false
if (consent.expires && consent.expires < now()) return false
if (!scopeCovers(consent.scope, purpose)) return false
return true
}function hasValidConsent(contact, channel, purpose) {
consent = getConsentRecord(contact.id, channel)
if (!consent) return false
if (consent.expires && consent.expires < now()) return false
if (!scopeCovers(consent.scope, purpose)) return false
return true
}QUIET_HOURS = {
"US": { start: 21, end: 8 }, // 9pm-8am
"AU": {
weekday: { start: 20, end: 9 }, // 8pm-9am
saturday: { start: 17, end: 9 }, // 5pm-9am
sunday: "no_contact"
},
"UK": { start: 21, end: 8 }
}
function isContactAllowed(contact, channel) {
if (channel != "phone" && channel != "sms") return true
local_time = getLocalTime(contact.timezone)
region = contact.region
hours = QUIET_HOURS[region]
// ... check against current time
}QUIET_HOURS = {
"US": { start: 21, end: 8 }, // 9pm-8am
"AU": {
weekday: { start: 20, end: 9 }, // 8pm-9am
saturday: { start: 17, end: 9 }, // 5pm-9am
sunday: "no_contact"
},
"UK": { start: 21, end: 8 }
}
function isContactAllowed(contact, channel) {
if (channel != "phone" && channel != "sms") return true
local_time = getLocalTime(contact.timezone)
region = contact.region
hours = QUIET_HOURS[region]
// ... check against current time
}function scheduleMessage(contact, message, preferred_time) {
if (isContactAllowed(contact, message.channel, preferred_time)) {
return schedule(message, preferred_time)
}
// Find next allowed time
next_allowed = getNextAllowedTime(contact, message.channel)
return schedule(message, next_allowed)
}function scheduleMessage(contact, message, preferred_time) {
if (isContactAllowed(contact, message.channel, preferred_time)) {
return schedule(message, preferred_time)
}
// Find next allowed time
next_allowed = getNextAllowedTime(contact, message.channel)
return schedule(message, next_allowed)
}[Company Name]: [Message content]
Reply STOP to unsubscribe[Company Name]
[Physical Address]
You're receiving this because [reason].
Unsubscribe: [link][公司名称]: [消息内容]
回复STOP退订[公司名称]
[实体地址]
您收到此邮件是因为[原因]。
退订:[链接]AuditRecord = {
timestamp: datetime,
action_type: "contact_attempt" | "opt_out" | "consent_change",
contact_id: string,
channel: string,
details: object,
compliance_checks: [
{ check: "dnc_list", result: "pass", timestamp: datetime },
{ check: "consent", result: "pass", timestamp: datetime },
{ check: "quiet_hours", result: "pass", timestamp: datetime }
]
}AuditRecord = {
timestamp: datetime,
action_type: "contact_attempt" | "opt_out" | "consent_change",
contact_id: string,
channel: string,
details: object,
compliance_checks: [
{ check: "dnc_list", result: "pass", timestamp: datetime },
{ check: "consent", result: "pass", timestamp: datetime },
{ check: "quiet_hours", result: "pass", timestamp: datetime }
]
}