Мы продолжаем радовать вас интересными техническими решениями.

Сегодня на очереди email оповещения из банка, которые выглядят примерно так:
Pokupka, SHELL AZS OLGINO 1133, karta *347788, 23.07.11 12:09, 300.25 rub. Dostupno = 421.61 rub
или так
1000.00 RUR было списано с Вашего счета **77876.
Торговая точка: ZAO GAMMAEKSPER
Дата: 12/07/2011
Доступный баланс: 12344.11 RUR


Как вы думаете, как должна выглядеть красивая обработка таких оповещений в сервисе учета личных финансов?


Король умер


Начну с истории. Обработка email появилась в Дзен-мани больше года назад. Но тогда она обладала кучей недостатков:
  • поддерживался всего один банк;
  • на каждый счет в Дзен-мани существовал свой email-адрес и, если у вас было несколько счетов в одном банке, платежи по счетам не разделялись;
  • если банк посылал какие-нибудь уведомления, они не доходили до вас, так как сервис перехватывал все письма.

Неудобства работы с email оповещениями и успехи нашего зарубежного собрата Mint (для пользования которым вообще не требуется вводить траты и доходы (все данные он получает с банковской карты и любезно сортирует их по категориям еда, бензин, развлечения...) побудили нас переписать механизм обработки email оповещений.

Начнем с малого, увеличим поддержку банков до четырех: ВТБ24, Ситибанк, Банк «Санкт-Петербург» и Банк24.ру. Это делается умными регулярными выражениями и упорным тестированием :)

Затем первое интересное решение, оставляем один электронный адрес (dropbox). Вообще один на все счета и все банки (для одного пользователя). Различие счетов происходит по последним четырем цифрам. Пользователь вводит их на этапе создания счета:



Последнее неудобство с потерей информационных писем, мы решили путем пересылки всех сообщений на личный email пользователя. И это было очень сложным решением для нас. До этой функции мы не спрашивали электронную почту, чтобы максимально сохранить приватность такой деликатной информации как личные финансы. Сейчас у вас есть выбор, указывать почту или нет.

Этих трех улучшений, еще не достаточно для _красивого_ решения. Пользователю все еще приходится определять на что была потрачена каждая транзакция: на бензин, на обучение или на что-то другое. Предлагаю вам разгадать, что мы придумали :) Отгадка ниже под заголовком «Изюминка», а пока немного кода.

Механизм парсера


Парсер сообщений работает в два этапа:
  • определение формата письма;
  • непосредственно парсинг.

Парсить мы будет вот это письмо:
Уважаемый клиент,

1000.00 RUR было списано с Вашего счета **77876.
Торговая точка: ZAO GAMMAEKSPERT
Дата: 12/07/2011
Доступный баланс: 12344.11 RUR
Обратите внимание, что доступный баланс по текущему рублевому счету включает кредитный лимит.

Если Вы не согласны с полученной информацией, пожалуйста, свяжитесь с сотрудником CitiPhone по телефону (495) 775 75 75 (в Москве), (812) 336 75 75 (в Санкт-Петербурге), 8 (800) 700 38 38 (в др. городах РФ) в течение восьми дней.

Для получения более полной информации о наших услугах посетите наш сайт в интернете по адресу www.citibank.ru.


Для определения из какого же банка пришло письмо, и что ждать внутри мы используем следующую табличку:
id     foreign_format     check_order     marker_location      marker_pattern         datatype
43     33                 0               10                   /www\.citibank\.ru/    mail
44     33                 1               2                    /^\d/                  mail


Для каждого письма мы по очереди проверяем каждый из форматов в порядке check_order и ищем в строках marker_pattern. Как несложно проверить письмо из Ситибанка выше дает нам 33 формат.

Из второй таблички выбираем парсеры полей для 33 формата:
id    column_name     value_offset             foreign_format
49    outcome         2/^([\d\.]+)/"           33
50    datedmy         4#(\d{2}/\d{2}/\d{4})$#  33
51    payee           3/[^:]+:(.*)$/"          33


Цифра перед регекспом означаем номер строки письма. Проходим еще раз по письму и получаем нужные нам данные.

Изюминка: Автоопределение категорий


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

Сначала еще пример:
Сообщаем Вам, что 21.07.2011 в 11:12:05 по Вашей банковской карте ВТБ24 ...7780 произведена транзакция по оплате на сумму 1959.00 RUR.
Доступно к использованию: 2274.35 RUR. Детали платежа: HITZONA. Код авторизации 222635


А теперь смотрите, в каждом платеже у нас есть код магазина:
  • SHELL AZS OLGINO — Бензин.
  • HITZONA — развлечения (музыка, кино, игры).

То есть нам достаточно сопоставить коды магазина нашим категориям. Но где же взять эти данные? На помощь приходит краудсорсинг.

Каждый пользователь Дзен-мани сопоставляя платеж по карте одной из категорий делает вклад в общее дело. И мы получаем примерно такую табличку (имена категорий пользователи вводят сами).
10 SHELL AZS Бензин
3 SHELL AZS Автомобили
1 SHELL AZS Сладости


Когда пользователь получает оповещение о платеже в SHELL AZS мы ищем пересечение базы с его категориями и выбираем самую популярную. Есть категория «Бензин» — выбираем ее, если нет выбираем «Автомобили».

Другими словами, мы в Дзен-мани делаем все, чтобы облегчить вам ведение домашней бухгалтерии. На сегодня это получение данных из шести банков: Альфа-Банк, Райффайзенбанк, ВТБ24, Ситибанк, Банк «Санкт-Петербург», Банк24.ру и системы Яндекс.Деньги.

Попробуйте сегодня :)