×

Нет рутине: как автоматизировать проверку остатков в рекламных кабинетах Яндекс Директа и Google Ads

Россия +7 (909) 261-97-71
Шрифт:
1 10557
Подпишитесь на нас в Telegram

Привет! Я Владимир Малюгин, CEO агентства Performance-маркетинга Digital Geeks. В нашей сфере много рутинных задач, от которых зависит результат. Например, если сотрудник забудет отследить баланс в рекламном кабинете, объявления клиента какое-то время не будут видеть потенциальные покупатели. Чтобы этого не произошло, мы решили делегировать проверку роботу. Алгоритм рассчитывает, на сколько дней хватит бюджета, и отправляет уведомления в Telegram. 

Рассказываю, как мы это сделали, чтобы вы смогли повторить.

Владимир Малюгин, основатель агентства performance-маркетинга Digital Geeks

Задача

У Digital Geeks много аккаунтов в сервисах Google Ads и Яндекс Директ – их ведут разные специалисты. Если деньги в одном из кабинетов закончатся, рекламная кампания остановится, поэтому нужно контролировать остатки.  

Делать это вручную долго и неудобно. Мы решили автоматизировать процесс и создать алгоритм, который будет сообщать об остатках средств. 

Решение 

На базе Google Ads Scripts мы создали алгоритм, интегрированный с чатом в Telegram. Он запускается автоматически и собирает информацию об остатках бюджета каждой активной рекламной кампании (то есть получившей больше одного клика за последние две недели).  

Алгоритм автоматически рассчитывает, на сколько дней хватит средств в личном кабинете. Для этого он вычисляет средние затраты за прошлый день и делит на них сумму остатка. 

Если деньги закончатся быстрее, чем за 5 дней, робот отправляет уведомление в специально созданный чат в Telegram. Сообщение содержит название рекламного кабинета, расход предыдущего дня, актуальный остаток средств и количество дней до блокировки кампании. Получать эту информацию можно не только в мессенджер, но и на электронную почту. 

Уведомления в Telegram

Подобный алгоритм мы создали и для Яндекс Директа. Внутри этого сервиса нет скрипта, поэтому мы сами написали его на языке программирования R. Система работает точно так же, как и робот для Google Ads, отправляя сообщения в тот же чат. 

Решения позволяют извлекать из личных кабинетов не только данные об остатках, но и любую другую информацию. Условия парсинга можно легко поменять. При этом интеграция Google Ads с Telegram реализована напрямую, без привлечения стороннего софта. Для Яндекс Директа мы использовали сервис Make (бывший Integromat). Через него информация об остатках отравляется в Telegram. 

Результат 

Автоматизация не только экономит время сотрудников Digital Geeks, но и помогает минимизировать влияние человеческого фактора. С нашим решением клиенты застрахованы от случайных остановок рекламных кампаний и потери лидов. 

Делимся с вами кодом, с помощью которого и вы сможете автоматизировать проверку остатков бюджета. 

Скрипт для Yandex Direct

Скрипт для Yandex Direct

<pre>

<code>

library(ryandexdirect)

library(dplyr)

setwd("C:/Scripts/Access")

Token = "C:/Scripts/Access"


#Замените login@yandex.ru на ваш агентский аккаунт в Я.Директ

yadirAuth(Login = "login@yandex.ru",

TokenPath = Token)


client <- yadirGetClientList(AgencyAccount= "login@yandex.ru")


print("Получаем данные по расходам Я.Директ")

# загрузка статистики из рекламных аккаунтов привязанных к агентскому аккаунту

stat <- yadirGetReport(ReportType = "CAMPAIGN_PERFORMANCE_REPORT",

DateRangeType = "CUSTOM_DATE",

DateFrom = Sys.Date()-7,

DateTo = Sys.Date()-1,

FieldNames = c(

"Cost"),

FilterList = c("Impressions GREATER_THAN 0"),

AgencyAccount = "login@yandex.ru",

Login = client$Login)


df = as.data.frame(stat)


df1 <- df

df1 %>%

group_by(Login) %>%

summarise_all(sum) %>%

data.frame() -> df1


df1$Cost <- as.numeric(df1$Cost)

df1$Cost <- df1$Cost / 7


client_balance <- yadirGetBalance(Logins = df1$Login,

AgencyAccount = "login@yandex.ru")



client_balance <- as.data.frame(client_balance)


client_balance <-select(client_balance,Login,Amount)

client_balance <- client_balance %>% rename('Balance' = Amount)


client_balance$`Balance` <- as.numeric(client_balance$`Balance`)


client_balance$`Date` <- c(Sys.time())

client_balance$`System` <- c("Яндекс Директ")


client_balance <- client_balance [order (-client_balance$`Balance`),]

