Данная статья может быть полезна тем кто ведет учет личных финансов в 1с деньги, и не хочет забивать операции руками.
for fun. its works.
Появилась идея не заносить руками операции в 1с деньги(далее 1сд), а загружать смс(напримере сбер банк(900)) и парсить данные по апи яндекс денег.
Конфигурация: Деньги 8, редакция 2.0 (2.0.33.13) (http://v8.1c.ru/money)
Платформа: 1С:Предприятие 8.3 (8.3.10.2650)
В процессе реализации идеи было реализовано:
1. шлюз для приема пакета смс в 1сд(http сервис)
2.модуль парсинга сообщений
3.мобильное приложение(кривое(андроид дев не мое), но со своей задачей справляется)(xamarin, android)
4.прикручен модуль обработки данных яндекс апи(//infostart.ru/public/304373)
Описание модулей 1сд:
1.Общий модуль DataSMS — модуль создания операций
2.общий модуль ЯндексДеньги — (ссылка на первоисточник:(//infostart.ru/public/304373)) — модуль работы с апи яндкс денег
3.HTTP-сервис DataSMS — шлюз приема данных с мобильного приложения
Общий принцип работы:
Для запуска процесса выгрузки необходимо запустить мобильное приложение. Мобильное приложение получает данные sms, сериализует json, отправляет в http сервис 1сд. 1сд получает пакет, запускает фоновое задание в котором:
1. создаются операции (доходрасходперемещение) по данным смс
2. получает данные с яндекс денег(при необходимости)
3. создаются операции (доходрасходперемещение) по данным яндекс денег
Пример установки:
1. Опубликовать HTTP-сервис
2. Собрать мобильное приложение (изменить при необходимости порт, адрес)(могу приложить бинарь)
3. Если есть необходимость работы с яндекс деньгами то: получить акцес токен яндекс денег(//infostart.ru/public/304373), изменить его в модуле ЯндексДеньги ф-ия ОписаниеКошелька()
Здесь стоит отметить что для получения акцесс токен нужен будет белый ип адрес(разово)
Соответствия статьи доходоврасходов тексту (смс), заголовку (для яд):
Загруженные операции:
Пример загруженной операции
Код мобильного приложения:
using Android.App;
using Android.OS;
using Android.Telephony;
using Android.Content;
using System;
using Android.Util;
using System.Net;
using System.Text;
using System.IO;
using System.Collections.Specialized;
using System;
namespace DataSMSForMoney
{
[Activity(Label = "DataSMSForMoney", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
private char n;
protected override void OnCreate(Bundle bundle)
{
string textJson = "";
string filePath = "/storage/sdcard0/logApp8/logApp8.log";
var uri = Android.Net.Uri.Parse("content://sms/inbox");
var cursor = ContentResolver.Query(uri, null, null, null, null);
textJson = textJson + "[";
while (cursor.MoveToNext())
{
textJson = textJson + "{";
for (int i = 0; i < cursor.ColumnCount; i++)
{
textJson = textJson + " " + 'u0002' + cursor.GetColumnName(i).ToString() + 'u0002' + ": " + 'u0002' +
cursor.GetString(i) + 'u0002';
if (i != cursor.ColumnCount - 1)
{
textJson = textJson + ", ";
}
//Toast.MakeText(this, cursor.GetColumnName(i).ToString()+"="+cursor.GetString(i), ToastLength.Short).Show();
}
textJson = textJson + "}";
if (!cursor.IsLast)
{
textJson = textJson + ",";
}
}
textJson = textJson + "]";
//System.IO.File.WriteAllText(filePath, textJson);
var Url = "http://192.168.1.99/Money/hs/dataSMS/load";
WebClient wc = new WebClient();
byte[] dataBytes = Encoding.UTF8.GetBytes(textJson);
byte[] responseBytes = wc.UploadData(new Uri(Url), "POST", dataBytes);
this.FinishAffinity();
}
}
}
Модуль работы с яд апи взят отсюда: //infostart.ru/public/304373
апдейт
код парсинга текста смс(900):
Функция РазобратьСообщениеСберБанк(ТекСтрока)
ОписаниеОперации = Неопределено;
ТелоСообщения = СокрЛП(ТекСтрока.body);
Если Не Найти(ТелоСообщения, "ОТКАЗ")>0 Тогда
Если Лев(ТелоСообщения, 4)="VISA" Тогда
Кошелек = Неопределено;
Сумма = Неопределено;
ВидОперации = Неопределено;
СтатьяДСОписание = Неопределено;
СтатьяДС = Неопределено;
Комментарий = Неопределено;
Комиссия = Неопределено;
Комментарий = ТелоСообщения;
КошелекТекст = Лев(ТелоСообщения, 8);
Кошелек = ПолучитьОбъектСоответствия(КошелекТекст);
ТелоСообщения = СокрЛП(Сред(ТелоСообщения, СтрДлина(КошелекТекст)+1));
ЭтоОплатаМобильногоБанка = Найти(Нрег(ТелоСообщения), "оплата мобильного банка")>0;
Если ЭтоОплатаМобильногоБанка Тогда
ВидОперации = "оплата услуг";
ДатаСообщения = СокрЛП(Сред(ТелоСообщения, 0, 8));
ТелоСообщения = СокрЛП(Сред(ТелоСообщения, СтрДлина(ДатаСообщения)+1));
СтатьяДСОписание = Сред(ТелоСообщения, 0, 48);
ТелоСообщения = СтрЗаменить(ТелоСообщения, СтатьяДСОписание, "");
ТелоСообщения = Сред(ТелоСообщения, 1, Найти(Нрег(ТелоСообщения), "баланс:")-1);
Сумма = Сред(ТелоСообщения, 1, Найти(Нрег(ТелоСообщения), "р")-1);
СтатьяДС = ПолучитьОбъектСоответствия("оплата мобильного банка");
Сумма = СтрЗаменить(Сумма, " ", "");
Иначе
ДатаСообщения = СокрЛП(Сред(ТелоСообщения, 0, 15));
ТелоСообщения = Сред(ТелоСообщения, СтрДлина(ДатаСообщения));
Если Найти(Нрег(ТелоСообщения), "оплата услуг")>0 Тогда
ВидОперации = "оплата услуг";
ИначеЕсли Найти(Нрег(ТелоСообщения), "оплата")>0 Тогда
ВидОперации = "оплата";
ИначеЕсли Найти(Нрег(ТелоСообщения), "покупка")>0 Тогда
ВидОперации = "покупка";
ИначеЕсли Найти(Нрег(ТелоСообщения), "зачисление")>0 Тогда
ВидОперации = "зачисление";
ИначеЕсли Найти(Нрег(ТелоСообщения), "списание")>0 Тогда
ВидОперации = "списание";
ИначеЕсли Найти(Нрег(ТелоСообщения), "выдача наличных")>0 Тогда
ВидОперации = "выдача наличных";
ИначеЕсли Найти(Нрег(ТелоСообщения), "выдача")>0 Тогда
ВидОперации = "выдача";
КонецЕсли;
Если Не ВидОперации=Неопределено Тогда
ТелоСообщения = Сред(ТелоСообщения, (Найти(Нрег(ТелоСообщения), ВидОперации))+СтрДлина(ВидОперации));
Сумма = Сред(ТелоСообщения, 1, Найти(Нрег(ТелоСообщения), "р")-1);
ЕстьКомиссия = Найти(Нрег(ТелоСообщения), "с комиссией")-1;
Если ЕстьКомиссия>0 Тогда
ТекстКомиссия = СокрЛП(Сред(ТелоСообщения, Найти(Нрег(ТелоСообщения), "р")+1));
Комиссия = Сред(ТекстКомиссия, 13, Найти(Нрег(ТелоСообщения), "р")-1);
КонецЕсли;
СтатьяДСОписание = СокрЛП(Сред(ТелоСообщения, (Найти(Нрег(ТелоСообщения), "р"))+1));
СтатьяДСОписание = СокрЛП(Сред(СтатьяДСОписание, 0 ,(Найти(Нрег(СтатьяДСОписание), "баланс:"))-1));
СтатьяДСОписание = СокрЛП(СтрЗаменить(СтатьяДСОписание, Сумма+"р", ""));
СтатьяДС = ПолучитьОбъектСоответствия(СтатьяДСОписание);
Сумма = СтрЗаменить(Сумма, " ", "");
КонецЕсли;
КонецЕсли;
ОписаниеОперации = Новый Структура;
ОписаниеОперации.Вставить("Кошелек", Кошелек);
ОписаниеОперации.Вставить("Комментарий", Комментарий);
ОписаниеОперации.Вставить("ДатаСообщения", ДатаСообщения);
ОписаниеОперации.Вставить("Сумма", Сумма);
ОписаниеОперации.Вставить("ВидОперации", ВидОперации);
ОписаниеОперации.Вставить("СтатьяДСОписание", СтатьяДСОписание);
ОписаниеОперации.Вставить("СтатьяДС", СтатьяДС);
ОписаниеОперации.Вставить("Комиссия", Комиссия);
КонецЕсли;
КонецЕсли;
Возврат ОписаниеОперации;
КонецФункции
код парсинга текста смс агропромкредитбанк:
Функция РазобратьСообщениеАгроПромКредитБанк(ТекСтрока)
ОписаниеОперации = Неопределено;
ТелоСообщения = СокрЛП(ТекСтрока.body);
Если Не Найти(ТелоСообщения, "ОТКАЗ")>0 Тогда
Комментарий = ТелоСообщения;
Сумма = Неопределено;
ВидОперации = Неопределено;
СтатьяДСОписание = Неопределено;
СтатьяДС = Неопределено;
Кошелек = Неопределено;
Если СокрЛП(Сред(ТелоСообщения, 0, 1))="+" Тогда
ВидОперации = "зачисление";
ТелоСообщения = Сред(ТелоСообщения, 2);
ИначеЕсли СокрЛП(Сред(ТелоСообщения, 0, 1))="-" Тогда
ВидОперации = "покупка";
ТелоСообщения = Сред(ТелоСообщения, 2);
КонецЕсли;
Если Не ВидОперации=Неопределено Тогда
ТелоСообщения = СокрЛП(Сред(ТелоСообщения, 0, Найти(ТелоСообщения, ". Dostupno")-1));
ДатаСообщения = СокрЛП(Прав(ТелоСообщения, 19));
ТелоСообщения = СокрЛП(СтрЗаменить(ТелоСообщения, ДатаСообщения, ""));
Если Не ВидОперации=Неопределено Тогда
Сумма = СокрЛП(Сред(ТелоСообщения, 0, Найти(ТелоСообщения, "RUR -")-1));
ТелоСообщения = СтрЗаменить(ТелоСообщения, Сумма+" RUR -", "");
СтатьяДСОписание = ТелоСообщения;
КошелекТекст = СокрЛП(Сред(ТелоСообщения, 0, Найти(ТелоСообщения, "-")-1));
Кошелек = ПолучитьОбъектСоответствия(КошелекТекст);
СтатьяДСТекст = СокрЛП(СтрЗаменить(ТелоСообщения, КошелекТекст, ""));
СтатьяДС = ПолучитьОбъектСоответствия(СокрЛП(Сред(СтатьяДСТекст, 2)));
Сумма = СтрЗаменить(Сумма, " ", "");
КонецЕсли;
ОписаниеОперации = Новый Структура;
ОписаниеОперации.Вставить("Кошелек", Кошелек);
ОписаниеОперации.Вставить("Комментарий", Комментарий);
ОписаниеОперации.Вставить("ДатаСообщения", ДатаСообщения);
ОписаниеОперации.Вставить("Сумма", Сумма);
ОписаниеОперации.Вставить("ВидОперации", ВидОперации);
ОписаниеОперации.Вставить("СтатьяДСОписание", СтатьяДСОписание);
ОписаниеОперации.Вставить("СтатьяДС", СтатьяДС);
КонецЕсли;
КонецЕсли;
Возврат ОписаниеОперации;
КонецФункции
код парсинга яндекс денег(апи):
Функция РазобратьСообщениеЯндексДеньги(ТекСтрока)
ДанныеЗаписи = ТекСтрока.data;
ОписаниеОперации = Неопределено;
type = ДанныеЗаписи["type"];
status = ДанныеЗаписи["status"];
ЭтоУспешнаяОперация = status="success";
СтатьяДСОписание = СокрЛП(ДанныеЗаписи["title"]);
ЭтоЗачислениеСберБанк = СтатьяДСОписание="Сбербанк, пополнение";
Если ЭтоЗачислениеСберБанк Тогда
Возврат ОписаниеОперации;
КонецЕсли;
Если ЭтоУспешнаяОперация Тогда
Кошелек = ОсновнойКошелекЯндексДенег();
Сумма = Неопределено;
ВидОперации = Неопределено;
СтатьяДС = Неопределено;
Комментарий = Неопределено;
Комиссия = Неопределено;
Комментарий = ДанныеЗаписи["title"];
Если type="payment-shop" Тогда
ВидОперации = "покупка";
ИначеЕсли type="deposition" Тогда
ВидОперации = "зачисление"
КонецЕсли;
ДатаСообщения = СтрЗаменить(ДанныеЗаписи["datetime"], "T", " ");
ДатаСообщения = СтрЗаменить(ДатаСообщения, "Z", " ");
ДатаСообщения = СтрЗаменить(ДатаСообщения, "-", " ");
ДатаСообщения = СтрЗаменить(ДатаСообщения, ":", " ");
ДатаСообщения = СтрЗаменить(ДатаСообщения, " ", "");
ДатаСообщения = Дата(ДатаСообщения);
Сумма = ДанныеЗаписи["amount"];
СтатьяДС = ПолучитьОбъектСоответствия(СтатьяДСОписание);
ОписаниеОперации = Новый Структура;
ОписаниеОперации.Вставить("Кошелек", Кошелек);
ОписаниеОперации.Вставить("Комментарий", Комментарий);
ОписаниеОперации.Вставить("ДатаСообщения", ДатаСообщения);
ОписаниеОперации.Вставить("Сумма", Сумма);
ОписаниеОперации.Вставить("ВидОперации", ВидОперации);
ОписаниеОперации.Вставить("СтатьяДСОписание", СтатьяДСОписание);
ОписаниеОперации.Вставить("СтатьяДС", СтатьяДС);
ОписаниеОперации.Вставить("Комиссия", Комиссия);
КонецЕсли;
Возврат ОписаниеОперации;
КонецФункции
Каким образом система узнаёт, по какой СМС нужно создать документы расход, доход, перемещение или вообще не создавать?
Как вычлиняется из СМС сумма, дата операции, «объект data SMS» (Ваш термин)?
«объект data SMS» (Ваш термин) — да, из смс парситься текст код открыт, оттуда же и вид операции, например сбер пишет что то вроде «покупка, оплата и тд», там если проанализовать
для яд в пакете будет вид операций уже.
(2) Но СМС — это просто текстовая строка. Интересно каким способом производится парсинг (код скачать не могу)? Парсинг зашит в коде или есть какой-то универсальный механизм?
зашит в коде там просто все относительно по формату, могу отдельно в статью добавить код
+(4) обновил статью
Можно было не писать приложение для андроид, а воспользоваться Automate. Там настраивается просто, как карта маршрута бизнес-процесса.
(6) оно умеет ли в getpost? в доке не нашел
(7) да, умеет.
(4) Я делаю вот такhttps://infostart.ru/public/829677/ . Возможно Вам будет интересно, особенно Этап 2. Не нужно будет хардкодить парсинг.