Ноя
11

Получение информации о балансе на банковском счёте бесплатно, по СМС

Автор Flashback    Рубрики Статьи, книги     Теги

В организации, где я работаю, зарплата всем сотрудникам начисляется на пластиковую карту, которая привязана к счёту в банке (не буду его называть). И вот, в те дни, когда ожидается поступление получки/аванса, среди народа наблюдается легкий ажиотаж, — интересно же знать, — упали уже деньги на счёт, и можно ли идти и начинать потрошить банкомат :)

У банка имеется услуга SMS уведомления о движениях средств на счетах, но эта услуга — платная, за эсэмэску, что вам перечислили деньги, банк забирает со счёта 30 рублей, поэтому у многих она не подключена.

Я тоже эту услугу себе не подключал, а зачем? проще зайти на сайт банка, в личный кабинет с компа и посмотреть, всё что нужно, бесплатно, да и дома, под кроватью, всегда валяется пара-тройка мешков с наличностью на черный день, :), так что нет необходимости наведываться к банкомату сразу же после поступления зарплаты. Но чисто из спортивного интереса, решил сделать себе возможность бесплатно получать СМС уведомления о своём текущем счёте, когда нет доступа к домашнему компьютеру.

Была написана программа, которая после запуска на домашнем компе,который у меня всегда в режиме онлайн, логинится в мой аккаунт на сайте банка и в реальном времени следит за изменениями баланса на счету; в случае, если значение баланса меняется в любую сторону, программа отсылает письмо с данными: баланс — время изменения, на ящик mail.ru. На ящике mail.ru, куда приходит письмо, включена опция информировать о новых письмах на мобильный телефон, в итоге, на указанный телефон приходит бесплатная СМС с нужной информацией.

интерфейс программы

Прога написана на Delphi 7, с компонентами Indy из стандартной поставки — девятой версии. Используемые компоненты: TWebBrowser — для работы с сайтом, IdSMTP (вкладка Indy Clients), IdMessage (вкладка Indy Misc) — для отправки почты, TTimer и TLabel, несколько штук. Ниже, алгоритм работы и примеры кода с пояснениями.

Чтобы авторизоваться на сайте, открываем страницу входа в TWebBrowser, с помощью этого компонента, определяем поля для ввода имени и пароля, подставляем в них нужные значения и передаём post запрос. Компонент IdHTTP здесь применить не получится, на странице авторизации используется javascript, который дополнительно шифрует имя-пароль при отправке запроса на сервер и формирует значение скрытых полей, которые также передаются в post запросе. Ктому же, если грузить страницу через Indy то сайт скорее всего выдаст сообщение "Ваш браузер не поддерживает 128 бит". Алгоритм авторизации обрабатывается в процедуре FormShow, сразу при старте приложения без всяких дополнительных кнопок, это сделано, чтобы программа могла работать в автоматическом режиме, например после запуска из внешнего планировщика

