Письмо с купоном: все тонкости настройки в ExpertSender

Дмитрий Барсуков

Эксперт по цифровому маркетингу

Ниже мы написали подробную инструкцию по настройке купонов в ExpertSender.

1. Создание таблицы с купонами

Начнем с того, что от маркетолога нам понадобится только список купонов и всё. Задача ExpertSender — выбрать любой купон, записать за ним емейл и затем подставить купон в письме. 
Разделим на несколько этапов наш путь.

Для хранения списка купонов в ExpertSender используем таблицу. Мы рассмотрим наиболее подробный вариант настройки, поэтому давайте создадим таблицу с четырьмя столбцами:  купон, емейл, дата присвоения, факт использования (да/нет). Выглядит она так :

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

Можно использовать таблицу даже с одним столбцом — купоном — но нам же лучше, если мы будем знать, кому, когда и какой купон подставился.

2. Код, который всё делает в письме

Вся основная работа происходит в текстовой версии письма. 

А почему? Потому, что текстовая исполняется раньше HTML.

А мы ответственные отправители и хотим купон и в текстовую версию вставить для тех, кто смотрит письма на пейджере.

А почему мы про это говорим? Потому что уже не раз клиенты переносили письма и начисто забывали про кусок кода в текстовой версии. Будьте ответственными и помните. 

2. 1. Платформа находит в таблице первый попавшийся купон с пустым значением в столбце «email». Забирает этот купон в письмо и удаляет его из таблицы.

Строка кода такая:

<var coupons="GetAndDeleteRow('coupons', null, new [] {new Filter('email', EQ, '')})"></var>

2.2. Затем добавляет в таблицу новую строку, в которую записывает емейл подписчика, купон, который забрал из таблицы в пункте 1, дату отправки сообщения — она же дата присвоения купона и логическое поле: активирован или нет — мы передаем ноль(нет), так как купон еще никто не активировал:

 ${InsertRow('coupons', new string[] {'coupons', 'email', ‘date’, ‘is_active’}, new object[] {coupons['coupon'], SubscriberEmail, MessageShortDate, 0})}

Вы спросите: зачем удалять и добавлять строку? Странный способ развлечься, когда на ютубе не все видео с котиками просмотрены.

А мы ответим: если рассылать стандартное письмо, это единственный способ избежать ситуации, в которой сразу нескольким подписчикам (которым параллельно генерируются письма) отправится один и тот же промокод, а в таблице присвоится только одному из них, и вся затея пойдет тем самым котикам из ютуба под хвост.

В текстовой версии можно еще вывести сам купон строкой:

${coupons['coupon']}

2.3. Теперь подставляем купон в html-версию письма. Так как html-версия генерируется после текстовой, то обращаться к таблице coupons придется еще раз. Нам не требуется уже брать новый купон с пустым полем «email». Сейчас нам нужно взять все строки из таблицы, где емейл равен емейлу подписчика:

<var coupons="GetRows('coupons', null, null, new [] {new Filter('email', EQ, SubscriberEmail)})"/> 

Сам купон подставим строкой

${coupons[0]['coupon']}

Стоит заметить, что в текстовой версии мы подставляем купон иначе:

${coupons['coupon']}

Тут мы не подставляем цифру ноль. Эта цифра нам говорит, какую по счету строчку мы взяли из таблицы и счет идет с нуля. В текстовой версии мы используем метод GetAndDeleteRow, который забирает и удаляет из таблицы строку. Так как мы это делаем только с одной строкой, то нам не нужно указывать ее номер. Она там сразу одна.

А если отправить письмо на тот же емейл еще раз?

Тогда этот емейл запишется к другому промокоду, и в таблице будет две строчки с одним и тем же емейлом, но с разными купонами. Чтобы этого избежать, мы можем добавить сортировку по дате присвоения купона. Тогда нам будет показывался всегда тот купон, который мы присвоили последним или первым. Для этого нужно добавить к прошлой строке кода параметр:

<var coupons="GetRows('coupons', null, null, new [] {new Filter('email', EQ, SubscriberEmail)}, new[] {new Order('date', DESC)})"/> 

А если отправить два письма в один день?

