Исходник Гайд Библиотека для VK API

Rice.

Известный
Автор темы
Модератор
1,756
1,622
Всех приветствую!
Сегодня Вы сможете увидеть мою первую библиотеку для VK API. Сразу говорю, что в этой библиотеки нету ничего эксклюзивного.

Данная библиотека не только будет полезна в написание скриптов для создания чат-ботов, но и поможет новичкам (каким я и являюсь), которые ничего не понимают в API.

Хочу сразу подметить, что в моей библиотеки используются функции для HTTP запросов, которые я увидел у @neverlane (https://www.blast.hk/threads/57120/). Спасибо, ег двачев.


Установка:
Файл "VK_API.lua" перенести в папку "lib" в папке "moonloader" (Не путайте с "modloader").

Библиотека требует Effil!
Все файлы из скаченного архива перенести в папку "lib" в папке "moonloader" (Не путайте с "modloader").

Функции:
Функция
Описание
Аргументы
botAuthorization(group, token, version)
Функция записывает данные о Вашем сообществе в переменную для дальнейшего использования.

Она должна быть вызвана до остальных функций.
Можно вызвать только один раз.
group (string): Айди Вашей группы VK.
token (string): Токен Вашей группы VK.
version (string): Версия VK API.
createRequest(method, parameters)
Функция для получения ссылки на метод.
method (string): Название метода. Пример: users.get.
parameters (table): Параметры запроса (токен и версию API указывать не нужно). Пример:
Ключ
Значение
user_ids
324119075
sendRequest(url, callback = NULL)
Функция для отправки метода в VK.
url (string): Ссылка для API (можно удобно получать через createRequest).
callback (function): Функция для получения ответа от сервера (необязательно (применение ищите в примере)).
getLongPollServer(callback = NULL)
Функция получает параметры из метода getLongPollServer для получения сообщений из бесед.

Можно вызвать только один раз.
callback (function): Функция для получения параметров LongPoll (необязательно (применение ищите в примере)).
sendMessage(text, chat, buttons = NULL, callback = NULL)
Отправляет сообщение в указанный чат. К сообщению можно прикрепить клавиатуру.
text (string): Текст сообщения.
chat (string): Айди чата.
buttons (table): Клавиатура в чате (необязательно).
callback (function): Функция для получения ответа от сервера (необязательно (применение ищите в примере)).
getMessage(array)
Функция callback, которая срабатывает каждый раз, когда приходит новое сообщение.
array (table): Возвращаемое значение.

Пример:
Lua:
-->> Подключаем библиотеку
local VK = require('VK_API')

-->> Создаём переменные
local token = 'Токен'
local group = 'Айди Группы'
local chat = 'Айди Чата'

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end

    -->> Запускаем бота
    VK.botAuthorization(group, token, '5.131')
    
    -->> Отправляем тестовое сообщение в чат
    VK.sendMessage('Test', chat, nil, function(result)
            print(result)
        end)
    
    -->> Получаем ссылку на метод
    local url = VK.createRequest('users.get', {['user_ids'] = 324119075})
        -->> Отправляем ссылку в ВК
        VK.sendRequest(url, function(result)
            -->> Выводим ИД пользователя
            print(decodeJson(result).response[1].id)
        end)
    
    -->> Запускаем получение сообщений из чатов
        VK.getLongPollServer(function(resolve)
            print(resolve)
        end)

    wait(-1)
end

-->> Создаем callback функцию для получения сообщений
function VK.getMessage(v)
    -->> Получаем текст сообщения
    local text = u8:decode(v.object.message.text)
    -->> Получаем Айди пользователя, который написал сообщение
    local from_id = v.object.message.from_id
    -->> Получаем Айди чата, в котором написано сообщение
    local peer_id = v.object.message.peer_id

    -->> Отправляем пользователю его Айди + Отправляем ему клавиатуру
        VK.sendMessage('Твой ИД: ' .. from_id, chat, button())
end

-->> Функция с массивом клавиатуры
function button()
    local keyboard = {
    
        -->> Клавиатура в самом сообщение
        ['inline'] = true,
        -->> Клавиатура под инпутом текста
        ['one_time'] = false,
        -->> Эти два аргумента не могут быть использованы вместе, выбирайте один из них, а второй удаляйте
        
        ['buttons'] = {
            -->> 1 ряд
            {
                -->> 1 кнопка
                {
                    ['action'] = {
                        ['type'] = 'text',
                        ['label'] = 'Пойти гулять',
                        ['payload'] = encodeJson({['button'] = 'street'})
                        -->> payload нужен для того, чтобы данная таблица передалась в массив с сообщением пользователя (если нужна будет помощь, то пишите в тему)
                    },
                    ['color'] = 'positive'
                },
                -->> 2 кнопка
                {
                    ['action'] = {
                        ['type'] = 'text',
                        ['label'] = 'Вернуться домой',
                        ['payload'] = encodeJson({['button'] = 'home'})
                    },
                    ['color'] = 'secondary'
                },
            },
            -->> 2 ряд
            {
                -->> 1 кнопка
                {
                    ['action'] = {
                        ['type'] = 'text',
                        ['label'] = 'Сохранить фотку тянки',
                        ['payload'] = encodeJson({['button'] = 'save'})
                    },
                    ['color'] = 'primary'
                },
                -->> 2 кнопка
                {
                    ['action'] = {
                        ['type'] = 'text',
                        ['label'] = 'Удалить фотку тянки',
                        ['payload'] = encodeJson({['button'] = 'delete'})
                    },
                    ['color'] = 'negative'
                }
            }
        }
    }
    return keyboard
end

Фотографии клавиатуры:
1683028656656.png
1683028674261.png

Настройки сообщества:
1683029474079.png
1683029492826.png
1683029501700.png
1683029517102.png
1683029525247.png
 

Вложения

  • VK_API.lua
    4.2 KB · Просмотры: 138
Последнее редактирование:

neverlane

t.me/neverlane00
Друг
1,010
1,159
Было бы славно если сделал еще для ТГ
для тг сделаю новый супер крутой гайд для муна и раксампа (ваще для муна всё уже готово только мне лень обновлять), а еще там кнопки и инлайн квери будут
 

kyrtion

Известный
975
355
почему бы и не дс?)