procedure TForm1.FormShow(Sender:TObject);
var
ovElements: OleVariant;
i,t:Integer;
begin
WebBrowser1.Navigate(‘https://user.bank.ru’); // страница авторизации
t:=GetTickCount()+20000; //ждём 20 сек, чтобы страница успела загрузиться
repeat
Application.ProcessMessages;
Label1.Caption:=’Соединение с сервером….’;
until
GetTickCount() >= t;
begin

//ищем в коде страницы поля ввода логина и пароля
ovElements := WebBrowser1.OleObject.Document.forms.item(0).elements;
for i := 0 to (ovElements.Length — 1) do
begin
if ovElements.item(i).type = ‘text’ then
begin
ovElements.item(i).value:= ‘mylogin’;// вводим свой логин
end;
begin
if ovElements.item(i).type = ‘password’ then
begin
ovElements.item(i).value:= ‘mypass’;// вводим свой пароль
end;
begin
if ovElements.item(i).tagName = ‘INPUT’ then
begin
ovElements.item(i).Click; //кликаем по кнопке входа
Label1.Caption:=’Обработка данных..’;
{ авторизовались включаем таймер,(по умолчанию отключенный при запуске приложения)
в процедуре таймера будет поизводиться обновление и анализ данных после входа в аккаунт}

Timer1.Enabled:=true;
end;
end;
end;
end;
end;
end;

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

Состояние счета на 12.05.2013 15:37:49

Всего на счете

 

99 241,50

Доступно для операций по картам (в том числе, кредитный лимит)

99 241,50

Заблокировано по авторизованным транзакциям*

0,00

В следующей процедуре считываем в тексте значение суммы, по таймеру периодически обновляем страницу (я выставил период срабатывания таймера — 60 секунд), и если значение изменилось, инициализируем отправку письма.

переменные s , Doc ,которые используются в процедуре были объявлены в секции public

…………………………

public
{ Public declarations }
Doc:IHTMLDocument2;
s:string;
end;

……………………………


procedure TForm1.Timer1Timer(Sender:TObject);
var
tp1,mp1,mp2:Integer;
timecurr,money:string;//переменные для текущего времени и суммы

begin
Sleep(1000);
WebBrowser1.Refresh; //обновление страницы
beep; //звуковой сигнал, даёт понять, что страница обновилась
Sleep(2000);
Doc:= WebBrowser1.Document as IHTMLDocument2;
s:=Doc.body.innerTEXT; //получение доступа к тексту страницы
//считываем текущее время и сумму
tp1:=AnsiPos(‘Состояние счета на’,s);
timecurr:= Copy(s,tp1+30,8);
Label2.Caption:=’ОБНОВЛЕНО В ‘+timecurr;
mp1:=AnsiPos(‘Всего на счете’,s);
mp2:=AnsiPos(‘Доступно для операций’,s);
money:= Copy(s,mp1+14,(mp2-2)-(mp1+14));
if Label3.Caption=» then
//при первом заходе на сайт в Label пусто
begin
Label3.Caption:=money;// записываем туда сумму счёта и после каждого обновления страницы
end;
sleep(2000);
if money <> Label3.Caption then// сравниваем старое значение с новым
//если не совпало,запускаем отправку письма

begin
IdSMTP1.Host:=’smtp.mail.ru’;// сервер исходящей почты mail.ru
IdSMTP1.Port:=25;// порт исходящей почты mail.ru
IdSMTP1.Username:=’mymaillogin’;// логин ящика mail.ru
IdSMTP1.Password:=’mymailpass’;// пароль ящика mail.ru
IdSMTP1.AuthenticationType:=atLogin;// авториация на сервере mail.ru
with IdMessage1 do
begin
IdMessage1.Body.Text:= ‘Состояние счёта на: ‘+timecurr;// текст письма
idMessage1.From.Name:=money;// имя отправителя,здесь вставляем сумму на счёте
IdMessage1.From.Address:=’user@box.ru’;// от кого,тот же ящик,через который отправляем
IdMessage1.Recipients.EMailAddresses:=’user@box.ru’;// кому,тот же ящик,через который отправляем
IdMessage1.Subject:= money;// тема письма
end;
Application.ProcessMessages;
IdSMTP1.Connect;
try
Label5.Caption:=’Отправка письма..’;
IdSMTP1.Send(IdMessage1);
finally
IdSMTP1.Disconnect;
Label5.Caption:=»;
sleep(10000);
close;// после отправки письма прога закрывается
//если была поставлена задача просто информировать о факте поступления денег на счёт
//то лучше сразу завершить программу, чтобы не держать слишком долго открытую сессию
end;
end;
end;
end.

Вот полный текст исходника со всеми используемыми модулями

unit Unit1;

interface

uses

Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,

Dialogs,StdCtrls,OleCtrls,SHDocVw,Activex,XPMan,MSHTML,ExtCtrls,

IdComponent,IdTCPConnection,IdTCPClient,IdMessageClient,IdSMTP,

IdBaseComponent,IdMessage;

type

TForm1 = class(TForm)

WebBrowser1:TWebBrowser;

Label1:TLabel;

XPManifest1:TXPManifest;

Timer1:TTimer;

Label2:TLabel;

Label3:TLabel;

Label4:TLabel;

IdMessage1:TIdMessage;

IdSMTP1:TIdSMTP;

Label5:TLabel;

Label6:TLabel;

Panel1:TPanel;

Label7:TLabel;

Label8:TLabel;

Label9:TLabel;

procedure Timer1Timer(Sender:TObject);

procedure FormShow(Sender:TObject);

private

{ Private declarations }

public

{ Public declarations }

Doc:IHTMLDocument2;

s:string;

end;

var

Form1:TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormShow(Sender:TObject);

var

ovElements: OleVariant;

i,t:Integer;

begin

WebBrowser1.Navigate(‘https://user.bank.ru’);

t:=GetTickCount()+20000;

repeat

Application.ProcessMessages;

Label1.Caption:=’Соединение с сервером….’;

until

GetTickCount() >= t;

begin

ovElements := WebBrowser1.OleObject.Document.forms.item(0).elements;

for i := 0 to (ovElements.Length — 1) do

begin

if ovElements.item(i).type = ‘text’ then

begin

ovElements.item(i).value:= ‘mylogin’;

end;

begin

if ovElements.item(i).type = ‘password’ then

begin

ovElements.item(i).value:= ‘mypass’;

end;

begin

if ovElements.item(i).tagName = ‘INPUT’ then

begin

ovElements.item(i).Click;

Label1.Caption:=’Обработка данных..’;

Timer1.Enabled:=true;

end;

end;

end;

end;

end;

end;

procedure TForm1.Timer1Timer(Sender:TObject);

var

tp1,mp1,mp2:Integer;

timecurr,money:string;

begin

Sleep(1000);

WebBrowser1.Refresh;

beep;

Sleep(2000);

Doc:= WebBrowser1.Document as IHTMLDocument2;

s:=Doc.body.innerTEXT;

tp1:=AnsiPos(‘Состояние счета на’,s);

timecurr:= Copy(s,tp1+30,8);

Label2.Caption:=’ОБНОВЛЕНО В ‘+timecurr;

mp1:=AnsiPos(‘Всего на счете’,s);

mp2:=AnsiPos(‘Доступно для операций’,s);

money:= Copy(s,mp1+14,(mp2-2)-(mp1+14));

if Label3.Caption=» then

begin

Label3.Caption:=money;

end;

sleep(2000);

if money <> Label3.Caption then

begin

IdSMTP1.Host:=’smtp.mail.ru’;

IdSMTP1.Port:=25;

IdSMTP1.Username:=’mymaillogin’;

IdSMTP1.Password:=’mymailpass’;

IdSMTP1.AuthenticationType:=atLogin;

with IdMessage1 do

begin

IdMessage1.Body.Text:= ‘Состояние счёта на: ‘+timecurr;

idMessage1.From.Name:=money;

IdMessage1.From.Address:=’user@box.ru’;

IdMessage1.Recipients.EMailAddresses:=’user@box.ru’;

IdMessage1.Subject:= money;

end;

Application.ProcessMessages;

IdSMTP1.Connect;

try

Label5.Caption:=’Отправка письма..’;

IdSMTP1.Send(IdMessage1);

finally

IdSMTP1.Disconnect;

Label5.Caption:=»;

sleep(10000);

close;

end;

end;

end;

end.

В параметре IdMessage1.From.Address обязательно следует ставить реально существующий почтовый адрес, иначе сервер mail.ru не даст ничего отправить — так у них работает антиспам, в IdMessage1.Recipients.EMailAddresses тоже лучше использовать реальный адрес.

СМС , которое приходит от mail.ru имеет такой вид: имя отправителя, адрес, ссылка на письмо, тема письма не показана, поэтому в параметр idMessage1.From.Name подставляем значение суммы на счёте, если интересно узнать, сколько конкретно у нас стало денег, а не только факт пополнения или (не дай бог!) списания. Ну можно, конечно, и ссылку открыть, но тогда теряется весь смысл затеи, у меня ,например, сразу 20 р списывается с баланса телефона за выход в интернет.

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

И ещё, чтобы исключить доступ посторонних к странице, открытой в WebBrowser, размеры компонента заданы минималыми, у меня он получился 9х17 пикселей, а чтобы он был полностью невидим, поверх него расположен компонент TPanel.

Автор: Veterock
Источник: http://veterock.com/blog/blog.php?page=5

Написать комментарий

XHTML: Вы можете использовать эти теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>