client_balance <- subset(client_balance, Login != 'bank')



library(googlesheets4)

#Замените login@site.ru на ваш аккаунт в Gmail

gs4_auth(email = "login@site.ru")


sh = "https://docs.google.com/spreadsheets/ID"


write_sheet(client_balance, sh,sheet = 'Я.Директ')

write_sheet(df1,sh, sheet = "Расход за вчера в Директ")


print("Я.Директ - готово")


</code>

</pre>


Скрипт для Google Ads

Google Ads

<pre>

<code>


var bud = 0


function main ()

{

sendTelegramMessage('Проверка бюджета в Google Ads:', CHAT_ID);

var accounts = MccApp.accounts()

.withCondition("Clicks >= 1")

.forDateRange("LAST_14_DAYS")

.executeInParallel("budgetControl")


Logger.log(bud);

sendTelegramMessage('Бюджет проверен.', CHAT_ID);


}


function budgetControl()

{

var accountName = AdWordsApp.currentAccount().getName();

var budgets = AdWordsApp.budgetOrders().withCondition('Status = ACTIVE').get();

while (budgets.hasNext())

{

try {

var budget = budgets.next();

if (budget.getSpendingLimit() !== null )

{

var startDate = timeFormat(budget.getStartDateTime());

var cost = AdWordsApp.currentAccount().getStatsFor(startDate,today()).getCost().toFixed(2);

var last7DaysCostByDay = (AdWordsApp.currentAccount().getStatsFor("YESTERDAY").getCost()).toFixed(2);

var limit = budget.getSpendingLimit().toFixed(2);

var remainingDays = rDays(limit, cost, last7DaysCostByDay);

var budgetNow = (limit - cost).toFixed(2);

if (budgetNow < 0)

{

var budgetNow = 0;

}

else

{

var budgetNow = budgetNow;

}

Logger.log([accountName, limit, cost, budgetNow,last7DaysCostByDay,remainingDays]);

if (remainingDays < 6 && last7DaysCostByDay >0)

{

bud = 1


sendTelegramMessage('Аккаунт ' + accountName+ '. Осталось на = ' + remainingDays + ' дней.' + ' Текущий остаток = ' + budgetNow + ' рублей.'+ ' Расход за вчера = ' + last7DaysCostByDay + ' рублей.',CHAT_ID);


/*

MailApp.sendEmail(CONFIG.email,

CONFIG.names +' / Заканчивается бюджет на аккаунте: ' + accountName,

'Аккаунт ' + accountName + ' . Текущий остаток = ' + budgetNow +

'. Расход в день = ' + last7DaysCostByDay + ' в валюте аккаунта. ' +

'Денег хватит на ' + remainingDays + ' дня/дней. В аккаунте заканчиваются средства. Необходимо предупредить PM.');

*/

}

}

}

catch (e)


{


Logger.log(e);


sendTelegramMessage('Ошибка выполнения скрипта контроль Бюджетов ' + accountName);

//MailApp.sendEmail(CONFIG.email,

//'Ошибка выполнения скрипта Контроль бюджетов',

//'Необходимо проверить работу скрипта Контроль бюджетов ' + accountName + ' ' + e);

}

}

}



function timeFormat (date)

{

var year = date.year.toString();

var month = date.month.toString();

var day = date.day.toString();

if (month.length == 1)

{

month = "0" + month;

}

if (day.length == 1) {

day = "0" + day;

}

return [year, month, day].join("");

}


function today () {

var date = new Date();

var timeZone = AdWordsApp.currentAccount().getTimeZone();

var format = 'yyyyMMdd';

return Utilities.formatDate(date, timeZone, format);

}

function rDays(limit, cost, last7DaysCostByDay) {

var remainingDays = ((limit - cost) / last7DaysCostByDay).toFixed();

if (remainingDays < 1 || remainingDays == "Infinity" || remainingDays == "-Infinity" || remainingDays == -0 ) {

remainingDays = 0;

}

return remainingDays;

}




function sendTelegramMessage(text, chat) {

var CONFIG2 = {

TOKEN: TOKEN_ID,

//CHAT_ID: '211002715'

CHAT_ID: '-575137669'

};

var telegramUrl = 'https://api.telegram.org/bot' + CONFIG2.TOKEN + '/sendMessage?chat_id=' + chat + '&text=';

var message = encodeURIComponent(text);

var sendMessageUrl = telegramUrl + message;

var options = {

method: 'POST',

contentType: 'application/json'

};


try {

UrlFetchApp.fetch(sendMessageUrl, options);

} catch (e) {

// Logs an ERROR message.

Logger.log('Ошибка: ' +e);

Logger.log('У пользователя: ' + chat);

}

}


