
Сегодня на очереди 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.ру и системы Яндекс.Деньги.
Попробуйте сегодня :)