Как автоматизировать контроль кабинетов Яндекс.Директ с помощью Telegram бота
СТАТЬЯ
Надоело каждый день заходить в рекламные кабинеты? Боитесь упустить момент, когда на балансе не останется средств? Хотели бы получать статистику прямо на телефон?
Делаем Telegram чат-бота, который будет присылать информацию о статистике за прошедший день и остаток на балансе ваших аккаунтов в Яндекс.Директ.
Будет полезно тем, кто ведет много проектов и хочет упростить работу за их отслеживанием.
Регистрация приложения
Первый делом надо зарегистрировать свое приложение в OAuth Яндекс.

Переходим на страницу https://oauth.yandex.ru/client/new
В графе «Для какой платформы нужно приложение?» выбираем «Веб-сервисы». И в качестве Callback URL указываем «https://oauth.yandex.ru/verification_code»

Ниже находим и ставим галочку у «Яндекс.Директ»
Сохраняем наше приложение и получаем данные такой страницы.
Теперь нужно добавить наше приложение в наш кабинет Яндекс.Директ. Для этого переходим по ссылке https://oauth.yandex.ru/authorize?response_type=token&client_id=ClientID&login_hint=login

ClientID - берем из кабинета с вашим приложением.
login - это ваш логин, куда вы хотите добавить ваше приложение

После перехода по ссылке и входа в аккаунт, мы попадаем на страницу с токеном. Сохраняем его. Он нам понадобится далее.
Скрипт бота
Сначала создадим файл config.py.

Ссылка GitHub проект https://github.com/zaharovmail/adsinfobot_v1

# Токен нашего бота
tokenbot = '1111111111:AAAAAaaaaaAAAAAaaaaa'

# Адрес для работы с API 5
ReportsURL5 = "https://api.direct.yandex.com/json/v5/reports"
# Адрес для работы с API 4 Live
ReportsURL4 = "https://api.direct.yandex.ru/live/v4/json/"

# Список наших логинов и токенов
login_token = {'login1':'token1','login2':'token2'}
# Chat_ID людей у кого есть разрешения
chat_id = ['11111111','222222222']
В этом файле у нас хранятся переменные с токеном нашего бота, ссылки для обращения к API Яндекс Директа, словарь наших логинов : токенов и chat_id кому разрешено получать сообщения (чтобы третьи лица не могли получить нашу статистику).

Создаем второй файл «yaDirect.py» для получения из API Яндекс Директа необходимых нам данных.

import config
import requests
from requests.exceptions import ConnectionError
from time import sleep
import json
import datetime

yesterday = str(datetime.date.today() - datetime.timedelta(days=1))

# Метод для корректной обработки строк в кодировке UTF-8 как в Python 3, так и в Python 2
import sys
if sys.version_info < (3,):
    def u(x):
        try:
            return x.encode("utf8")
        except UnicodeDecodeError:
            return x
else:
    def u(x):
        if type(x) == type(b''):
            return x.decode('utf8')
        else:
            return x

# Функция получения остатка баланса
def yaBalance(token, login):
    # Создание тела запроса
    body = {
        "method": "AccountManagement",
        "token": token,
        "locale": "ru",
        "param": {
            "Action": "Get"
        },
        "SelectionCriteria": {
            "Logins": [
                login
            ]
        }
    }
    body = json.dumps(body, indent=4)
    while True:
        try:
            req = requests.post(config.ReportsURL4, body)
            req.encoding = 'utf-8'
            if req.status_code == 400:
                info = ("Параметры запроса указаны неверно или достигнут лимит отчетов в очереди")
                break
            elif req.status_code == 200:
                r = req.json()
                info = [r['data']['Accounts'][0]['Login'], r['data']['Accounts'][0]['Amount'],
                        r['data']['Accounts'][0]['Currency']]
                break
            else:
                info = ("Произошла непредвиденная ошибка")
                break
        except:
            info = ("Произошла непредвиденная ошибка")
            break
    return info

