westacks / telebot

Easy way to create Telegram bots in PHP
https://westacks.github.io/telebot/
MIT License
282 stars 44 forks source link

[Cannot cast value of type NULL to type string error in Inline mode] #60

Closed DyarWeb closed 1 year ago

DyarWeb commented 1 year ago

Describe the bug Hello, The library does not support Inline mode and I tested it with a simple bot and got Cannot cast value of type NULL to type string error in log channel

To Reproduce Steps to reproduce the behavior:

1.Turn on Inline mode in BotFather 2.use Inline mode : @bot_username some_thing

Then you will receive the following error in log channel if you add it: Laravel ERROR (local): Cannot cast value of type NULL to type string {"exception":"[object] (WeStacks\\TeleBot\\Exceptions\\TeleBotException(code: 0): Cannot cast value of type NULL to type string at /var/www/vendor/westacks/telebot/src/Helpers/Type.php:96)"} []

Additional context The first time I encountered this problem was September 3. on September 2nd you released version 2.2.2 but I installed earlier versions and it still didn't work.

punyflash commented 1 year ago

Dublicate of #59. I tested inline mode and it works well, attaching script below. Again - your description is unclear. You are only telling that something is not working, but not providing code examples and full error trace. I'm not responsible for mistakes you make in your project.

<?php

use WeStacks\TeleBot\Objects\Update;
use WeStacks\TeleBot\TeleBot;

require_once 'vendor/autoload.php';

$bot = new TeleBot([
    'token' => '<token>'
]);

$bot->addHandler(function (TeleBot $bot, Update $update, callable $next) {
    if (!isset($update->inline_query)) {
        return $next();
    }

    return $bot->answerInlineQuery([
        'inline_query_id' => $update->inline_query->id,
        'results' => [[
            'type' => 'article',
            'id' => 'google',
            'title' => 'Google',
            'url' => 'http://google.com/',
            'input_message_content' => [
                'message_text' => $update->inline_query->query
            ]
        ]]
    ]);
});

$last_offset = 0;
while (true) {
    $updates = $bot->getUpdates([
        'offset' => $last_offset + 1
    ]);
    foreach ($updates as $update) {
        $bot->handleUpdate($update);
        $last_offset = $update->update_id;
    }
}
DyarWeb commented 1 year ago

This is a test and in the file SearchMoviesInlineQuery.php You can see is a very simple handler But the update doesn't reach the handler and it exits in Type.php:96 because $value_type is equal to NULL

punyflash commented 1 year ago

I've just cloned your project, and everything works as intended. image image

DyarWeb commented 1 year ago

I really don't understand that it works properly in long polling mode Screenshot from 2022-12-16 17-14-49 image

But it gives an error in the webhook Screenshot from 2022-12-16 17-23-51 image

punyflash commented 1 year ago

I figured it out. It is actually a bug. There is a weird behavior in Telegram's API: when the incoming update is inline query, there is a field - inline_query.offset. Documentation says that this field is actually a string, however - when you receive updates using long polling, it sends an empty string, as docs say. But when they send a webhook request - they send NULL, that is not passing validation in our library. It's kind of weird, but I guess we can write some "crutches" to expect this from webhooks.

UPD. Actually, by second though, it's not Telegram's API, but Laravel's middleware, that converts empty strings to NULL on every request. It's even easier to fix then. For quick fix: enter app/Http/Kernel.php and remove ConvertEmptyStringsToNull middleware from your global middleware list. In the next update, I'll write the webhook route in a way to bypass Laravel's global middleware

protected $middleware = [
    // \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
DyarWeb commented 1 year ago

ok thank you