На коленке накидал бот, который позволяет создавать выплаты через панель.
У нас нет публичного API, который позволяет создавать выплаты по соображениям безопасности. Ниже код, который имитирует запрос, словно он сделан через браузер.
Использование
-
/start
– пингует бота. Если бот ответил, значит установка правильная -
/setcookie $cookie
– сохраняет обязательный куки, без которого бот будет выдавать ошибку. Инструкция по получению выше -
/settoken $token
– также, как /setcookie -
/balance
– отображает баланс вашего аккаунта -
/payout $method $purse $sum
– запрашивает выплату на указанный реквизит.$method
может быть qiwi или card
Установка
- Установите на сервер ggram (скачайте и киньте в addons)
- По пути
addons/ggram-mod/lua/autorun/ggram-launcher.lua
скопируйте и вставьте код загрузчика из этой страницы - Создайте файл
addons/ggram-mod/lua/ggram/bots/gmdbot/_init.lua
и поместите в него код, который ниже - На первой строке укажите токен своего бота. Получить можно в Telegram: Contact @BotFather
- На 6й строке замените 123456 на свой telegram id. Получить можно в Telegram: Contact @jsonson_bot
- На этом этапе после перезагрузки сервера, у вас в боте должна работать команда
/start
. Если не работает, значит дальше пока не читайте, пока не разберетесь в проблеме - Если /start ответила “hello”, значит все хорошо. Теперь вам нужно вызвать команды
/setcookie
и/settoken
в боте.Информация ниже
Получаем значение для /setcookie
Можете либо извлечь значение куки без плагина или с плагином для браузера.
С плагином
Установите EditThisCookie, на странице выплат откройте окно расширения и скопируйте там это значение: скриншот
Без плагина
- Зайдите на сайт, сразу на страницу выплат.
- Откройте dev tools (F12)
- Обновите страницу и затем вот тут получите куки: скриншот. Копируйте значение после знака “равно” ( = ), но ДО точки с запятой ( ; )
Получаем значение для /settoken
- Открываем dev tools на странице выплат
- Меняем метод выплаты (например, с киви на карту или наоборот)
- Токен будет видно тут: скриншот
Код бота
Путь: addons/ggram-mod/lua/ggram/bots/gmdbot/_init.lua
(не забудьте установить ggram, как написано выше)
👉 Код (кликни сюда)
local bot = require("ggram")("your_bot_token")
require("ggram.polling").start(bot)
function bot.secureCommand(cmd, func)
return bot.command(cmd, function(ctx)
if ctx.from.id ~= 123456 then -- СЮДА НУЖНО ВСТАВИТЬ ТВОЙ TELEGRAM ID
return ctx.reply.text("fak yu")
end
return func(ctx)
end)
end
bot.command("start", function(ctx) ctx.reply.text("hello") end)
-- либа, которая в гмоде сохраняет все в sv.db
local cookie = cookie or require("gmod.cookie")
local HTTP = HTTP or require("gmod.globals").HTTP
local BASE_URL = "https://gm-donate.net"
local function request(method, endpoint, parameters_, fSuccess, fError)
local session = cookie.GetString("gmd_session_cookie")
assert(session, "Сначала нужно выполнить /setcookie")
assert(cookie.GetString("gmd_post_token"), "Большинство запросов требуют /settoken")
HTTP({
method = method or "GET",
url = BASE_URL .. endpoint,
headers = {
Cookie = "laravel_session=" .. session,
},
success = fSuccess,
failed = fError,
parameters = parameters_
})
end
local function get_balance(cb)
request("GET", "/panel/payouts", nil, function(_, body)
local bal_str = body:match("fa fa%-rub.-</span>.-([%d,%.]+).*</a>") -- 2,332.65
local bal_num = bal_str:gsub(",", "")
cb(true, tonumber(bal_num))
end, function(err) cb(false, err) end)
end
-- get_balance(print)
local function request_payout(sum, cb)
request("POST", "/panel/payouts/add", {
_token = cookie.GetString("gmd_post_token"),
sum = tostring(sum),
}, function(_, body)
local ok = not not body:match("Redirecting to")
cb(ok, body)
end, function(err) cb(false, err) end)
end
-- request_payout(13, print)
-- 1 qiwi, 2 card
local function update_payout_method(iMethod, cb)
request("GET", "/panel/payouts/setPaymentMethod/" .. iMethod, {
_token = cookie.GetString("gmd_post_token"),
}, function(code, body)
if code ~= 200 then -- iMethod = 3 => 404
cb(false, body)
return
end
if iMethod == 1 then
local changed = not not body:match("Укажите номер вашего кошелька")
cb(changed, body)
elseif iMethod == 2 then
local changed = not not body:match("Укажите номер банковской карты")
cb(changed, body)
end
end, function(err) cb(false, err) end)
end
-- update_payout_method(2, print)
-- sMethod: qiwi, card
-- purse: 79134567890, 1111222233334444
local function update_purse(sMethod, purse, cb)
local param_name = ""
if sMethod == "qiwi" then
param_name = "qiwi_phone"
elseif sMethod == "card" then
param_name = "card_number"
end
local params = {
_token = cookie.GetString("gmd_post_token"),
method = sMethod,
}
params[param_name] = purse
request("POST", "/panel/payouts/save-settings", params, function(_, body, headers)
local redirect = (not not body:match("Redirecting to")) and headers.location
if redirect then
local string_PatternSafe = string.PatternSafe or require("gmod.string").PatternSafe
request("GET", headers.location:gsub( string_PatternSafe(BASE_URL),"" ), nil, function(_, body)
-- Бывает "Произошла ошибка при смене номера реквизитов, пожалуйста убедитесь что реквизиты указаны верно."
local success = not not body:match("Вы успешно сменили")
cb(success, body)
end, function(err2) cb(false, err2) end)
else
cb(false, body)
end
end, function(err) cb(false, err) end)
end
-- update_purse("qiwi", "79134567890", print)
-- update_purse("card", "1111222233334444", print)
-- Брать тут: https://file.def.pm/JYOF0cFb.jpg
bot.secureCommand("setcookie", function(ctx)
local cook = ctx.args()[1]
if not cook then ctx.reply.text("add cookie string to parameters") return end
cookie.Set("gmd_session_cookie", cook)
ctx.reply.text("OK")
end)
-- Брать тут (из post запросов): https://file.def.pm/7d4c86D1.jpg
bot.secureCommand("settoken", function(ctx)
local token = ctx.args()[1]
if not token then ctx.reply.text("add token string to parameters") return end
cookie.Set("gmd_post_token", token)
ctx.reply.text("OK")
end)
bot.secureCommand("balance", function(ctx)
get_balance(function(ok, bal)
local str = ok and ("Баланс: " .. bal) or ("Ошибка запроса: " .. bal)
ctx.reply.text(str)
end)
end)
bot.secureCommand("payout", function(ctx)
local args = ctx.args()
local method, purse, sum = args[1], args[2], tonumber(args[3])
if not sum then
ctx.reply.text("Example: /payout qiwi 79134567890 123.45")
return
end
local iMethod = method == "qiwi" and 1 or method == "card" and 2
if not iMethod then ctx.reply.text("Указан некорректный метод выплаты") return end
update_payout_method(iMethod, function(ok1)
if not ok1 then ctx.reply.text("Ошибка смены метода выплаты") return end
update_purse(method, purse, function(ok2)
if not ok2 then ctx.reply.text("Ошибка смены реквизитов") return end
request_payout(sum, function(ok3)
ctx.reply.text(ok3 and "Запрос создан" or "Ошибка создания запроса выплаты")
end)
end)
end)
end)
Примечания
- Код слишком хрупкий, может сломаться в любой момент, поскольку все данные просто парсит из html страницы-ответа, которая в будущем может меняться. Тем не менее, я готов делать фиксы, если это будет востребованно в этой теме
- Здесь нет проверки статуса выплаты, это сильно усложнило бы код, тем не менее такую функцию можно доделать самостоятельно (после создания выплаты парсите таблицу выплат и проверяете статус раз в пару минут)
- Код будет работать как на Garry’s Mod, так и на чистом Lua (за пределами гаррисмод). Тестировалось как раз в обычном Lua. Вот здесь я немного писал об этой библиотеке для ботов
- Мы не принимаем никаких жалоб на то, что у вас украли деньги. Вы сами в ответе за секретные данные и сами отвечаете за их защиту. Если вдруг у вас украдут код сервера, а с ним и сделают выплаты – мы не поможем. Могу лишь порекомендовать не хранить секретные данные в lua файлах или делать выплаты вручную
- Время от времени куки и токен может потребоваться обновлять. Я не могу точно сказать, насколько часто это нужно будет делать, но полагаю, что не очень часто