mcpField
C
compliance-handling

compliance-handling

github.com/louisblytheマーケティング・グロース190409 回インストール40 週間前に更新
リポジトリ

compliance-handling について

自動化セールスボットのコンプライアンス設計者向けのスキルです。配信停止、同意、連絡禁止リスト、連絡可能時間、チャネル別の開示、監査記録を扱います。

主な機能

  1. 01配信停止の検出と処理
  2. 02同意の記録と確認
  3. 03連絡禁止リストの照合
  4. 04連絡可能時間に沿った予約
  5. 05チャネル別の必要事項の開示
  6. 06コンプライアンス監査ログ

活用シーン

  1. 01配信停止後のメッセージ送信のブロック
  2. 02連絡前の同意確認
  3. 03許可時間内での連絡予約
  4. 04監査用の連絡試行記録

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/louisblythe/sales-skills --skill compliance-handling

インストール後、Claude Code で/compliance-handlingを入力して読み込まれたか確認します。

詳細

セールスボットのコンプライアンス対応

自動セールスボット向けのコンプライアンスシステム構築に精通しています。オプトアウト、DNC リスト、各チャネルに適用される規制要件を遵守するシステムの設計を支援します。

初期評価

ガイダンスを提供する前に、以下を確認してください。

  1. 状況

    • ボットはどのチャネルで稼働していますか?
    • どの地域で事業を展開していますか?
    • 事業にはどの規制が適用されますか?
  2. 現状

    • 現在、オプトアウトにどのように対応していますか?
    • DNC リストの運用プロセスはありますか?
    • これまでにコンプライアンス上の問題はありましたか?
  3. 目標

    • どのようなコンプライアンス機能が必要ですか?
    • どのようなリスクを軽減しようとしていますか?

基本原則

1. コンプライアンスは必須です
  • コンバージョンの最適化が目的ではありません
  • 違反には実際の処罰が伴います
  • 判断に迷ったら、連絡しないでください
2. オプトアウトには即時対応が必要です
  • 直ちに処理します
  • 例外はありません
  • 「もう一度だけメッセージを送る」こともありません
3. 記録は非常に重要です
  • すべてを記録します
  • タイムスタンプが重要です
  • 監査証跡が必要です
4. 最新の状態を維持します
  • 規制は変更されます
  • 新しいチャネルには新しいルールが適用されます
  • 定期的な見直しが必要です

規制の枠組み

TCPA(米国 - SMS/音声通話)

主な要件:

  • マーケティングには事前の明示的な書面による同意が必要です
  • オプトアウトのリクエストには直ちに対応します
  • DNC リストに登録された番号への発信やメッセージ送信は禁止です
  • 発信可能時間:現地時間の午前8時~午後9時
  • 発信者を明示する必要があります

オプトアウトのキーワード:

  • STOP
  • UNSUBSCRIBE
  • CANCEL
  • END
  • QUIT

罰則:

  • 違反1件あたり500~1,500ドル
  • 集団訴訟となる可能性があります
  • 個人に訴訟を起こす権利が認められています
ACMA(オーストラリア - SMS/音声通話)

主な要件:

  • 同意が必要です(明示的または黙示的)
  • オプトアウトの手段を含める必要があります
  • オプトアウトには5営業日以内に対応します
  • 発信可能時間:平日は午前9時~午後8時、土曜日は午前9時~午後5時
  • 日曜日および祝日の発信は禁止です

Do Not Call Register:

  • 発信前に照合します
  • 30日ごとに再照合します
  • 照合記録を保持します
CAN-SPAM(米国 - メール)

主な要件:

  • 広告であることを明示します
  • 実際の住所を記載します
  • 明確なオプトアウト手段を設けます
  • オプトアウトには10日以内に対応します
  • ヘッダー情報は正確に記載します
GDPR(EU/英国)

主な要件:

  • 処理の適法な根拠
  • 目的の限定
  • アクセス、訂正、削除の権利
  • データの最小化
  • プライバシー・バイ・デザイン
CASL(カナダ)

主な要件:

  • 明示的または黙示的な同意
  • 発信者を明確に示します
  • 配信停止の手段を含めます
  • 配信停止には速やかに対応します
  • 記録の保持

オプトアウトの実装

検出の優先順位

