06.02.2020       Выпуск 320 (03.02.2020 - 09.02.2020)       Статьи

Аналитика для Telegram-ботов, написанных на Python

На данный момент бум на создание телеграмм-ботов начал сходить, но тема их создания не теряет актуальности. Написано множество библиотек для облегчение взаимодействия с Telegram Bot API, но после создания бота я так и не нашёл скрипта(библиотеки) для получения статистики бота. Поэтому решил написать скрипт для всех ботов на Python. Статистику будем получать, логируя действия пользователей и обрабатывая логи в удобный вид.

Читать>>




Экспериментальная функция:

Ниже вы видите текст статьи по ссылке. По нему можно быстро понять ссылка достойна прочтения или нет

Просим обратить внимание, что текст по ссылке и здесь может не совпадать.

На данный момент бум на создание телеграмм-ботов начал сходить, но тема их создания не теряет актуальности. Написано множество библиотек для облегчение взаимодействия с Telegram Bot API, но после создания бота я так и не нашёл скрипта(библиотеки) для получения статистики бота. Поэтому решил написать скрипт для всех ботов на Python. Статистику будем получать, логируя действия пользователей и обрабатывая логи в удобный вид.

Требования для среды

Для использования скрипта нужно установить следующие библиотеки:

pip install datetime
pip install pandas

Как внедрить аналитику в своего бота?

Скачайте с

репозитория

py-скрипт под свою ОС и data.csv файл. Разместите их в папке, где лежит ваш бот.

После подключения используемых вами библиотек в файле с телом бота добавьте строчку:

import tg_analytic

После команд бота добавьте:

tg_analytic.statistics(<id пользователя>, <команда>)

Если вы используете библиотеку telebot, то это должно выглядеть следующим образом:

Также, чтобы получать статистику прямо из бота, нужно добавить в message_handler(content_types=['text']):

if message.text[:(длина ключевого слова)] == '<ключевое слово>':
        st = message.text.split(' ')
        if 'txt' in st or 'тхт' in st:
            tg_analytic.analysis(st,message.chat.id)
            with open('%s.txt' %message.chat.id ,'r',encoding='UTF-8') as file:
                bot.send_document(message.chat.id,file)
                tg_analytic.remove(message.chat.id)
        else:
            messages = tg_analytic.analysis(st,message.chat.id)
            bot.send_message(message.chat.id, messages)

Ключевое слово нужно придумать и вписать для того, чтобы только вы могли просматривать статистику вашего бота. В репозитории хранится также телеграм-бот с уже внедрённой аналитикой, чтобы вы могли ознакомиться как подключить её на примере.

Какие команды использовать для получение статистики?

К примеру ключевое слово будет «статистика»:

    if message.text[:10] == 'статистика' or message.text[:10] == 'Cтатистика':
        st = message.text.split(' ')
        if 'txt' in st or 'тхт' in st:
            tg_analytic.analysis(st,message.chat.id)
            with open('%s.txt' %message.chat.id ,'r',encoding='UTF-8') as file:
                bot.send_document(message.chat.id,file)
                tg_analytic.remove(message.chat.id)
        else:
            messages = tg_analytic.analysis(st,message.chat.id)
            bot.send_message(message.chat.id, messages)

Тело команды боту выглядит следующим образом:

статистика <количество дней> <параметры запроса*>>

* — Есть команды: «пользователи», «команды» и «тхт». Можно использовать одновременно. «Пользователи» даёт статистику по людям за необходимое вам количество дней. «Команды» даёт статистику по командам за необходимое вам количество дней. При указание txt, вы получите файл, в ином случае ответ в телеграмм.

Пример использования команд

Cтатистика 2 пользователи команды Cтатистика 2 команды Статистика 2 пользователи команды тхт

Из чего состоит скрипт?

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

Первая часть скрипта — это логирование действий пользователей. Я принял решение сохранять только дату, id пользователя и используемую им команду:

def statistics(user_id, command):
    data = datetime.datetime.today().strftime("%Y-%m-%d")
    with open('data.csv', 'a', newline="", encoding='UTF-8') as fil:
        wr = csv.writer(fil, delimiter=';')
        wr.writerow([data, user_id, command])

