clickSomo
Открыть ClickSomo

Контакты и согласия

Список, который вы можете защитить, а не просто список, который у вас есть

Десять тысяч адресов электронной почты может держать кто угодно. Вопрос, который действительно важен — тот, который регулятор, провайдер и ваша собственная совесть задают чуть разными словами, — это откуда взялся каждый из них и на каком основании вы можете ему писать. ClickSomo превращает это в сохранённый факт, а не в то, что вам пришлось бы восстанавливать.

Идентификатор — это адрес электронной почты

Один контакт на адрес на проект — это гарантирует база данных, а не надежда на аккуратность. Адреса нормализуются при записи, а не при чтении: если нормализовать при чтении, ограничение превращается в украшение, которое пропускает и Anna@, и anna@.

Номера телефонов хранятся в формате E.164, если они есть, но телефон — это атрибут, а не идентичность. Здесь нет графа разрешения идентичностей, протокола слияния и журнала аудита слияний, потому что каждый контакт приходит по каналу, у которого уже есть адрес: импорт, форма, подписка или ваш собственный код.

Имя хранится целиком

display_name сохраняется ровно так, как было введено, и никогда не разбивается на части. Разбиение имён — фабрика ошибок: «van der Berg», «Ким Мин Джун», однословные имена, титулы и любой порядок, кроме англоязычного. А неверное разбиение всплывает в merge-теге как «Уважаемый ван,» — это хуже, чем никакой персонализации.

Структурные части существуют только для источников, которые предоставляют их уже разделёнными. Ничего не выводит их само. И имя, которое человек ввёл сам, никогда не перезаписывается более поздним CSV, случайно зафиксировавшим что-то иное: стратегия «последняя запись побеждает» позволяет победить самому небрежному импорту.

Один контактЧто хранится
  • 1ИдентичностьЭлектронная почта, нормализованная. Уникальна в рамках проекта.
  • 2ИмяХранится целиком. first_name вычисляется при отрисовке и никогда не хранится.
  • 3АтрибутыЧто угодно, в формате JSON. Ваши данные, подставляемые как attrs.*.
  • 4Теги и спискиТеги — полноценные сущности и живут в одном хранилище; списки — явное членство.
  • 5СогласиеОдна строка на канал, с правовым основанием и его подтверждением.
  • 6СобытияЖурнал с дополнением в конце (append-only) обо всём, что делал этот человек. Таблица, на которой держится весь продукт.
  • ×НикогдаНи пароля, ни хеша, ни сессии, ни API-ключа. Колонка, аутентифицирующая кого-либо, — это инцидент, а не функция.

Ограничено и арендатором, и проектом — обоими сразу

Реестр согласий

Отсутствие — это не разрешение

Одна строка на контакт на канал — электронная почта, SMS, письмо, push — каждая содержит состояние, правовое основание, источник, подтверждение, отметки времени и юрисдикцию. Контакту, у которого нет строки основания для канала, нельзя отправить ничего по этому каналу. Не «помечен как запрещённый». Нельзя.

consent

Человек активно попросил. Отправка формы с сохранённым подтверждением, двойное подтверждение (double opt-in), галочка, которую он поставил сам. Это самое сильное основание и единственное, которое может породить форма.

legitimate_interest

Лучшее, чем может оказаться импорт из CSV. Таблица не может помнить, что человек на что-то согласился, поэтому ей никогда не разрешается утверждать это — и повторная загрузка того же файла не повышает основание.

contract

Вы пишете им потому, что вы оба — стороны чего-то. Напоминание об обслуживании, уведомление о продлении — то, чего они были бы раздосадованы не получить.

Перед отправкой кампании вы видите состав оснований её аудитории: сколько из этих людей попросили сами, скольких вы достигаете на основании законного интереса и сколько здесь из-за договора. Это одно число, которое остановило больше плохих рассылок, чем любой когда-либо написанный предупреждающий баннер.