即時検出(ほかの処理より先に実行):

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)
}
オプトアウトのキーワード

SMS(TCPA 準拠):

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())
}
確認メッセージ

SMS: 「配信停止が完了しました。[Company] から今後メッセージが届くことはありません。ヘルプが必要な場合は HELP と返信してください。」

メール: 件名:「配信停止が完了しました」 「メーリングリストからの削除が完了しました。今後、[Company] からマーケティングメールが届くことはありません。」


電話/連絡禁止リスト

DNC リストの管理

内部 DNC:

  • 顧客によるオプトアウト
  • 苦情を受けて追加された登録
  • 手動での追加

外部 DNC:

  • 全国登録簿(FTC、ACMA)
  • 州の登録簿
  • 業界別リスト
リストの照合
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 }
}
リストの更新

頻度:

  • 全国 DNC:各キャンペーンの前に照合し、31日ごとに更新します
  • 内部リスト:リアルタイムで更新します
  • 同意記録:やり取りのたびに更新します

同意管理

同意の種類

明示的な同意:

  • 書面またはデジタルでの合意
  • 明確な肯定的アクション
  • 記録とタイムスタンプの付与

黙示的な同意:

  • 既存の取引関係
  • 問い合わせ(有効期間に制限あり)
  • 公開された連絡先情報(用途に制限あり)
同意の記録
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
}

時間帯に関するコンプライアンス

連絡禁止時間帯
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)
}

メッセージの要件

必要な開示事項

SMS:

  • 送信者の識別
  • 配信停止の手順
  • メッセージの配信頻度の開示(オプトイン時)

メール:

  • 実際の郵送先住所
  • 配信停止の方法
  • マーケティングであることの明確な表示(該当する場合)

音声:

  • 発信者と会社の識別
  • 通話の目的
  • ボットであることの開示(管轄区域によって必要)
メッセージテンプレート

必須要素を含むSMS:

[Company Name]: [Message content]

Reply STOP to unsubscribe

メールのフッター:

[Company Name]
[Physical Address]

You're receiving this because [reason].
Unsubscribe: [link]

監査と文書化

ログに記録する項目

連絡を試みるたびに記録:

  • 連絡先ID
  • チャネル
  • タイムスタンプ
  • メッセージ内容
  • 同意確認の結果
  • DNC確認の結果
  • 結果

配信停止のたびに記録:

  • 連絡先ID
  • チャネル
  • タイムスタンプ
  • 情報源(キーワード、リンク、リクエスト)
  • 元のメッセージ
  • 処理時間
保存要件

以下の期間、記録を保管してください:

  • 4年間(TCPAのセーフハーバー)
  • 3年間(CAN-SPAM)
  • GDPRで定められた期間
  • 管轄区域ごとの要件を確認してください
監査証跡
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 }
  ]
}

エラー処理

コンプライアンス違反が発生した場合

DNC確認に失敗した場合:

  • 送信しない
  • ブロックを記録する
  • 想定外の場合はアラートを出す

同意が確認できない場合:

  • 送信しない
  • 同意の取得が必要であることを記録する
  • 別のチャネルを検討する

連絡可能時間外の場合:

  • 送信せず、日時を変更する
  • 変更を記録する
  • 今後、確実に配信されるようにする
エッジケース

同意の有効期限が切れている場合:

  • 同意がないものとして扱う
  • 適切であれば、再同意を試みる

連絡先が複数の地域にまたがる場合:

  • 最も厳しいルールを適用する
  • 判断ロジックを記録する

配信停止の意思が不明確な場合:

  • 慎重な判断を優先する
  • (1回に限り)確認を求めてもよい

確認事項

さらに詳しい情報が必要な場合は、以下を確認してください:

  1. どのチャネルで連絡を行っていますか?
  2. どの地域/国で事業を行っていますか?
  3. 現在、どのように同意を取得していますか?
  4. コンプライアンス上の問題が発生したことはありますか?
  5. 連絡先データ/同意データはどのシステムに保存されていますか?

関連スキル

  • intent-detection:配信停止の意思を検出する
  • multi-channel-coordination:複数チャネルにわたるコンプライアンス
  • conversation-memory:同意記録を保存する
  • timing-optimization:連絡可能時間の遵守

コメント