|
|
@@ -3,6 +3,7 @@ use utf8;
|
|
|
|
|
|
use Mojo::Base -strict, -async_await, -signatures;
|
|
|
use Data::Dumper;
|
|
|
+use experimental qw/switch/;
|
|
|
|
|
|
our $client;
|
|
|
our $abon_client;
|
|
|
@@ -19,18 +20,38 @@ sub __
|
|
|
our $commands = [
|
|
|
{command=>"help", name=>__("Помощь"), description=>__("Список доступных команд")},
|
|
|
{command=>"info", name=>__("Информация"), description=>__("Информация о пользователе")},
|
|
|
- {command=>"balance", name=>__("Баланс"), description=>__("Проверка баланса"), main=>1, icon=>"\x{1FA99}"},
|
|
|
+ {command=>"balance", name=>__("Баланс"), description=>__("Проверка баланса"), main=>1, icon=>"\x{1F45B}"},
|
|
|
{command=>"service", name=>__("Сервисы"), description=>__("Подключенные сервисы")},
|
|
|
{command=>"credit", name=>__("Кредит"), description=>__("Установка кредита"), main=>1, icon=>"\x{1FAF0}"},
|
|
|
{command=>"card", name=>__("Карта пополнения"), description=>__("Оплата карточкой пополнения"), main=>1, icon=>"\x{1F4B3}"},
|
|
|
{command=>"payberry", name=>__("Payberry"), description=>__("Оплата через Payberry"), main=>1, icon=>"\x{1F17F}\x{FE0F}"},
|
|
|
{command=>"transfer", name=>__("Перевод"), description=>__("Перевод денег")},
|
|
|
{command=>"new_task", name=>__("Новая заявка"), description=>__("Новая заявка")},
|
|
|
- {command=>"tasks", name=>__("Заявки"), description=>__("Открытые заявки"), main=>1, icon=>"\x{2764}\x{FE0F}\x{200D}\x{1FA79}"},
|
|
|
+ {command=>"tasks", name=>__("Заявки"), description=>__("Открытые заявки"), main=>1, icon=>"\x{2692}\x{FE0F}"},
|
|
|
{command=>"support", name=>__("Техподдержка"), description=>__("Связь с техподдержкой")},
|
|
|
{command=>"logout", name=>__("Выход"), description=>__("Выход")},
|
|
|
];
|
|
|
|
|
|
+#############################
|
|
|
+
|
|
|
+our $lex_actions = {
|
|
|
+ xfer => {
|
|
|
+ name => __("перевод денег"),
|
|
|
+ canceled => __("отменён"),
|
|
|
+ },
|
|
|
+ card => {
|
|
|
+ name => __("пополнение карточкой"),
|
|
|
+ canceled => __("отмененo"),
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+our $lex_vars = {
|
|
|
+ xfer_to => __("номер личного счета"),
|
|
|
+ xfer_amount => __("сумму"),
|
|
|
+ card_code => __("код карточки"),
|
|
|
+ card_serial => __("номер карточки"),
|
|
|
+};
|
|
|
+
|
|
|
##############################################
|
|
|
|
|
|
sub command_help($fsa, $info)
|
|
|
@@ -43,19 +64,19 @@ async sub command_logout
|
|
|
{
|
|
|
my ($fsa, $info) = @_;
|
|
|
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
|
|
|
await $client->delete_p("client", "/client/$uid/telegram");
|
|
|
reply($info, _("Благодарим за использование нашего бота"));
|
|
|
|
|
|
- $fsa->delete_note("uid");
|
|
|
+ $fsa->delete_note("[uid]");
|
|
|
$fsa->state("logged_out");
|
|
|
}
|
|
|
|
|
|
async sub command_balance
|
|
|
{
|
|
|
my ($fsa, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
|
|
|
my $money = await $abon_client->get_p($info, "client", "/client/$uid/money?human=1");
|
|
|
my $cur = $money->{human};
|
|
|
@@ -86,7 +107,7 @@ async sub command_info
|
|
|
{
|
|
|
my ($fsa, $info) = @_;
|
|
|
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
my $client = await $abon_client->get_p($info, "client", "/client/$uid");
|
|
|
reply($info,
|
|
|
sprintf("<u>%s</u>: %d", _("Номер учетной записи"), $client->{uid}),
|
|
|
@@ -100,7 +121,7 @@ async sub command_info
|
|
|
async sub command_credit
|
|
|
{
|
|
|
my ($fsa, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
|
|
|
my $money = await $abon_client->get_p($info, "client", "/client/$uid/money?human=1");
|
|
|
|
|
|
@@ -122,12 +143,12 @@ async sub command_credit
|
|
|
async sub callback_set_credit
|
|
|
{
|
|
|
my ($fsa, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
|
|
|
my $res = await $abon_client->post_p($info, "client", "/client/$uid/credit", {human=>1});
|
|
|
return reply($info, _("Кредит не имеет смысла для бесплатных тарифных планов")) if $res->{credit} == 0;
|
|
|
|
|
|
- await reply($info,
|
|
|
+ await reply_with($info, {button_menu=>1},
|
|
|
sprintf("%s <b>%.2f %s</b>", _("Установлен кредит "), $res->{credit}, $res->{human}),
|
|
|
"",
|
|
|
);
|
|
|
@@ -138,7 +159,7 @@ async sub callback_set_credit
|
|
|
async sub command_service
|
|
|
{
|
|
|
my ($fsa, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
|
|
|
my $res = await $abon_client->get_p($info, "client", "/client/$uid/service?human=1&as-array=1");
|
|
|
my @list = map { sprintf("<u>%s:</u> %s (%s '%s')", $_->{name_ru}, format_wd($_->{tariff}, $_->{human}), _("тариф"), $_->{tariff}->{name_ru}) }
|
|
|
@@ -154,22 +175,13 @@ async sub command_transfer
|
|
|
my ($fsa, $info) = @_;
|
|
|
reply($info, _("Введите номер личного счета пользователя, которому вы хотите перевести деньги со своего собственного счета"));
|
|
|
|
|
|
- $fsa->delete_note("xfer_to");
|
|
|
- $fsa->delete_note("xfer_amount");
|
|
|
- $fsa->delete_note("xfer_fio");
|
|
|
-
|
|
|
- return needs_input(
|
|
|
- fsa => $fsa,
|
|
|
- name => "xfer_to",
|
|
|
- item => _("номер личного счета"),
|
|
|
- process => _("перевод денег"),
|
|
|
- );
|
|
|
+ return needs_input($fsa, "xfer", "xfer_to");
|
|
|
}
|
|
|
|
|
|
async sub verify_xfer_to
|
|
|
{
|
|
|
my ($fsa, $target_uid, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
|
|
|
return _("Номер личного счета должен состоять из цифр") unless $target_uid =~ /^\d+$/;
|
|
|
return _("Нельзя перевести деньги себе самому") if $uid==$target_uid;
|
|
|
@@ -177,14 +189,14 @@ async sub verify_xfer_to
|
|
|
my $res = await $abon_client->get_p($info, "client", "/client/$target_uid");
|
|
|
return _("Абонент") . " $target_uid " . _("отключен") if $res->{disabled};
|
|
|
|
|
|
- $fsa->note(xfer_fio => $res->{fio});
|
|
|
+ $fsa->note("xfer_fio" => $res->{fio});
|
|
|
return undef;
|
|
|
}
|
|
|
|
|
|
async sub use_xfer_to
|
|
|
{
|
|
|
my ($fsa, $target_uid, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
|
|
|
my $nick = $fsa->note("xfer_fio");
|
|
|
my @fio = split(/\s+/, $nick);
|
|
|
@@ -194,23 +206,20 @@ async sub use_xfer_to
|
|
|
$nick = join(" ", (substr($f, 0, 1) . ".", @fio));
|
|
|
}
|
|
|
|
|
|
+ $fsa->note(xfer_nick => $nick);
|
|
|
+
|
|
|
reply(
|
|
|
$info, _("Получатель денег: ") . $nick,
|
|
|
_("Теперь введите сумму, которую хотите перевести"),
|
|
|
);
|
|
|
|
|
|
- return needs_input(
|
|
|
- fsa => $fsa,
|
|
|
- name => "xfer_amount",
|
|
|
- item => _("сумму"),
|
|
|
- process => _("перевод денег"),
|
|
|
- );
|
|
|
+ return needs_input($fsa, "xfer", "xfer_amount");
|
|
|
}
|
|
|
|
|
|
sub verify_xfer_amount
|
|
|
{
|
|
|
my ($fsa, $amount, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
|
|
|
$amount =~ s/,/./g;
|
|
|
$amount =~ s/[^\d\.]//g;
|
|
|
@@ -223,15 +232,17 @@ sub verify_xfer_amount
|
|
|
async sub use_xfer_amount
|
|
|
{
|
|
|
my ($fsa, $amount, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
my $to_uid = $fsa->note("xfer_to");
|
|
|
+ my $nick = $fsa->note("xfer_nick");
|
|
|
|
|
|
reply_with($info, {
|
|
|
inline_menu => [[
|
|
|
{ text=>_("Подтвердите перевод"), callback_data=>"\x00/transfer" },
|
|
|
]]
|
|
|
},
|
|
|
- sprintf("%.2f %s %s %d", $amount, $config->{currency}->{human}, _(" на счет абонента"), $to_uid),
|
|
|
+ sprintf("%.2f %s %s %d (%s)", $amount, $config->{currency}->{human}, _(" на счет абонента"), $to_uid, $nick)
|
|
|
);
|
|
|
|
|
|
return "command";
|
|
|
@@ -240,16 +251,11 @@ async sub use_xfer_amount
|
|
|
async sub callback_transfer
|
|
|
{
|
|
|
my ($fsa, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
|
|
|
- my $to_uid = $fsa->delete_note("xfer_to");
|
|
|
- my $amount = $fsa->delete_note("xfer_amount");
|
|
|
- $fsa->delete_note("xfer_fio");
|
|
|
-
|
|
|
- unless ($to_uid && $amount)
|
|
|
- {
|
|
|
- return reply($info, _("Произошла внутренняя ошибка"));
|
|
|
- }
|
|
|
+ my $to_uid = $fsa->note("xfer_to");
|
|
|
+ my $amount = $fsa->note("xfer_amount");
|
|
|
+ return unless $to_uid && $amount;
|
|
|
|
|
|
my $res = $abon_client->post_p($info, "client", "/client/$uid/money/to/$to_uid", {
|
|
|
amount => $amount,
|
|
|
@@ -258,7 +264,7 @@ async sub callback_transfer
|
|
|
currency => $config->{currency}->{name},
|
|
|
});
|
|
|
|
|
|
- reply($info, _("Деньги успешно переведены"));
|
|
|
+ reply_with($info, {button_menu=>1}, _("Деньги успешно переведены"));
|
|
|
command_balance($fsa, $info);
|
|
|
}
|
|
|
|
|
|
@@ -267,7 +273,7 @@ async sub callback_transfer
|
|
|
async sub command_new_task
|
|
|
{
|
|
|
my ($fsa, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
|
|
|
my $res = await $abon_client->get_p($info, "task", "/task?created_by_client=$uid&list=new,work");
|
|
|
|
|
|
@@ -283,10 +289,13 @@ async sub command_new_task
|
|
|
async sub callback_task_post
|
|
|
{
|
|
|
my ($fsa, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
+
|
|
|
+ my $descr = $fsa->note("task_text");
|
|
|
+ return unless $descr;
|
|
|
|
|
|
my $params = {
|
|
|
- description => $fsa->note("task_text"),
|
|
|
+ description => $descr,
|
|
|
"for-client" => $uid,
|
|
|
client => $uid,
|
|
|
type => "client-issue",
|
|
|
@@ -298,25 +307,24 @@ async sub callback_task_post
|
|
|
|
|
|
my $res = await $client->post_json_p("task", "/task", $params);
|
|
|
|
|
|
- reply($info, "Заявка размещена");
|
|
|
-
|
|
|
- $fsa->delete_note("task_text");
|
|
|
+ reply_with($info, {button_menu=>1}, _("Ваша заявка размещена"));
|
|
|
command_tasks($fsa, $info);
|
|
|
}
|
|
|
|
|
|
async sub callback_task_cancel
|
|
|
{
|
|
|
-say 666;
|
|
|
my ($fsa, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
-say "aaa", Dumper $fsa;
|
|
|
- reply($info, _("Заявка отменена"));
|
|
|
+
|
|
|
+ $fsa->delete_note("task_text");
|
|
|
+ $fsa->delete_note("if_edited");
|
|
|
+
|
|
|
+ reply_with($info, {button_menu=>1}, _("Заявка отменена"));
|
|
|
}
|
|
|
|
|
|
async sub command_tasks
|
|
|
{
|
|
|
my ($fsa, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
|
|
|
my $res = await $abon_client->get_p($info, "task", "/task?created_by_client=$uid&list=new,work&sort=id");
|
|
|
|
|
|
@@ -338,7 +346,7 @@ async sub command_tasks
|
|
|
async sub callback_task
|
|
|
{
|
|
|
my ($fsa, $info, $task_id) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
|
|
|
my $res = await $client->get_p("task", "/task/$task_id?with_comments=1");
|
|
|
|
|
|
@@ -367,12 +375,10 @@ async sub callback_comment
|
|
|
|
|
|
##################################################
|
|
|
|
|
|
-use constant FAIL_BLOCK => 10;
|
|
|
-
|
|
|
async sub command_payberry
|
|
|
{
|
|
|
my ($fsa, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
|
|
|
my $menu = [[
|
|
|
{text => _("Payberry"), url => $config->{pay}->{payberry_url} . "?acc=$uid"}
|
|
|
@@ -381,10 +387,15 @@ async sub command_payberry
|
|
|
reply_with($info, {inline_menu=>$menu}, _("Для оплаты перейдите по ссылке"));
|
|
|
}
|
|
|
|
|
|
+#####################################
|
|
|
+
|
|
|
+use constant FAIL_BLOCK => 10;
|
|
|
+use constant FAIL_ASK_SERIAL => 3;
|
|
|
+
|
|
|
async sub command_card
|
|
|
{
|
|
|
my ($fsa, $info) = @_;
|
|
|
- my $uid = $fsa->note("uid");
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
|
|
|
my $key = "card-guess-$uid";
|
|
|
my $failed = $redis->get($key) || 0;
|
|
|
@@ -401,41 +412,114 @@ async sub command_card
|
|
|
}
|
|
|
|
|
|
reply($info, _("Введите код карточки пополнения (16 цифр, можно разделять их знаком '-')"));
|
|
|
+ return needs_input($fsa, "card", "card_code");
|
|
|
+}
|
|
|
|
|
|
- $fsa->delete_note("card_code");
|
|
|
- $fsa->delete_note("card_serial");
|
|
|
-
|
|
|
- $fsa->state("card_needs_code");
|
|
|
+sub verify_card_code($fsa, $code, $info)
|
|
|
+{
|
|
|
+ $code =~ s/\D//g;
|
|
|
+ return _("Код карточки должен состоять из 16 цифр") unless $code =~ /^\d{16}$/;
|
|
|
+ return undef;
|
|
|
+}
|
|
|
+
|
|
|
+async sub use_card_code
|
|
|
+{
|
|
|
+ my ($fsa, $code, $info) = @_;
|
|
|
+
|
|
|
+ my $uid = $fsa->note("[uid]");
|
|
|
+ my $key = "card-guess-$uid";
|
|
|
+ my $fails = $redis->get($key) || 0;
|
|
|
+
|
|
|
+ if ($fails > FAIL_ASK_SERIAL)
|
|
|
+ {
|
|
|
+ reply($info, _("Теперь введите номер карточки (7 цифр, можно разделять знаком'-')"));
|
|
|
+ return needs_input($fsa, "card", "card_serial");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ pay_from_card($info, $uid, $code, "");
|
|
|
+ return "command";
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+sub verify_card_serial($fsa, $serial, $info)
|
|
|
+{
|
|
|
+ $serial =~ s/\D//g;
|
|
|
+ return _("Номер карточки должен состоять из 7 цифр") unless $serial =~ /^\d{7}$/;
|
|
|
+ return undef;
|
|
|
+}
|
|
|
+
|
|
|
+async sub use_card_serial
|
|
|
+{
|
|
|
+ my ($fsa, $serial, $info) = @_;
|
|
|
+ pay_from_card($info, $fsa->note("[uid]"), $fsa->note("card_code"), $serial);
|
|
|
}
|
|
|
|
|
|
+async sub pay_from_card
|
|
|
+{
|
|
|
+ my ($info, $uid, $code, $serial) = @_;
|
|
|
+
|
|
|
+ my $args = {
|
|
|
+ code => $code =~ s/\D//gr,
|
|
|
+ uid => $uid,
|
|
|
+ domain => $config->{domain},
|
|
|
+ source => "abonbot",
|
|
|
+ ip => "0.0.0.0",
|
|
|
+ };
|
|
|
+
|
|
|
+ $args->{serial} = $serial =~ s/\D//gr if $serial;
|
|
|
+
|
|
|
+ my $res = eval { await $client->post_p("card", "/redemption", $args) };
|
|
|
+
|
|
|
+ unless($@)
|
|
|
+ {
|
|
|
+ return reply_with($info, {button_menu=>1}, _("Ваш счёт пополнен на " . $res->{amount} . " " . $res->{currency_short_name_ru} . ". " . _("Оплачено до ") . $res->{paid_until}));
|
|
|
+ };
|
|
|
+
|
|
|
+ given($@->{code})
|
|
|
+ {
|
|
|
+ when(400)
|
|
|
+ {
|
|
|
+ reply_with($info, {button_menu=>1}, _("Вы ввели неправильный номер или код карточки"));
|
|
|
+ my $key = "card-guess-$uid";
|
|
|
+ $redis->incr($key);
|
|
|
+ $redis->expire($key, 24 * 3600);
|
|
|
+ }
|
|
|
+ when(409)
|
|
|
+ {
|
|
|
+ reply_with($info, {button_menu=>1}, _("Карточка уже использована"));
|
|
|
+ }
|
|
|
+ when(406)
|
|
|
+ {
|
|
|
+ reply_with($info, {button_menu=>1}, _("Карточка не активирована. Обратитесь в службу поддержки"));
|
|
|
+ }
|
|
|
+ default
|
|
|
+ {
|
|
|
+ die $@;
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+#####################################################
|
|
|
+
|
|
|
sub command_support
|
|
|
{
|
|
|
- my ($fsa, $info) = @_;
|
|
|
- return reply($info, _("Телефоны техподдержки:"), @{$config->{support_phones}});
|
|
|
+ my ($fsa, $info) = @_;
|
|
|
+ return reply($info, _("Телефоны техподдержки:"), @{$config->{support_phones}});
|
|
|
}
|
|
|
|
|
|
##################################################
|
|
|
|
|
|
-sub needs_input(%args)
|
|
|
+sub needs_input($fsa, $action, $var)
|
|
|
{
|
|
|
- my $name = $args{name};
|
|
|
- my $fsa = $args{fsa};
|
|
|
+ $fsa->delete_note($var);
|
|
|
+ $fsa->note(input_var => $var);
|
|
|
+ $fsa->note(input_action => $action);
|
|
|
|
|
|
- $fsa->delete_note($name);
|
|
|
- $fsa->note(input_name => $name);
|
|
|
- $fsa->note(input_again => _("Введите заново ") . $args{item} . _(" или нажмите Отмена, чтобы прервать ") . $args{process});
|
|
|
- $fsa->note(input_process => $args{process});
|
|
|
$fsa->state("needs_input");
|
|
|
- return "needs_input";
|
|
|
-}
|
|
|
|
|
|
-sub cancel_input
|
|
|
-{
|
|
|
- my ($fsa, $info) = @_;
|
|
|
- $fsa->delete_note($fsa->delete_note("input_name"));
|
|
|
- $fsa->delete_note("input_again");
|
|
|
- reply($info, ucfirst($fsa->delete_note("input_process")) . " " . _("отменён"));
|
|
|
- $fsa->state("command");
|
|
|
+ return "needs_input";
|
|
|
}
|
|
|
|
|
|
##################################################
|
|
|
@@ -445,7 +529,7 @@ sub format_wd($rec, $cur)
|
|
|
return _("бесплатно") if $rec->{dayly} == 0 && $rec->{monthly} == 0;
|
|
|
|
|
|
my $m = sprintf("<b>%.2f $cur</b> %s", $rec->{monthly}, _("в месяц")) if $rec->{monthly} != 0;
|
|
|
- my $d = sprintf("<b>%.2f $cur</b> %s", $rec->{dayly}, _("в месяц")) if $rec->{dayly} != 0;
|
|
|
+ my $d = sprintf("<b>%.2f $cur</b> %s", $rec->{dayly}, _("в день")) if $rec->{dayly} != 0;
|
|
|
|
|
|
return ("$m + $d") if $m && $d;
|
|
|
return $m if $m;
|