# Функция получения статистики
def yaStat(token, login):
    headers = {
        "Authorization": "Bearer " + token,
        "Client-Login": login,
        "Accept-Language": "ru",
        "processingMode": "auto"
    }
    body = {
        "params": {
            "SelectionCriteria": {
                "DateFrom": yesterday,
                "DateTo": yesterday
            },
            "FieldNames": [
                "Date",
                "Impressions",
                "Clicks",
                "Cost"
            ],
            "ReportName": u(f"ACCOUNT {login}"),
            "ReportType": "ACCOUNT_PERFORMANCE_REPORT",
            "DateRangeType": "CUSTOM_DATE",
            "Format": "TSV",
            "IncludeVAT": "NO",
            "IncludeDiscount": "NO"
        }
    }
    body = json.dumps(body, indent=4)
    while True:
        try:
            req = requests.post(config.ReportsURL5, body, headers=headers)
            req.encoding = 'utf-8'
            if req.status_code == 400:
                info = ("Параметры запроса указаны неверно или достигнут лимит отчетов в очереди")
                break
            elif req.status_code == 200:
                info = format(u(req.text)).replace('Total rows: 1', ' ')
                data = info.split('"')
                body = data[2].split()
                info = (f"{data[1]}\n{body[0]} - {body[4]}\n{body[1]} - {body[5]}\n{body[2]} - {body[6]}\n{body[3]} - {int(body[7]) / 1000000}")
                break
            else:
                info = ("Произошла непредвиденная ошибка")
                break
        except:
            info = ("Произошла непредвиденная ошибка")
            break
    return info
Тут две основные функции yaBalance() - для получения остатка на балансе и yaStat() - для получения статистики за вчера.

Следующий файл у нас будет с самим ботом «bot.py».

from config import tokenbot, login_token, chat_id
from yaDirect import yaBalance, yaStat
import logging
from aiogram import Bot, Dispatcher, executor, types
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton
from aiogram.contrib.fsm_storage.memory import MemoryStorage

# Настраиваем логирование
logging.basicConfig(level=logging.INFO, format='%(asctime)s / %(levelname)s / %(message)s')

# Инициализация бота
bot = Bot(token=tokenbot)
dp = Dispatcher(bot, storage=MemoryStorage())

# Создание клавиатуры
kb_start = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True).row(KeyboardButton('Получить информацию'))

# Старт
@dp.message_handler(commands=['start'])
async def mes_start(message: types.Message):
    user_id = str(message.from_user.id)
    await message.answer(f"Привет {user_id}", reply_markup=kb_start)

# Отправление информации по запросу
@dp.message_handler(regexp='(Получить информацию)')
async def GetInfo(message: types.Message):
    user_id = str(message.from_user.id)
    if user_id in chat_id:
        for item in login_token.items():
            info_balance = yaBalance(item[1], item[0])
            info_stat = yaStat(item[1], item[0])
            await message.answer(f"{info_stat}\nОстаток баланса: {info_balance[1]} {info_balance[2]}", reply_markup=kb_start)

# запускаем лонг поллинг
if __name__ == '__main__':
    executor.start_polling(dp, skip_updates=True)
Получаем готового бота.

При СТАРТЕ бот будет привествовать вас и говорить ваш chat_id. Сохраняйте его в список chat_id в файле «config.py». У бота будет кнопка «Получить информацию», при нажатии на неё бот будет выдавать статистику и остаток на балансе по каждому вашему кабинету.
В итоге получаем такого полезного Telegram бота, который по вашему запросу присылает необходимую вам информацию.
Готовое решение
Мы сделали такого Telegram-бота (https://t.me/ZaharovAdsBot), которого вы можете зайти и протестировать как он работает.

После команды /start, у бота появляется меню.
  1. Жмем «Добавить акк», бот попросит ввести логин аккаунта Яндекс Директ (Почта до @).
  2. После этого бот пришлет ссылку. При переходе по ссылке разрешаем доступ приложению, получаем токен.
  3. Отправляем этот токен боту. Бот проверяет данные.
  4. Если все сделали верно, бот пришлёт сообщение, что аккаунт успешно добавлен.
Как выглядит процесс добавления аккаунта в самом боте
Теперь ежедневно в 10:00 по Московскому времени бот будет присылать статистику из вашего добавленного рекламного кабинета.

Аккаунтов можно добавить неограниченное количество.

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