| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- use Modern::Perl;
- use Data::Dumper;
- use Mojo::Base -strict, -signatures;
- use FSA::Rules;
- our $redis;
- our $config;
- our $client;
- our $commands;
- our $kb_menu;
- my %main = (
- logged_out => {
- rules => [
- logged_out => sub($state, $line, $chatid, $rest)
- {
- if ($line ne "/start")
- {
- notify($chatid, _("Для начала работы наберите <b>/start</b>"), $rest);
- return 1;
- }
- return undef;
- },
-
- dummy => sub($state, $line, $chatid, $rest)
- {
- my $res = $client->get("client", "/telegram/$chatid/client");
- if (my $err = $client->error)
- {
- if ($err->{code}==410)
- {
- reply($rest, _("Вас приветствует провайдер") . " " . $config->{provider});
- reply($rest, _("Введите номер учетной записи или логин"));
- $state->result("ask_login");
- }
- else
- {
- report($chatid, $err);
- $state->result("error");
- }
- }
- else
- {
- $state->result("logined");
- $state->notes(uid => $res->{uid});
- }
-
- return undef;
- },
-
- needs_login => sub($state, $line, $chatid, $rest)
- {
- return $state->result eq "ask_login";
- },
-
- logged_out => sub($state, $line, $chatid, $rest)
- {
- return $state->result eq "error";
- },
- command => 1,
- ],
- },
- needs_login => {
- rules => [
- needs_password => sub($state, $login, $chatid, $rest)
- {
- $state->notes(login => $login);
- reply($rest, _("Теперь введите пароль"));
- 1;
- },
- ],
- },
- needs_password => {
- rules => [
- logged_out => sub($state, $password, $chatid, $rest)
- {
- my $login = $state->notes("login");
- my $res = $client->post("client", "/telegram/client", {login=>$login, password=>$password, telegram_id=>$chatid});
- $state->notes(login => undef);
- if (my $err = $client->error)
- {
- report($chatid, $err);
- return 1;
- }
-
- my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
- my $greet = $hour>=4 && $hour<=10 ? _("Доброе утро") : $hour>10 && $hour<6 ? _("Добрый день") : _("Добрый вечер");
- reply($rest, "$greet, " . $res->{fio});
- $state->notes(uid => $res->{uid});
- return undef;
- },
- command => 1,
- ],
- },
-
- command => {
- rules => [
- command => sub($state, $line, $chatid, $rest)
- {
- do_command($line, $chatid, $rest);
- 1;
- }
- ],
- },
-
- dummy => {
- },
- );
- our $fsa = FSA::Rules->new(%main);
- sub report($chatid, $err)
- {
- if ($err->{code}>=400 && $err->{code}<500 && ref $err->{body} eq "HASH")
- {
- notify($chatid, $err->{body}->{text_ru});
- }
- else
- {
- my $code = int(rand(10000));
- say STDERR "====== $code";
- say STDERR Dumper $err;
- notify($chatid, _("Ошибка авторизации. Сообщите в службу технической поддержки код") . " $code");
- }
- }
- ######################
-
- sub save_fsa_state($id)
- {
- my $ks = make_key($id, "state");
- my $kn = make_key($id, "notes");
- $redis->set($ks, $fsa->curr_state->name);
- $redis->expire($ks, 3600*24);
- $fsa->notes(chatid => undef);
- say "saving state ", $fsa->curr_state->name, Dumper map { ($_, $fsa->notes->{$_}) } grep { defined $fsa->notes->{$_} } keys %{ $fsa->notes };
- $redis->hmset($kn, map { ($_, $fsa->notes->{$_}) } grep { defined $fsa->notes->{$_} } keys %{ $fsa->notes });
- $redis->expire($kn, 3600*24);
- }
- sub restore_fsa_state($chat, $from)
- {
- my $state = $redis->get(make_key($chat, "state"));
- set_fsa_state($state, $chat, $from);
- }
- sub set_fsa_state($state, $chat, $from)
- {
- if ($state)
- {
- my $notes = { $redis->hgetall(make_key($chat, "notes")) };
- $fsa->notes($_ => $notes->{$_}) for keys %$notes;
- $fsa->notes(chatid => $chat);
- $fsa->curr_state($state);
- say "restore ", $state, Dumper make_key($chat, "notes"), $notes;
- }
- else
- {
- $fsa->reset;
- $fsa->notes(chatid => $chat);
- $fsa->notes(lang => $from->{language_code});
- $fsa->start;
- }
- }
- sub process_input($line, $chatid, $rest)
- {
- say "*** current state = ", $fsa->curr_state->name;
- $fsa->switch($line, $chatid, $rest);
- if (defined (my $new_state = $fsa->notes("new_state")))
- {
- say "*** mandatory switching to $new_state";
- set_fsa_state($new_state, $chatid, $rest);
- $fsa->notes(new_state => undef);
- }
- say "*** Switched to ", $fsa->curr_state->name;
- }
- sub set_new_state($name)
- {
- $fsa->notes(new_state => $name);
- }
- 1;
|