Почему это строже, чем вам требуется: дело на самом деле не в вас. Репутация массовых рассылок — общий ресурс, и одна небрежная база отравляет колодец для всех, кто отправляет с той же инфраструктуры. Уровни жалоб и отказов отслеживаются по каждому арендатору, и аккаунт, превысивший порог, ограничивается здесь — прежде чем это сделает провайдер для всех сразу.

За каждой строкой в списке стоит чьё-то «да».

Четыре пути

Каждый путь в ваш список — это вы, действующие со своими данными

Здесь нет канала приёма через сервисные токены и никакого соседнего продукта, тихо пишущего в ваши контакты. Если вы хотите видеть кого-то в списке, туда его попал один из этих четырёх путей.

Импорт CSV

Сопоставление колонка за колонкой, нормализация при записи, проверка MX, чтобы мёртвые и ошибочные домены отсеивались до жёсткого отказа в доставке, и основание, которое вы задаёте явно. Импорт получает идентификатор, и каждый созданный им контакт ссылается на него.

Форма ClickSomo

Отрисовывается из того же документа, что и всё остальное, с валидацией, honeypot-полем и ограничением частоты. Отправка формы — единственный путь, который может законно породить consent, потому что это единственный случай, когда человек присутствует лично.

Страница, созданная вами в dash-b

Конструктор дашбордов публикует страницы; форма на такой странице отправляет данные сюда с вашими учётными данными. Та же валидация, та же обработка согласия, никакой второй интеграции для поддержки.

Публичный API

POST /v1/contacts с вашим собственным токеном, семантикой upsert и поддержкой ключа идемпотентности. Ваше приложение уже знает, кто зарегистрировался; это кратчайший путь от этого факта к воронке.

Сегменты — это предикат, компилируемый

Сегмент — это сохранённое дерево предикатов по полям контактов, атрибутам, тегам, принадлежности к спискам и поведению, компилируемое в SQL и кэшируемое вместе со счётчиком. Операторы обычные — равно, не равно, в, не в, начинается с, заканчивается на, содержит, задан, не задан — и комбинируются через and, or и not на любую нужную вам глубину.

Предварительно просмотрите его перед использованием. Эндпоинт возвращает реальные контакты, поэтому на вопрос «кто здесь на самом деле» вы отвечаете, посмотрев, а не отправив и узнав.

Сегменты затем несут двойную нагрузку: как аудитория кампании, как условие на ветке воронки и как триггер сами по себе — segment_enter запускает выполнение в тот момент, когда кто-то становится подходящим.

Молчаливые постоянныеПредпросмотр сегмента · 412
  • 1Тегtags contains "regular"
  • 2Атрибутattrs.total_orders >= 3 — ваше поле, ваше название для него.
  • 3ПоведениеНет события order.paid за последние 90 дней.
  • 4СогласиеПригодное основание для e-mail. Контакты без него не входят в подсчёт, потому что им всё равно нельзя отправить.
  • iПредпросмотр412 контактов, перечислено. Пересчитывается при отправке, потому что сегмент — это вопрос, а не снимок.

Компилируется в SQLСчётчик кэшируется, ответ живой

Исключения и когда они проверяются

Исключения действуют на уровне проекта и глобально: жёсткие отказы, жалобы, отписки, ручные записи и ролевые адреса. Они проверяются в момент отправки, а затем ещё раз внутри самой службы отправки.

Второе слово и делает работу. Воронка с трёхдневным ожиданием даёт трёхдневное окно, в котором кто-то может отписаться, и система, проверившая исключения при постановке в очередь, всё равно отправит ему письмо. Проверка при отправке — это разница между уважением отписки и её записью.

Удаление работает так же: запрос на удаление убирает контакт и его историю сообщений здесь и достигает каждой родственной службы, хранившей копию, через тот же внутренний канал, которым пользуется всё семейство. Есть одно место, куда просить, и одно, что происходит.