Вторая часть — это обработка данных по запросу и вывод необходимой статистики. Мы считываем данные из csv в Pandas группируем по пользователям и командам:

season = int(bid[1])
#Считывание данных в Dataframe
df = pd.read_csv('data.csv', delimiter=';', encoding='utf8')
#Получение количества всех пользователей и дней
number_of_users = len(df['id'].unique())
number_of_days = len(df['data'].unique())
#Узнаём о количестве пользователей в опредёленные дни
df_user = df.groupby(['data', 'id']).count().reset_index().groupby('data').count().reset_index()
list_of_dates_in_df_user = list(df_user['data'])
list_of_number_of_user_in_df_user = list(df_user['id'])
list_of_dates_in_df_user = list_of_dates_in_df_user[-season:]
list_of_number_of_user_in_df_user = list_of_number_of_user_in_df_user[-season:]
#Узнаем о количестве использованых команд по дням
df_command = df.groupby(['data', 'command']).count().reset_index()
unique_commands = df['command'].unique()
commands_in_each_day = []
list_of_dates_in_df_command = list(df_command['data'])
list_of_number_of_user_in_df_command = list(df_command['id'])
list_of_name_of_command_in_df_command = list(df_command['command'])
commands_in_this_day = dict()
for i in range(len(list_of_dates_in_df_command)):
     commands_in_this_day[list_of_name_of_command_in_df_command[i]] = list_of_number_of_user_in_df_command[i]
     if i + 1 >= len(list_of_dates_in_df_command) or list_of_dates_in_df_command[i] != list_of_dates_in_df_command[i + 1]:
     commands_in_each_day.append(commands_in_this_day)
     commands_in_this_day = dict()
commands_in_each_day = commands_in_each_day[-season:]

Ответ пользователю составляется на основе данных из предыдущего шага:


message_to_user = 'Статистика использования бота за %s %s: \n' % (season, day_type.get(season, 'дней'))
message_to_user += 'Всего статистика собрана за %s %s: \n' % (number_of_days, day_type.get(season, 'дней'))
if season > number_of_days:
     season = number_of_days
     message_to_user += 'Указанное вами количество дней больше,чем имеется\n' \
                        'Будет выведена статистика за максимальное возможное время\n'
if 'пользователи' in bid:
    message_to_user += 'За всё время бота использовало: ' + '%s' % number_of_users \
    + ' %s ' % users_type.get(number_of_users, 'пользователей') + '\n' \
    'Пользователей за последние %s %s: \n' % (season, day_type.get(season, 'дней'))
    for days, number, comm_day in zip(list_of_dates_in_df_user, list_of_number_of_user_in_df_user, 
    commands_in_each_day):
      message_to_user += 'Дата:%s Количество:%d Из них новых:%s\n' % (days, number, comm_day.get('/start', 0))
if 'команды' in bid:
    message_to_user += 'Статистика команд за последние %s %s: \n' %  
    (season,day_type.get(season, 'дней'))
    for days, commands in zip(list_of_dates_in_df_user, commands_in_each_day):
       message_to_user += 'Дата:%s\n' % days
       for i in unique_commands:
           if i in commands:
                message_to_user += '%s - %s раз\n' % (i, commands.get(i))
          else:
                message_to_user += '%s - 0 раз\n' % i

В конце, после составления ответного сообщения, мы проверяем запрос пользователя на наличее команды «тхт», чтобы решить в каком формате ответить:

if 'txt' in bid or 'тхт' in bid:
    with open('%s.txt' % user_id, 'w', encoding='UTF-8') as fil:
        fil.write(message_to_user)
        fil.close()
    else:
        return message_to_user

Заключение

Скрипт оттестирован и работает в нормальном режиме. Если вам интересно посмотреть, как это работает реально на боте, то можете потестировать на любом из моих ботов: @exchange_minsk_bot, @pogoda_belarus_bot, @fast_translate_bot.

Ключевое слово: «статистика».

Приятного использования!






Разместим вашу рекламу

Пиши: mail@pythondigest.ru

Нашли опечатку?

Выделите фрагмент и отправьте нажатием Ctrl+Enter.

Система Orphus