Ой-ёй. В таблице будут две строки с купоном, и дата у них будет одинаковая. Ситуация редкая, но решаемая. Для этого мы запишем в таблицу не только дату отправки, но и время. Изменится только переменная даты (с «сегодня» на «сейчас») в строке записи купона с емейлом в таблицу:

${InsertRow('coupons', new string[] {'coupons', 'email', ‘date’, ‘is_active’}, new object[] {coupons['coupon'], SubscriberEmail, System.DateTime.Now.ToString('yyyy-MM-dd HH:mm:ss'), 0})}

В таблице нужно также изменить тип столбца на тип «дата и время»: 

Теперь у нас есть время подстановки купона, и при параметре {new Order(‘date’, DESC)} всегда будет подставляться последний купон.

Что делать, чтобы подписчик мог получить только один купон?

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

Чтобы проверить емейл, нам нужно сначала взять из таблицы строки с фильтром по емейлу. Весь код будет выглядеть так: 

<var coupons="GetRows('coupons', null, null, new [] {new Filter('email', EQ, SubscriberEmail)})"/> <!-- взяли строки из таблицы и отфильтровали их по емейлу -->

<if condition="coupons.Count == 0"> <!-- Проверяем, если таких строк нет, то действуем по стандартной схеме - забираем купон с пустым емейлом и удаляем его из таблицы -->

<var emptyCoupon="GetAndDeleteRow('coupons', null, new [] {new Filter('email', EQ, '')})"/> 

<!-- а затем добавляем его в таблицу уже с емейлом и датой-->
${InsertRow('coupons', new string[] {'coupons', 'email', 'date', 'is_active'}, new object[] {emptyCoupon['coupon'], SubscriberEmail, MessageShortDate, 0})}

<p>Вот твой купон, друг - ${emptyCoupon['coupon']}</p>
</if>
<else>
<!--Если купон уже есть, то подставляем его -->
<p>Вот твой купон, друг - ${coupons[0]['coupon']}</p>
</else>

В HTML-версии мы этих условий не делаем, просто подставляем тот купон, который был изначально в таблице.

Есть нюансы у писем с веб-версией?

Если у письма есть веб-версия, то при её открытии код в текстовой части будет срабатывать заново. Соответственно, каждый раз, когда кто-то будет нажимать веб-версию или просто переходить по ссылке на веб-версию, всегда будут появлятся новые строки с этим емейлом в таблице. 

Как этого избежать. Нам снова нужно задать условие в текстовой версии письма. Мы можем проверять, открыта веб-версия сейчас или нет: 

<if condition="!(IsViewInBrowser)"> <!-- Проверяем, если сейчас не веб-версия,  идем в условии по обычной схеме -->

<var emptyCoupon="GetAndDeleteRow('coupons', null, new [] {new Filter('email', EQ, '')})"/> 

<!-- а затем добавляем его в таблицу уже с емейлом и датой-->
${InsertRow('coupons', new string[] {'coupons', 'email', 'date', 'is_active'}, new object[] {emptyCoupon['coupon'], SubscriberEmail, MessageShortDate, 0})}

<p>Вот твой купон, друг - ${emptyCoupon['coupon']}</p>
</if>
<else> <!--Если сейчас веб-версия, мы просто подставляем купон, который есть уже. Причем можно сделать сортировку, чтобы показался последний купон-->
<var coupons="GetRows('coupons', null, null, new [] {new Filter('email', EQ, SubscriberEmail)}, new[] {new Order('date', DESC)})"/> 
<!--Если купон уже есть, то подставляем его -->
<p>Вот твой купон, друг - ${coupons[0]['coupon']}</p>
</else>

Вот так выглядит готовое письмо в платформе ExpertSender:

А вот письмо в ящике:

Купоны — это не страшно для маркетолога и приятно для подписчика. Используйте купоны, а с настройкой мы вам поможем 🙂

P.S. Не хочется вас разочаровывать, но этот промокод уже потрачен (не нами). 

Согласен

Мы используем файлы cookie для записи информации о сеансе, например, прошлой активности на сайте, чтобы обеспечить лучший сервис, когда посетители возвращаются на наш сайт или настраивают содержимое веб-страницы на основе типа браузера посетителей. Используя веб-сайт, вы выражаете свое согласие с нашей политикой cookie. Вы можете изменить настройки файла cookie в своем веб-браузере.