Giter Club home page Giter Club logo

botman-vk-community-callback-driver's Introduction

BotMan VK Community Callback driver

BotMan driver to connect VK Community with BotMan via Callback API.

License: MIT Packagist

Contributing

Contributions are welcome, I would be glad to accept contributions via Pull Requests. 🙂 See Contributors tab for more details.

Support

Table of driver's features:

Feature Is Supported
Sending text messages ✔ Fully supported
Sending images ✔ Supported (no titles for images provided by VK API, pictures can't be uploaded to external albums with community token)*
Sending videos ⚠ Partially supported (uploading videos with community token is not supported by VK API)*
Sending audio ⚠ Partially supported (uploading audio is restricted by VK API)
Sending voice messages ✔ Fully supported via Audio object with addExtras('vk_as_voice', true)
Sending documents (files) ✔ Supported (some files might be restricted by the platform to be uploaded, the updated criteria list is no longer public in VK docs)
Sending links ✔ Supported
Sending locations ✔ Fully supported
Sending stickers ✔ Supported as an additional parameter to reply
Sending wall posts ✔ Supported as an additional parameter to reply
Sending polls ✔ Supported as an additional parameter to reply
Sending market items ✔ Supported as an additional parameter to reply
Sending keyboards ✔ Fully supported
Sending carousels ✔ Supported as an additional parameter to reply
Listening for images ✔ Supported (no titles for images provided by VK API)
Listening for videos ⚠ Partially supported (no video URL provided by VK API, info of copyrighted videos can be unavailable via API)*
Listening for audio ✔ Fully supported
Listening for files ✔ Fully supported
Listening for locations ✔ Fully supported
Listening for voice messages ❌ Not supported yet
Receiving messages with mixed attachments ✔ Fully supported
Typing status ✔ Fully supported (photo or document upload, user call)
Mark seen ⚠ Partially supported (user-created conversations can't be marked via API)
Retrieving user data ✔ Fully supported (use VK_USER_FIELDS property for retrieving custom user fields)
Usage in VK conversations ✔ Supported
Multiple communities handling ❌ Not supported yet
VK Speech Recognition Service ❌ Not implemented yet
VK API low-level management ✔ Fully supported
Events listener ✔ Fully supported (as for 14.08.2020)

* - uploading feature with user token is under construction

Setup

Getting the Community API key

From the page of your community, go to Manage -> Settings tab -> API usage -> Access tokens tab. Click Create token button.

API usage

Then tick all the permissions in the dialog box.

Dialog box with permissions

Copy your created token by clicking Show link.

Firstly added API token

Installing the driver

Require the driver via composer:

composer require yageorgiy/botman-vk-community-callback-driver

If you're using BotMan Studio, you should define in the .env file the following properties:

VK_ACCESS_TOKEN="REPLACE_ME"                    # User or community token for sending messages (from Access tokens tab, see above)
VK_SECRET_KEY="REPLACE_ME"                      # Secret phrase for validating the request sender (from Callback API tab, see above)
VK_API_VERSION=5.103                            # API version to be used for sending an receiving messages (should be 5.103 and higher) (not recommended to change)
VK_MESSAGES_ENDPOINT=https://api.vk.com/method/ # VK API endpoint (don't change it if unnecessary)
VK_CONFIRM=                                     # DEPRECATED SINCE v.1.4.2, LEAVE BLANK (EMPTY STRING) - see 'Mounting & confirming the bot' section. Confirmation phrase for VK
VK_GROUP_ID="REPLACE_ME"                        # Community or group ID
VK_USER_FIELDS=                                 # Extra user fields (see https://vk.com/dev/fields for custom fields) (leave blank for no extra fields) (note: screen_name is already included!)

If you don't use BotMan Studio, the driver should be applied manually:

// ...

// Applying driver
DriverManager::loadDriver(\BotMan\Drivers\VK\VkCommunityCallbackDriver::class);

// Applying settings for driver
BotManFactory::create([
    "vk" => [
        "token" => "REPLACE_ME",                    // User or community token for sending messages (from Access tokens tab, see above)
        "secret" => "REPLACE_ME",                   // Secret phrase for validating the request sender (from Callback API tab, see above)
        "version" => "5.103",                       // API version to be used for sending an receiving messages (should be 5.103 and higher) (not recommended to change)
        "endpoint" => "https://api.vk.com/method/", // VK API endpoint (don't change it if unnecessary)
        "confirm" => "",                            // DEPRECATED SINCE v.1.4.2, LEAVE BLANK (EMPTY STRING) - see 'Mounting & confirming the bot' section. Confirmation phrase for VK
        "group_id" => "REPLACE_ME",                 // Community or group ID
        "user_fields" => ""                         // Extra user fields (see https://vk.com/dev/fields for custom fields) (leave blank for no extra fields) (note: screen_name is already included!)
    ]
]);

// ...

Mounting & confirming the bot

⚠ [Migrating from v.1.4.1 and older] Method of confirming the bot has changed since driver version 1.4.2: validation should be managed by using events listener, VK_SECRET_KEY (or $botmanSettings["vk"]["confirm"]) should be blank (empty string).

From the page of your community, go to Manage -> Settings tab -> API usage -> Callback API tab:

Callback API tab

  • Find the string (validation code) in section String to be returned:

Callback API tab

  • Add the following code to routes/botman.php file, replace REPLACE_ME with the validation code (e.g. 1a2b3c4d5e):
$botman->on("confirmation", function($payload, $bot){
    // Use $payload["group_id"] to get group ID if required for computing the passphrase.
    echo("REPLACE_ME");
});
  • Click Confirm button.

Quick guide with examples

In usage examples, the used file is routes/botman.php.

Sending simple message

If bot receives Hello message, it will answer Hi, <First Name>:

$botman->hears('Hello', function ($bot) {
    $bot->reply('Hi, '.$bot->getUser()->getFirstName());
});

Example image

Typing activity

Bot will wait 10 seconds before answering the question:

$botman->hears("What\'s your favourite colour\?", function ($bot) {
    $bot->reply('Let me think...');
    $bot->typesAndWaits(10);
    $bot->reply("I guess it's orange! 😄");
});

Example image

After all, it will answer:

Example image

Attaching image

If bot receives Gimme some image message, it will answer Here it is! with an attached image:

use BotMan\BotMan\Messages\Attachments\Image;
use BotMan\BotMan\Messages\Outgoing\OutgoingMessage;

$botman->hears('Gimme some image', function ($bot) {
    // Create attachment
    $attachment = new Image('https://botman.io/img/logo.png');
    // $attachment->addExtras("vk_photo", "photo123456_123456"); // Or send an already uploaded photo (driver will ignore image url)    

    // Build message object
    $message = OutgoingMessage::create('Here it is!')
        ->withAttachment($attachment);

    // Reply message object
    $bot->reply($message);
});

Example image

Attaching video

Example of sending an already uploaded video:

Note: uploading videos to VK is not supported by the driver yet.

use BotMan\BotMan\Messages\Attachments\Video;
use BotMan\BotMan\Messages\Outgoing\OutgoingMessage;

$botman->hears('Gimme some video', function ($bot) {
    // Create attachment
    $attachment = new Video('http://unused-video-url');
    // Attaching already uploaded videos is the ONLY way to send them (as for now):
    $attachment->addExtras("vk_video", "video-2000416976_41416976"); // Send an already uploaded video (driver will ignore video url)

    // Build message object
    $message = OutgoingMessage::create('Here it is!')
        ->withAttachment($attachment);

    // Reply message object
    $bot->reply($message);
});

Example image

Attaching audio

Example of sending an already uploaded audio:

Note: uploading audio to VK is restricted by the platform.

use BotMan\BotMan\Messages\Attachments\Audio;
use BotMan\BotMan\Messages\Outgoing\OutgoingMessage;

$botman->hears('Gimme some audio', function ($bot) {
    // Create attachment
                            // URL can be uploaded ONLY as voice message (due to restrictions of VK)
    $attachment = new Audio('https://unused-audio-url');
    $attachment->addExtras("vk_audio", "audio371745438_456268888"); // Send an already uploaded audio (driver will ignore audio url and vk_as_voice parameter)

    // Build message object
    $message = OutgoingMessage::create('Here it is!')
        ->withAttachment($attachment);

    // Reply message object
    $bot->reply($message);
});

Example image

Sending voice message

Voice messages can be send using Audio with extra parameter vk_as_voice = true.

Example of sending a voice message with message text:

Note: better to upload an *.ogg file rather than *.mp3, *.wav and others. See Uploading Voice Message for more info.

use BotMan\BotMan\Messages\Attachments\Audio;
use BotMan\BotMan\Messages\Outgoing\OutgoingMessage;

$botman->hears('Sing me a song', function ($bot) {
    // Create attachment
                            // URL can be uploaded ONLY as voice message (due to restrictions of VK)
    $attachment = new Audio('https://url-to-ogg-file');
//  $attachment->addExtras("vk_audio", "audio371745438_456268888"); // Send an already uploaded audio (driver will ignore audio url and vk_as_voice parameter)
    $attachment->addExtras("vk_as_voice", true);                    // Send as voice message (better to use *.ogg file)

    // Build message object
    $message = OutgoingMessage::create('Well...')
        ->withAttachment($attachment);

    // Reply message object
    $bot->reply($message);
});

During upload, the driver will send "recording audio" activity:

Example image

The result:

Example image

Attaching document (file)

Example of sending file:

Note: not all files are available to upload. See Uploading documents for more info.

use BotMan\BotMan\Messages\Attachments\File;
use BotMan\BotMan\Messages\Outgoing\OutgoingMessage;

$botman->hears("Any files\?", function ($bot) {
    $attachment = new File('https://url-to-file');
//  $attachment->addExtras("vk_doc", "doc123456_123456"); // Send an already uploaded document (driver will ignore audio url and vk_doc_title, vk_doc_tags parameters)
    $attachment->addExtras("vk_doc_title", "Cool guy.gif"); // Title
    $attachment->addExtras("vk_doc_tags", "cool, guy"); // Document tags

    // Build message object
    $message = OutgoingMessage::create('Yep!')
        ->withAttachment($attachment);

    // Reply message object
    $bot->reply($message);
});

Uploading a file will also trigger "sending message" activity.

Example image

Attaching location

Example of sending location (taken from BotMan docs):

use BotMan\BotMan\Messages\Attachments\Location;
use BotMan\BotMan\Messages\Outgoing\OutgoingMessage;

$botman->hears('Any locations\?', function($bot) {
    // Create attachment
    $attachment = new Location(61.766130, -6.822510, [
        'custom_payload' => true,
    ]);

    // Build message object
    $message = OutgoingMessage::create('Locations are also supported!')
        ->withAttachment($attachment);

    // Reply message object
    $bot->reply($message);
});

The result:

Example image

Additional parameters

Additional parameters are used to append or replace message request parameters.

Note: v and access_token fields are ignored to be replaced. Change their parameters in .env file or in configuration array.

Example of replacing message text:

$botman->hears('Show me the replaced message', function($bot) {
    $bot->reply("This string will be ignored", [
        "message" => "This message string will be sent"
    ]);
});

The result

See messages.send method for more info.

Sending question buttons (simple keyboard)

Example of sending simple keyboard via adding buttons to question. Keyboard will be shown as one_time = true (shown once) and inline = false (default non-inline keyboard), one button in a row. See Sending full-supported keyboard section for in-depth setup.

use BotMan\BotMan\Messages\Outgoing\Actions\Button;
use BotMan\BotMan\Messages\Outgoing\Question;
$botman->hears("List of functions\?", function ($bot) {
    $question = Question::create('My list of functions:')
        ->addButtons([
            Button::create('Function 1')->value('f1'),
            Button::create('Function 2')->value('f2'),
            Button::create('Function 3')->value('f3'),
            Button::create('Function 4')->value('f4'),
            Button::create('Function 5')->value('f5')
        ]);

    $bot->ask($question, function ($answer) {
        // Detect if button was clicked:
        if ($answer->isInteractiveMessageReply()) {
            $selectedValue = $answer->getValue(); // Contains button value e.g. 'f1', 'f2', ...
            $selectedText = $answer->getText(); // Contains title e.g. 'Function 1', 'Function 2', ...
        }
    });
});

Example image

Note: don't use $answer->getText() for validation purposes as it can be changed by the client (user). Use $answer->getValue() instead.

Note: better to send keyboards only in Conversation class, asking a question with buttons. See more here.

Customizing the question buttons (simple keyboard)

⚠ [Migrating from v.1.4.x and older] Fields of __x and __y are now ignored by the driver. Use VKKeyboard serializing class to build a keyboard and add it to $additionalParameters of your outcoming message.

You can also change button's properties via additional parameters such as colour:

//...
$botman->hears("List of functions\?", function ($bot) {
    $question = Question::create('My list of functions:')
        ->addButtons([
            Button::create('Function 1')->value('f1')->additionalParameters([
                "color" => "secondary" // Colour (see available colours here - https://vk.com/dev/bots_docs_3)
            ]),
            Button::create('Function 2')->value('f2')->additionalParameters([
                "color" => "negative"
            ]),
            Button::create('Function 3')->value('f3')->additionalParameters([
                "color" => "primary"
            ]),
            Button::create('Function 4')->value('f4')->additionalParameters([
                "color" => "primary"
            ]),
            Button::create('Function 5')->value('f5')->additionalParameters([
                "color" => "primary"
            ])
        ]);

    $bot->ask($question, function ($answer) {
        //...
    });
});

Example image

See VK documentation page for available colours, types and other features. Just add new fields in array of additional parameters as it is shown in the example above.

Sending native keyboard

Native keyboard can be send as an additional parameter (works only for VK!):

use BotMan\Drivers\VK\Extensions\VKKeyboard;
use BotMan\Drivers\VK\Extensions\VKKeyboardButton;
use BotMan\Drivers\VK\Extensions\VKKeyboardRow;

$botman->hears('keyboard', function(BotMan $bot) {
    $keyboard = new VKKeyboard();
    $keyboard->setInline(false);    // Setting the inline mode ("inline" parameter)
    $keyboard->setOneTime(false);   // Setting "one_time" parameter
    
    $keyboard->addRows(
        // Top row
        new VKKeyboardRow([
            // Text example
            ( new VKKeyboardButton() )->setColor("primary")->setText("Sample text")->setValue("button1"),
            // UTF-8 text example
            ( new VKKeyboardButton() )->setColor("primary")->setText("Текст для примера")->setValue("button2"),
        ]),
        // Middle row
        new VKKeyboardRow([
            // Long text trim example
            ( new VKKeyboardButton() )
                // Colour (see available colours here - https://vk.com/dev/bots_docs_3)                
                ->setColor("default")
                
                // Long text will be trimed with ellipsis at the end of the label
                ->setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam nec ultrices purus, ut sollicitudin arcu.")

                // Set button value
                ->setValue("button3"), 
        ]),
        // Bottom row
        new VKKeyboardRow([
            // Emoji example
            ( new VKKeyboardButton() )->setColor("negative")->setText("")->setValue("button4"),
            ( new VKKeyboardButton() )->setColor("primary")->setText("")->setValue("button5"),
            ( new VKKeyboardButton() )->setColor("positive")->setText("")->setValue("button6"),
        ])
    );

    $bot->reply("Native keyboard:", [
        "keyboard" => $keyboard->toJSON()
    ]);
});

Example image

You can also send a Question with additional parameters with keyboard:

// ...
$bot->ask($question, function ($answer) {
    // Detect if button was clicked:
    if ($answer->isInteractiveMessageReply()) {
        $selectedValue = $answer->getValue(); // Contains button value e.g. 'f1', 'f2', ...
        $selectedText = $answer->getText(); // Contains title e.g. 'Function 1', 'Function 2', ...
    }
}, [
    "keyboard" => $keyboard->toJSON()
]);
// ...

Listening for images

Native way for receiving images.

Note: no message text will be provided via receivesImages() method.

$botman->receivesImages(function($bot, $images) {
    foreach ($images as $image) {
        $url = $image->getUrl(); // The direct url
        $title = $image->getTitle(); // The title (empty string as titles are not supported by VK)
        $payload = $image->getPayload(); // The original payload

        $bot->reply("Detected image: {$url}");
    }
});

Example image

Listening for videos

Native way for receiving videos.

Note: no message text will be provided via receivesVideos() method.

$botman->receivesVideos(function($bot, $videos) {
    foreach ($videos as $video) {
        $url = $video->getUrl(); // The direct url
        $payload = $video->getPayload(); // The original payload

        // For YouTube videos title can be accessed in the following way:
        $bot->reply("Detected video: {$payload["title"]}");
    }
});

Example image

Listening for audio

Native way for receiving audio.

Note: no message text will be provided via receivesAudio() method.

$botman->receivesAudio(function($bot, $audios) {
    foreach ($audios as $audio) {
        $url = $audio->getUrl(); // The direct url
        $payload = $audio->getPayload(); // The original payload

        $bot->reply("Detected audio: {$url}");
    }
});

Example image

Listening for documents (files)

Native way for receiving files.

Note: no message text will be provided via receivesFiles() method.

$botman->receivesFiles(function($bot, $files) {
    foreach ($files as $file) {
        $url = $file->getUrl(); // The direct url
        $payload = $file->getPayload(); // The original payload

        $bot->reply("Detected file (document): {$url}");
    }
});

Example image

Listening for location

Native way for receiving location.

Note: no message text will be provided via receivesLocation() method.

$botman->receivesLocation(function($bot, $location) {
    $lat = $location->getLatitude();
    $lng = $location->getLongitude();

    $bot->reply("Detected location: $lat $lng");
});

Example image

Receiving messages with mixed attachments

Message with mixed attachments can be asked via hears(), ask() or fallback() method (IncomingMessage with message text and attachments with all supported types).

Example with video and image attachments:

$botman->hears('I have both image and video for you.', function ($bot) {
    $bot->reply("Cool!");

    // Scanning for images
    $images = $bot->getMessage()->getImages() ?? [];
    foreach ($images as $image) {

        $url = $image->getUrl();

        $bot->reply("Image found: {$url}");
    }

    // Scanning for videos
    $videos = $bot->getMessage()->getVideos() ?? [];
    foreach ($videos as $video) {
        $payload = $video->getPayload();

        $bot->reply("Video found: {$payload["title"]}");
    }
});

Example image

Retrieving extra user data

Extra user fields should be defined in .env file and can be accessed via getUser()->getInfo() method.

⚠ [Migrating from v.1.5.x and older] screen_name is now used by the driver too. Remove screen_name value from user_fields parameter to prevent sending screen_name twice. Use $bot->getUser()->getUsername() to get username.

Example contents of .env:

# ...
VK_USER_FIELDS="photo_200_orig"
# ...

Example route:

$botman->hears('Gimme my photo_200_orig', function ($bot) {
    $bot->reply('Here it is: '.$bot->getUser()->getInfo()["photo_200_orig"]);
});

Example image

Multiple fields should be comma-separated:

# ...
VK_USER_FIELDS="photo_200_orig, photo_50"
# ...

See User object for available fields.

Retrieving extra client information

Information about supported features of user's VK client can be accessed via $bot->getMessage()->getExtras("client_info"):

Note: the feature works only with new messages sent (message_new event).

$botman->hears('my info', function(BotMan $bot) {
    // Prints raw "client_info" array
    $bot->reply(print_r($bot->getMessage()->getExtras("client_info"), true));
});

The reply

See Information about features available to the user for more details.

Mark seen example

Every message will be marked as seen even if there is no response for it:

$botman->hears("Don\'t answer me", function ($bot) {
    // Do nothing
});

Example image

Listening to events

List of supported events:

  • confirmation
  • message_allow
  • message_deny
  • message_typing_state *
  • message_event *
  • photo_new
  • photo_comment_new
  • photo_comment_edit
  • photo_comment_restore
  • photo_comment_delete
  • audio_new
  • video_new
  • video_comment_new
  • video_comment_edit
  • video_comment_restore
  • video_comment_delete
  • wall_post_new
  • wall_repost
  • wall_reply_new
  • wall_reply_edit
  • wall_reply_restore
  • wall_reply_delete
  • board_post_new
  • board_post_edit
  • board_post_restore
  • board_post_delete
  • market_comment_new
  • market_comment_edit
  • market_comment_restore
  • market_comment_delete
  • market_order_new *
  • market_order_edit *
  • group_leave
  • group_join
  • user_block
  • user_unblock
  • poll_vote_new
  • group_officers_edit
  • group_change_settings
  • group_change_photo
  • vkpay_transaction *
  • app_payload *
  • like_add *
  • like_remove *

* - missing english version in VK docs, but feature exists (as for 14.08.2020)

** - missing in VK docs, but feature exists (as for 14.08.2020)

Note: events of message_new, message_reply, message_edit are assessable via Hearing Messages functions (e.g. $botman->hear()).

Full list of events (VK docs)

Example of sending message when the typing state changed:

$botman->on("message_typing_state", function($payload, $bot){
    // $payload is an array of the event object ("Object field format"),
    // excepting Confirmation event, where $payload contains full root JSON schema.
    // See https://vk.com/dev/groups_events for more info
    $bot->say("Hey! You're typing something!", $payload["from_id"]);
});

Note: $bot->reply() is not supported here, use $bot->say("...", $peer_id_from_data) instead.

The result:

The result image

ℹ️ Don't forget to enable a Typing status event in Callback API -> Event types tab.

Typing status enabled

Sending low-level API requests

Example of sending a sticker via $bot->sendRequest():

Note: it is also possible to send stickers via additional parameters.

$botman->hears('sticker', function($bot) {
    // API method
    $endpoint = "messages.send";
    
    // Arguments ("v" and "access_token" are set by driver, no need to define)
    $arguments = [
         "peer_id" => $bot->getUser()->getId(), // User ID
         "sticker_id" => 12, // Sticker ID
         "random_id" => 0 // required by VK API
    ];

    $test = $bot->sendRequest($endpoint, $arguments);
    // $test now equals to ["response" => 1234];
});

The result:

The result of sticker sending

Sending carousels

The driver also ships with implemented wrapper for attaching native carousel objects.

For example:

use BotMan\Drivers\VK\Extensions\VKKeyboardButton;
use BotMan\Drivers\VK\Extensions\VKCarousel;
use BotMan\Drivers\VK\Extensions\VKCarouselActionOpenLink;
use BotMan\Drivers\VK\Extensions\VKCarouselElement;

$botman->hears('carousel', function($bot) {
    $carousel = new VKCarousel();

    for($i = 1; $i <= 10; $i++){
        $carousel->addElements(
            new VKCarouselElement(
                "Element {$i}",
                "Description {$i}",
                [
                    ( new VKKeyboardButton() )
                        ->setColor("secondary")->setText("Button {$i}")->setValue("button1")
                ],
                "-00000_11111", // This is an example icon ID:
                                // replace `00000` with community ID, the `11111` - with image ID
                new VKCarouselActionOpenLink("https://some-url/")
            )
        );
    }

    $bot->reply("Native carousel:", [
        "template" => $carousel->toJSON()
    ]);
});

Example result

See also

License

VK Community Callback driver is made under the terms of MIT license. BotMan is free software distributed under the terms of the MIT license.

botman-vk-community-callback-driver's People

Contributors

yageorgiy avatar yui-ezic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

botman-vk-community-callback-driver's Issues

Бот отправляет сообщение в беседу несколько раз, перед этим он их уже кидал.

Describe the bug
A clear and concise description of what the bug is.

Бот отправляет сообщение в беседу несколько раз, перед этим он их уже кидал.
Иногда это происходит, а иногда нет. Может выкинуть то же что я писал 5 минут назад.

To Reproduce
Steps to reproduce the behavior:

  1. Use method '...' with specific arguments '...' [or] send specific payload '...'
  2. See stack trace error

Ошибок нет, что бы повторить достаточно написать в беседу.

Expected behavior
A clear and concise description of what you expected to happen.

Чтобы он не отправлял сообщения, на которые уже прочитал.

Screenshots
If applicable, add screenshots to help explain your problem.

image

Environment

  • Driver version: [e.g. 1.6.3]
  • VK client: [any, website, mobile website, mobile client, desktop, client, 3d-party client: Name, Version]
  • PHP version: [e.g. 7.4.3] 7.2

Additional context
Add any other context about the problem here.

В логах вк это сообщение также отправляется боту, видимо несколько раз, но не думаю что это баг вконтакте.

Buttons не видит другие Type кроме text и callback

Botman(не студия) | PHP 7.3.11 | "version" => "5.103"

В документации сказано:

Sending links | ✔ Supported
See VK documentation page for available colours, types and other features. Just add new fields in array of additional parameters as it is shown in the example above.

Оба способа выставления Type не работают:

$buttons = array(
 Button::create('pay')->additionalParameters(["action" => ["type" => "open_link", "url" => "https://vk.com", "label" => "test"])
);
$question = Question::create('test')->addButtons($buttons);

$open_link = ["type" => "open_link", "url" => "https://vk.com", "label" => "test"];
$keyboard->addRows(
 new VKKeyboardRow([	            
  ( new VKKeyboardButton() )->setRawAction($open_link)->setPayload(json_encode(["action"=>$open_link]))->setColor(null)
 ])
);

Судя по коду драйвер принудительно выставляет цвет, что возможно противоречит той же информации по ссылке от ВК:

//class VKKeyboardButton
const COLOR_PRIMARY = "primary";
protected $color = self::COLOR_PRIMARY;
public function toArray(){
 return [
  "color" => $this->color,
  "action" => $this->action
 ];
}

цвет кнопки. Параметр используется только для кнопок с type: text и callback.

Если убрать обязательное требование цвета, то некоторые Type вроде open_app удалось заставить работать, но open_link даже так почему-то не работает:

public function toArray(){
        if( !isset($this->color) ){
            return [                
                "action" => $this->action
            ];
        }
        return [
            "color" => $this->color,
            "action" => $this->action
        ];
}

// без обязательного цвета кнопки этот пример из ВК работает
$open_app = [
 "type" => "open_app",                	
 "app_id" => 6232540,
 "owner_id" => -157525928,
  "hash" => "123",
 "label" => "LiveWidget"	                
];

$keyboard->addRows(
  new VKKeyboardRow([	            
  ( new VKKeyboardButton() )->setRawAction($open_link)->setPayload(json_encode(["action"=>$open_app]))->setColor(null)
 ])
);

Different errors in markSeen() method

When adding a bot to a chat, I got the error in markSeen method() "VK API returned error when processing method 'messages.markAsRead': One of the parameters specified was missing or invalid: message_ids is undefined."

I found several errors in this method.

Firstly, $matchingMessage->getPayload()->get("id") returns nothing because payload is json like

{
    "type": "message_new",
    "object": {
        "message": {
            "date": <int>,
            "from_id": <int>,
            "id": <int>,
            ...
        }
}

and id fields locate inside object.message. To get it we need to use $matchingMessage->getPayload()->get("object")['message']['id'] .

Secondly, 'message_ids' fields is deprecated from version 5.80 (https://vk.com/dev/messages.markAsRead).
Screenshot
(It's funny, but this is not written in the English version of the documentation)

Third, I don't know how to make this method work in chat. Maybe because messages from chats are not stored for bots and their id is always equals to zero.

"types" method api error, when sending message with attachment

Code:

$attachment = new File('http://url');
$message = OutgoingMessage::create($text, $attachment);
$botman->say($message, $vkId);

Error:

    [content:protected] => {\"error\":{\"error_code\":100,\"error_msg\":\"One of the parameters specified was missing or invalid: you should specify correct user_id, chat_id, or domain param\",\"request_params\":[{\"key\":\"method\",\"value\":\"messages.setActivity\"},{\"key\":\"oauth\",\"value\":\"1\"},{\"key\":\"peer_id\",\"value\":\"\"},{\"key\":\"type\",\"value\":\"typing\"},{\"key\":\"v\",\"value\":\"5.103\"}]}}
    [version:protected] => 1.0
    [statusCode:protected] => 200
    [statusText:protected] => OK
    [charset:protected] => 
)
 at vendor\\yageorgiy\\botman-vk-community-callback-driver\\src\\VkCommunityCallbackDriver.php:1117)
[stacktrace]
#0 vendor\\yageorgiy\\botman-vk-community-callback-driver\\src\\VkCommunityCallbackDriver.php(1053): BotMan\\Drivers\\VK\\VkCommunityCallbackDriver->api('messages.setAct...', Array, true)
#1 vendor\\yageorgiy\\botman-vk-community-callback-driver\\src\\VkCommunityCallbackDriver.php(980): BotMan\\Drivers\\VK\\VkCommunityCallbackDriver->types(Object(BotMan\\BotMan\\Messages\\Incoming\\IncomingMessage))
#2 vendor\\yageorgiy\\botman-vk-community-callback-driver\\src\\VkCommunityCallbackDriver.php(850): BotMan\\Drivers\\VK\\VkCommunityCallbackDriver->prepareAttachments(Object(BotMan\\BotMan\\Messages\\Incoming\\IncomingMessage), Object(BotMan\\BotMan\\Messages\\Attachments\\File))
#3 vendor\\botman\\botman\\src\\BotMan.php(642): BotMan\\Drivers\\VK\\VkCommunityCallbackDriver->buildServicePayload(Object(BotMan\\BotMan\\Messages\\Outgoing\\OutgoingMessage), Object(BotMan\\BotMan\\Messages\\Incoming\\IncomingMessage), Array)
#4 vendor\\botman\\botman\\src\\BotMan.php(560): BotMan\\BotMan\\BotMan->reply(Object(BotMan\\BotMan\\Messages\\Outgoing\\OutgoingMessage), Array)

Debug:

public function types(IncomingMessage $matchingMessage)
    {
        dd($matchingMessage);
        $this->api("messages.setActivity", [
            "peer_id" => $matchingMessage->getRecipient(),
            "type" => "typing"
        ], true);

        return true;
    }

Debug output:

BotMan\BotMan\Messages\Incoming\IncomingMessage {#1901
  #message: ""
  #sender: 412312311
  #recipient: ""
  #images: []
  #videos: []
  #payload: null

My solution:

public function types(IncomingMessage $matchingMessage)
    {
        $this->api("messages.setActivity", [
            "peer_id" => !empty($matchingMessage->getRecipient()) ? $matchingMessage->getRecipient() : $matchingMessage->getSender(),
            "type" => "typing"
        ], true);

        return true;
    }

AND The same error when uploading file. Code trying to call getRecipient:

private function prepareAttachments($matchingMessage, $attachment){
        $ret = [];
        $peer_id = $matchingMessage->getRecipient();

Must be replaced to:

$peer_id = !empty($matchingMessage->getRecipient()) ? $matchingMessage->getRecipient() : $matchingMessage->getSender();

ВК шлет запросы с одинаковым event_id, а бот считает их разными командами

Describe the bug

Иногда ВКонтакте отправляет несколько одинаков запросов c одинаковыми "event_id" в результате все рушится. Из-за того что пуступают одинаковые команды. А у меня бот-викторина. И происходит ответ на следующие вопросы сам по себе.

Ошибка может не проявлятся несколько дней. А потом ВК начинает слать по несколько раз. Например сегодня постоянно шлет одинаковые запросы пачками.

To Reproduce

Вот например:

  1. 29.01.2023 22:39:36 | message_new
    {
    "group_id": 00000000,
    "type": "message_new",
    "event_id": "beea7f04ba6a1553adcc5445943e118d151169ff",
    "v": "5.103",
    "object": {
    ...
  2. 29.01.2023 22:39:54 message_new
    {
    "group_id": 00000000,
    "type": "message_new",
    "event_id": "beea7f04ba6a1553adcc5445943e118d151169ff",
    "v": "5.103",
    "object": {
    "message": {
    ...

Пожалуйста помогите.

Спасибо.

Driver always matching

In class VkCommunityCallbackDriver field payload will never be null, because constructor call method buildPayload() which fill this field. But in method hasMatchingEvent() you do next check

public function hasMatchingEvent() {
   if (!is_null($this->payload)) {
        //...
    }

    return false;
}

Due to the fact that the payload is never null, the method never returns false and always matches. This leads to inoperability of other drivers.

Crash when pressing "Start" button, provided by vk bots functionality

Request string

{"type":"message_new","object":{"message":{"date":1600265466,"from_id":11111111,"id":65,"out":0,"peer_id":11111111,"text":"Начать","conversation_message_id":1,"fwd_messages":[],"important":false,"random_id":0,"attachments":[],"payload":"{\"command\":\"start\"}","is_hidden":false},"client_info":{"button_actions":["text","vkpay","open_app","location","open_link"],"keyboard":true,"inline_keyboard":true,"carousel":false,"lang_id":0}},"group_id":11111,"event_id":"82d32482992f91243a","secret":"asdyhauihsdiyasd"}

Error str

[stacktrace]

#0 vendor\\yageorgiy\\botman-vk-community-callback-driver\\src\\VkCommunityCallbackDriver.php(242): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(8, 'Undefined index...', 'C:\\\\Data\\\\Dev\\\\lnu...', 242, Array)

#1 vendor\\botman\\botman\\src\\BotMan.php(192): BotMan\\Drivers\\VK\\VkCommunityCallbackDriver->getMessages()

#2 vendor\\botman\\botman\\src\\Traits\\HandlesConversations.php(170): BotMan\\BotMan\\BotMan->getMessages()

#3 vendor\\botman\\botman\\src\\BotMan.php(422): BotMan\\BotMan\\BotMan->loadActiveConversation()

#4 app\\Http\\Controllers\\BotManController.php(18): BotMan\\BotMan\\BotMan->listen()```

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.