p.s.
Теперь есть полное требование:
- effil (как и указали там)
- encoding
- ssl (ssl.https)
 
Последнее редактирование:
  • Нравится
Реакции: Wasta

kyrtion

Известный
975
355
@Rice. походу я первый нашел баг (мб или нет)

Код, просто код:
function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end

    VK.botAuthorization(group, token, '5.131')
    VK.getLongPollServer()
    sampRegisterChatCommand('send', function(arg)
        if not arg or #arg == 0 or not arg:find('^(%d+) (.+)$') then sampAddChatMessage('Введите: /send [peer_id] [текст]', -1) return end
        local peer_id, text = arg:match('^(%d+) (.+)$')
        local peer_id = tonumber(peer_id)
        if peer_id < 2000000000 then peer_id = peer_id+2000000000 end
        print('Sended in chat ['..peer_id..'], text: '..text)
        VK.sendMessage(text, peer_id)
    end)
    wait(-1)
end

Применение: /send 1 da

Sampfuncs Console:
[ML] (script) VK_API: Sended in chat [2000000001], text: da
[ML] (error) VK_API: C:\Games\samp\moonloader\lib\VK_API.lua:66: attempt to yield across C-call boundary
stack traceback:
    [C]: in function 'wait'
    C:\Games\samp\moonloader\lib\VK_API.lua:66: in function 'createRequest'
    C:\Games\samp\moonloader\lib\VK_API.lua:133: in function 'sendMessage'
    C:\Games\samp\moonloader\vk.lua:82: in function <C:\Games\samp\moonloader\vk.lua:76>
[ML] (error) VK_API: Script died due to an error. (082AD53C)

Скрипт умер, а сообщение отправилось...
1683215430755.png


Бонус
Если отправить текст ТестTest!@#"/' то сообщение не отправится, а скрипт помер (также и сверху).
Может неправильно конвертировали?
 

Rice.

Известный
Автор темы
Модератор
1,756
1,622
походу я первый нашел баг (мб или нет)
Да, баг. Ошибка в том, что библиотека пытается использовать задержку вне потока lua_thread.
Наверное, фикс будет завтра.
Пока используй: lua_thread.create(function() VK.sendMessage(text, peer_id) end)
 
  • Нравится
Реакции: kyrtion

Rice.

Известный
Автор темы
Модератор
1,756
1,622
@kyrtion Обновил тему. Просьба ознакомиться с функциями и примером.
 
  • Нравится
Реакции: kyrtion

kyrtion

Известный
975
355
@Rice. странно, если получил сообщение - отправляю запрос чтобы узнать имя, но функция выполняется до сих пор, пока не приходило результаты.

Вот что например:
Lua:
function VK.getMessage(is)
    local text = u8:decode(is.object.message.text) -- text, utf-8
    local from_id = is.object.message.from_id -- account id
    local peer_id = is.object.message.peer_id -- chat id
    if from_id == peer_id or #text == 0 then return end

    newTask(function()
        local this = get_profile(from_id)
        print('this')
        print('[VK] '..this.first_name..' '..this.last_name..' [id'..from_id..']: '..text)
        if text:find('^/ping$') then
            if this.from_id == from_id then
                VK.sendMessage('Pong!', peer_id)
            end
        end
    end)