function rDays(limit, cost, last7DaysCostByDay) {

var remainingDays = ((limit - cost) / last7DaysCostByDay).toFixed();

if (remainingDays < 1 || remainingDays == "Infinity" || remainingDays == "-Infinity" || remainingDays == -0 ) {

remainingDays = 0;

}

return remainingDays;

}



</code>

</pre>


Есть о чем рассказать? Тогда присылайте свои материалы в редакцию.


Новые 
Новые
Лучшие
Старые
Сообщество
Подписаться 
Подписаться на дискуссию:
E-mail:
ОК
Вы подписаны на комментарии
Ошибка. Пожалуйста, попробуйте ещё раз.
Отправить отзыв
  • Гость
    1
    комментарий
    0
    читателей
    Гость
    больше года назад
    со временем скрипт начнет работать не правильно. так как он не учитывает возвраты за недействительный клики или скликивание.
    -
    1
    +
    Ответить
ПОПУЛЯРНЫЕ ОБСУЖДЕНИЯ НА SEONEWS
Как ИИ усиливает маркетинг и помогает общаться с пользователем
Иван
1
комментарий
0
читателей
Полный профиль
Иван - Классная статья, забрал Хотелось бы услышать еще от эксперта мнение про модели в таком случае и дисперсию
Тренды e-commerce 2026: рынок ждет отток с маркетплейсов?
Арина
1
комментарий
0
читателей
Полный профиль
Арина - Мы пробовали разные сервисы, но уже давно используем этот сервис tryon.mall-er.com у них есть и Визуальный поиск и Виртуальная примерка. Мы пользуемся Виртуальной примеркой очков и поиском и внедрили себе на сайт, сейчас порядка 80% нашего трафика с удовольствием пользуются данными функциями.
SEO-анализ сайта – новый сервис для технического аудита сайта
Олег Алексеев
1
комментарий
0
читателей
Полный профиль
Олег Алексеев - Сюда t.me/obivaaan или сюда t.me/olegalexeyev
Что будет с SEO в 2026: эксперты рынка подводят итоги и делают прогнозы на этот год
Марал Гаипова
142
комментария
0
читателей
Полный профиль
Марал Гаипова - Дмитрий, спасибо, эксперты и правда - топ)
Ozon добавил генерацию ответов на отзывы с помощью ИИ
Сергей
1
комментарий
0
читателей
Полный профиль
Сергей - Интересно добавят ли такую фичу, чтобы покупатель товара мог "свой" сгенерированный отзыв о товаре добавлять и получать за это балы? :)
Мошенники придумали новую схему обмана с дипфейками
Константин Овсиенко
1
комментарий
0
читателей
Полный профиль
Константин Овсиенко - Мошенники в телеграм 2202206115977659 Юлия Владимировна К.
Где взять данные о GEO-видимости: 9 инструментов в одной статье
Евгений Молдовану
1
комментарий
0
читателей
Полный профиль
Евгений Молдовану - Хороший список, но используя подобные чекеры помните, что в GEO важен консенсус и если его нет, то на каждый запрос может формироваться свой ответ.
Высокая позиция в Яндексе: гарантированный билет в нейроответы или миф?
Старый сеошник
7
комментариев
0
читателей
Полный профиль
Старый сеошник - Так наивно повелся на заголовок и обещание исследования на 5 млн запросах. А попал на частные мнения трех сеошников с общими формулировками и аргументами, которые гуляют по интернету уже полгода почти)
Лучшие бесплатные редакторы видео
Сергей
22
комментария
0
читателей
Полный профиль
Сергей - По-моему, тут в минусах явно не хватает пункта о наложении водяного знака - можно все минусы стерпеть, но если у видео будет водяной знак, то зачем вообще таким приложением пользоваться? Если только для тестирования. А вы много тестируете? Вряд ли. Поэтому непонятно почему авторы статьи не внесли самый важный пункт в список недостатков. Лишь пару раз это всплывает во писаниях, а должно быть везде!
Стратегии в Mobile: как построить эффективную коммуникацию
Потаппотейтос
1
комментарий
0
читателей
Полный профиль
Потаппотейтос - у вас что, циклическая ссылка на странице? дальше оптимизацию смотреть?
ТОП КОММЕНТАТОРОВ
Комментариев
910
Комментариев
834
Комментариев
554
Комментариев
540
Комментариев
483
Комментариев
393
Комментариев
373
Комментариев
262
Комментариев
249
Комментариев
171
Комментариев
156
Комментариев
142
Комментариев
128
Комментариев
121
Комментариев
100
Комментариев
97
Комментариев
97
Комментариев
96
Комментариев
80
Комментариев
77
Комментариев
74
Комментариев
67
Комментариев
66
Комментариев
60
Комментариев
59

Отправьте отзыв!
Отправьте отзыв!