Core: Raw Message Data

Created on 19 May 2016  路  11Comments  路  Source: php-telegram-bot/core

I want to add Botan.io statistics to my bot. There is a piece of documentation from the site:

$messageObj = json_decode($message_json, true);
$messageData = $messageObj['message'];

$botan = new Botan($this->token);
$botan->track($messageData, 'Start');

How can I get $messageData with your SDK? Or perhaps you can recommend another statistic platform.

Thank you!

Most helpful comment

Just had a quick look at it and I don't think it's a question any more if we're going to add it!
Looks amazing!

@jacklul Would you like to create a new issue dedicated to this? That'd be great 馃槉

All 11 comments

This is how I integrated it in my bots:

changes in Telegram.php

    public function executeCommand($command)
    {
        $command_obj = $this->getCommandObject($command);

        if (!$command_obj || !$command_obj->isEnabled()) {
            //Failsafe in case the Generic command can't be found
            if ($command === 'Generic') {
                throw new TelegramException('Generic command missing!');
            }

            //Handle a generic command or non existing one
            $this->last_command_response = $this->executeCommand('Generic');
        } else {
            //execute() method is executed after preExecute()
            //This is to prevent executing a DB query without a valid connection
            $this->last_command_response = $command_obj->preExecute();

            $this->botanTrack($this->input, $command);
        }

        return $this->last_command_response;
    }

    /**
     * Botan.io track code
     *
     * @param $input
     * @param $command
     */
    private function botanTrack($input, $command)
    {
        $obj = json_decode($input, true);
        if (isset($obj['message']) && $obj['message']['from']['username'] != $this->bot_name && strtolower($command) != 'generic' && strtolower($command) != 'genericmessage') {
            $data = $obj['message'];

            if ($obj['message']['entities'][0]['type'] == 'bot_command') {
                $event_name = 'Command (/'.strtolower($command).')';
            } elseif ($obj['message']['chat']['type'] == 'private') {
                $event_name = 'Message';
            }
        } elseif (isset($obj['inline_query'])) {
            $data = $obj['inline_query'];
            $event_name = 'InlineQuery';
        } elseif (isset($obj['chosen_inline_result'])) {
            $data = $obj['chosen_inline_result'];
            $event_name = 'ChosenInlineResult';
        } elseif (isset($obj['callback_query'])) {
            $data = $obj['callback_query'];
            $event_name = 'CallbackQuery';
        }

        if (!empty($event_name) && !empty($data)) {
            $botan = new Botan();
            $botan->track($data, $event_name);
        }
    }

and this should be placed where Telegram.php is:

Botan.php

<?php

namespace Longman\TelegramBot;

class Botan
{
    protected $track_url = 'https://api.botan.io/track?token=#TOKEN&uid=#UID&name=#NAME';
    protected $shortener_url = 'https://api.botan.io/s/?token=#TOKEN&user_ids=#UID&url=#URL';

    protected $token = '';

    public function track($message, $event_name = 'Message')
    {
        $uid = $message['from']['id'];
        $url = str_replace(
            ['#TOKEN', '#UID', '#NAME'],
            [$this->token, $uid, urlencode($event_name)],
            $this->track_url
        );

        $options = [
            'http' => [
                'header'  => 'Content-Type: application/json',
                'method'  => 'POST',
                'content' => json_encode($message),
                'ignore_errors' => true
            ]
        ];

        $context = stream_context_create($options);
        $response = @file_get_contents($url, false, $context);
        $responseData = json_decode($response, true);

        return $responseData;
    }

    public function shortenUrl($url, $user_id)
    {
        $url = str_replace(
            ['#TOKEN', '#UID', '#URL'],
            [$this->token, $user_id, urlencode($url)],
            $this->shortener_url
        );

        $options = [
            'http' => [
                'ignore_errors' => true
            ]
        ];

        $context = stream_context_create($options);
        $response = @file_get_contents($url, false, $context);

        return $response === false ? $url : $response;
    }
}

Remember to set your track token in it.

Why silencing errors (@file_get_contents): very often botan API is overloaded and returns error, this does not affect your bot functionality and thats why you shouldn't care about those errors. Of course if you come into issues where it doesnt send statistics you should unsilence file_get_contents for debug purposes.

@akalongman @MBoretto @noplanman We could add build-in support for botan.io in the library, what you guys think?

I never use it so far, I have to say that I don't know exactly what it does (maybe you can explain a bit more the advantages ;) )

Usage could be optional, but it's really good platform to track what commands are executed the most or what types or updates are used, in addition to access to the stats from botaniobot you can also view them on AppMetrica website.

Wow! seems interesting, I will support the introduction, seems also already done ;)

Just had a quick look at it and I don't think it's a question any more if we're going to add it!
Looks amazing!

@jacklul Would you like to create a new issue dedicated to this? That'd be great 馃槉

@noplanman then should I wait for your implementation or do it myself?

@jackul thanks a lot again for your advice!

@deios0 Feel free to implement this 馃憤
Maybe even join up with @jacklul and discuss it in #194

@jacklul I used your code and got an error:

[2016-05-20 07:12:17] prod.ERROR: ErrorException: Undefined index: entities in /vendor/longman/telegram-bot/src/Telegram.php:533

and here is a code on 533:

if ($obj['message']['entities'][0]['type'] == 'bot_command') {
    $event_name = 'Command (/' . strtolower($command) . ')';
} elseif ($obj['message']['chat']['type'] == 'private') {
    $event_name = 'Message';
}

Do you have any ideas?

@deios0 Well, that shouldn't happen,
Telegram API request should contain entities field, for failsafe you can try replacing the line with

if ((isset($obj['message']['entities']) && $obj['message']['entities'][0]['type'] == 'bot_command') || substr($obj['message']['text'], 0, 1) == '/')

Currently working on official integration, if everything will work as expected I'm gonna push this to develop soon!

Ok! Will implement your fix and wait for official integration)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

marcolino7 picture marcolino7  路  3Comments

TheSleepySlee picture TheSleepySlee  路  3Comments

dorcu picture dorcu  路  3Comments

ttvd94 picture ttvd94  路  4Comments

tchibomann picture tchibomann  路  3Comments