end


function get_profile(from_id)
    print('get_profile('..tostring(from_id)..')')
    if not from_id or type(from_id) ~= 'number' then return false end
    local list = {
        from_id = 0,
        rang = 0,
        first_nick = '',
        last_nick = '',
        nick_full = '',
        nick_small = '',
        nick_space_full = '',
        nick_space_small = '',
        first_name = '',
        last_name = '',
        name_full = '',
        name_small = '',
        name_space_small = ''
    }

    local req = VK.sendRequest(VK.createRequest('users.get', {['user_ids'] = from_id}), function(result)
        local this = rjson.decode(u8:decode(result)).response[1]
        list.first_name = this.first_name
        list.last_name = this.last_name
        list.name_full = this.first_name..' '..this.last_name
        list.name_small = this.first_name:match('^(.)')..'.'..this.last_name
        list.name_space_small = this.first_name:match('^(.)')..' '..this.last_name

        local json_general = fjson(jsonFilePath_General):read()
        for i=1, #json_general.admin do
            if json_general.admin[i].from_id == from_id then
                list.from_id = json_general.admin[i].from_id
                list.rang = json_general.admin[i].rang
                list.first_nick = json_general.admin[i].nick:match('^(.-)%_')
                list.last_nick = json_general.admin[i].nick:match('%_(.-)$')
                list.nick_full = json_general.admin[i].nick
                list.nick_small = json_general.admin[i].nick:match('^(.)')..'.'..json_general.admin[i].nick:match('%_(.-)$')
                list.nick_space_full = json_general.admin[i].nick:gsub('%_', ' ')
                list.nick_space_small = json_general.admin[i].nick:match('^(.)')..' '..json_general.admin[i].nick:match('%_(.-)$')
                return list
            end
        end
        return list
    end)
end

json for test:
{
    "nick_space_small": "",
    "name_space_small": "М Потемкин",
    "nick_space_full": "",
    "last_nick": "",
    "name_small": "М.Потемкин",
    "nick_full": "",
    "name_full": "Михаил Потемкин",
    "from_id": 0,
    "first_nick": "",
    "first_name": "Михаил",
    "last_name": "Потемкин",
    "nick_small": "",
    "rang": 0
}

Вот что возвращает. Я так понял что вернул только лишь что я там храню инфы, а запрос уже как будто "скипнул"
 
Последнее редактирование:

.KOHTOP.

Активный
226
35
Lua:
                {
                    ['action'] = {
                        ['type'] = 'text',
                        ['label'] = 'Выйти',
                        ['payload'] = encodeJson({['button'] = 'home'})
                    },
                    ['color'] = 'secondary'
                },

При нажатии на кнопку скрипт вводит команду в игре? И можно сделать как-то, чтобы он делал скриншот и кидал мне в диалог?
 

Rice.

Известный
Автор темы
Модератор
1,756
1,622
Lua:
                {
                    ['action'] = {
                        ['type'] = 'text',
                        ['label'] = 'Выйти',
                        ['payload'] = encodeJson({['button'] = 'home'})
                    },
                    ['color'] = 'secondary'
                },

При нажатии на кнопку скрипт вводит команду в игре? И можно сделать как-то, чтобы он делал скриншот и кидал мне в диалог?
Привет.
Формат ответа от сервера, который используется в функции VK.getMessage:
1688272115731.png
Мы должны получить v.object.message.payload. В данный момент времени от находится в формате JSON, т.е. нам нужно его декодировать с помощью функции decodeJson().

Код (взят из примера):
Lua:
function VK.getMessage(v)
    -->> Получаем текст сообщения
    local text = u8:decode(v.object.message.text)
    -->> Получаем Айди пользователя, который написал сообщение
    local from_id = v.object.message.from_id
    -->> Получаем Айди чата, в котором написано сообщение
    local peer_id = v.object.message.peer_id
    -->> Получаем кнопки
    local buttons = v.object.message.payload

    -->> Отправляем пользователю его Айди + Отправляем ему клавиатуру
    VK.sendMessage('Твой ИД: ' .. from_id, chat, button())
    print(buttons and decodeJson(buttons).button or 'кнопка не найдена')
end
1688272604099.png


Получение скриншота придется самому делать. Если найду функцию для отправки файла в диалог, то прикреплю.
 

Gapord

Новичок
13
1
vkbot.lua: {"error":{"error_code":901,"error_msg":"Can't send messages for users without permission","request_params":[{"key":"random_id","value":"0"},{"key":"v","value":"5.131"},{"key":"peer_id","value":"2"},{"key":"method","value":"messages.send"},{"key":"oauth","value":"1"}]}}
я вроде все разрешения дал