Русский
Русский
English
Статистика
Реклама

Facebook api

Из песочницы Urban Bot или как писать чат-ботов для Telegram, Slack, Facebook на React.js

27.07.2020 22:10:16 | Автор: admin

image


В этой статье я хочу познакомить с новой библиотекой Urban Bot, которая адаптирует React для написания чат-ботов. Ниже я расскажу, зачем эта библиотека появилась на свет, какие дает преимущества и как написать вашего первого чат-бота.


Чат-бот это чаще всего отдельный чат в мессенджере, в котором вы общаетесь не с человеком, а с программой. Он может присылать сообщения в виде текста, изображений, кнопок и многих других UI элементов и реагировать на сообщения от пользователей. Современные чат-боты это полноценные UI приложения внутри мессенджеров.

В отличии от большинства чат-бот библиотек, которые чаще всего просто оборачивают http запросы в функции с готовыми аргументами и предоставляют подписки вида bot.on('message', callback), иногда позволяя передавать контекст между вызовами, Urban Bot предлагает совершенно иной подход к разработке чат-ботов через декларативное программирование и компонентный подход. Живой пример, написанный на Urban Bot, вы можете попробовать в Telegram, cсылка на чат-бот, и посмотреть код на GitHub.


Как мы заметили выше, чат-боты это полноценные UI приложения. А какой язык в 2020 и какая библиотека наиболее подходит для разработки UI приложений? Правильно, JavaScript и React. Такая интеграция позволяет легко и непринужденно строить чат-боты любой сложности без единого знания об API мессенджеров. Далее я расскажу, как создавать простые компоненты и на их основе строить сложных чат-ботов, работать с навигацией, создавать диалоги любой вложенности, писать одно приложение и запускать в любых мессенджерах, и многое другое.


Отправка сообщений


Так выглядит самый простой пример на Urban Bot. Для отправки текстового сообщения нам нужно создать функцию и вернуть из него готовый компонент Text с текстом внутри, который мы хотим отправить. Когда компонент отрендериться, все пользователи чат-бота получат сообщение "Hello, world!".


import React from 'react';import { Text } from '@urban-bot/core';function App() {    return (        <Text>           Hello, world!        </Text>    );}

Изображение можно отправить так:


import React from 'react';import { Image } from '@urban-bot/core';function App() {    const imageByURL =  'https://some-link.com/image.jpg';    return <Image file={imageByURL} />;}

Urban Bot имеет готовый набор компонентов, для каждого вида сообщений, для файлов File, для кнопок ButtonGroup и много других, подробнее можно взглянуть здесь. В каждый из них можно передать определенный набор пропсов, например, имитировать будто бот печатает сообщение 1 секунду <Text simulateTyping={1000}>.


Получение сообщений


Мы рассмотрели как посылать сообщения, давайте разберемся как подписываться на сообщения от пользователей. За подписки в Urban Bot отвечают React Hooks.


Чтобы подписаться на текстовые сообщения, мы можем использовать хук useText.


import React from 'react';import { Text, useText } from '@urban-bot/core';function App() {    useText(({ text }) => {        console.log(`Пользователь отправил сообщение ${text}`);    });    return (        <Text>            Hello, world!        </Text>    );}

Urban Bot предоставляет готовы набор хуков для разных типов сообщений. Например, useImage, если пользователь отправил изображение, useFile и т.д. Полный список здесь. В каждый хук также приходит мета информация, кто отправил сообщение и т.д.


Эхо бот


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


В этом компоненте мы впервые добавим работу с переменными через React хук useState. Этот хук возвращает переменную и функцию, чтобы ее изменять. React.useState нужен, чтобы изменение переменной приводило к ререндеру и, соответсвенно, отправке нового сообщения. Мы определим начальное значение переменной text как "Привет" и передадим в компонент Text. Также мы подпишемся на сообщения от пользователей с помощью хука useText, и будем изменять text через функцию setText. После вызова setText React перерендерит компонент Echo с новым значением, и пользователь получит новое сообщение с тем что он сам отправил боту.


import React from 'react';import { Text, useText } from '@urban-bot/core';function Echo() {    const [text, setText] = React.useState('Привет!');    useText(({ text }) => {        setText(text);    });    return (        <Text>            {text}        </Text>    );}

Кнопки


Давайте также напишем пример с кнопками, сделаем простейший счетчик. Для этого нам понадобятся компоненты ButtonGroup и Button. Каждой кнопке мы определим свой обработчик, который будет менять count на +1 или -1 и будем передавать результат в ButtonGroup в проп title. Мы установим проп isNewMessageEveryRender как false, чтобы при последующих ререндерах отправлялось не новое сообщение с новыми кнопками, а просто изменялось начальное сообщение.


import React from 'react';import { ButtonGroup, Button } from '@urban-bot/core';function Counter() {    const [count, setCount] = React.useState(0);    const increment = () => setCount(count + 1);    const decrement = () => setCount(count - 1);    return (        <ButtonGroup title={count} isNewMessageEveryRender={false}>            <Button onClick={increment}>+1</Button>            <Button onClick={decrement}>-1</Button>        </ButtonGroup>    );}


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


Теперь, когда пользователь напишет "/echo" отрендериться компонент Echo, когда "/counter" управление перейдет в Counter. Роуты также могут принимать path как regexp.


import React from 'react';import { Router, Route } from '@urban-bot/core';import { Echo } from './Echo';import { Counter } from './Counter';function App() {    return (        <Router>            <Route path="/echo">                <Echo />            </Route>            <Route path="/counter">                <Counter />            </Route>        </Router>    );}

Визуальный пример, чтобы увидеть как будет работать код.


image


Если вы почувствовали концепцию, то уже поняли, что можно создавать десятки, сотни компонентов, комбинировать их вместе, либо разделять роутером, делиться компонентами между разными чат-ботами и строить действительно сложные SPA внутри мессенджеров.


Форматирование текста


Urban Bot позволяет стилизовать сообщения через привычные HTML теги. Писать жирным <b>, курсивом <i>, зачеркнутым <s>, переносить строки <br /> и так далее, полный список здесь.


Пример
const someCode = `function sum2() {    return 2 + 2;}if (sum2() !== 4) {    console.log('WTF');}`;<Text>    Usual text    <br />    <b>Bold text</b>    <br />    <i>Italic text</i>    <br />    <u>Underscore text</u>    <br />    <s>Strikethrough text</s>    <br />    <q>quote</q>    <br />    <b>        Bold and <s>Strikethrough text</s>    </b>    <br />    <code >Code 2 + 2</code >    <br />    <pre>{someCode}</pre>    <br />    <a href="http://personeltest.ru/aways/github.com/urban-bot/urban-bot">External link</a></Text>


Диалоги


Чат-боты могут вести диалоги с пользователем, что-то спрашивать, реагировать на сообщения в зависимости от ответа пользователя. В Urban Bot встроен компонент Dialog, который позволяет легко создавать диалоги любой сложности.


Пример плоского диалога. Бот задаст первый вопрос, после ответа задаст второй, потом третий, потом запустит callback onFinish с готовыми ответами. На каждом шаге можно обрабатывать ответ пользователя через callback onNext.


import React from 'react';import { Dialog, DialogStep, Text } from '@urban-bot/core';function FlatDialogExample() {    return (        <Dialog onFinish={(answers) => console.log(answers)}>            <DialogStep                content={<Text>Привет, как тебя зовут?</Text>}                 id="name"                onNext={(name) => console.log(name)}            >                <DialogStep                    content={<Text>Cколько тебе лет?</Text>}                    id="age"                >                    <DialogStep                         content={<Text>Из какого ты города?</Text>}                        id="city"                    />                </DialogStep>            </DialogStep>        </Dialog>    );}

Можно получать на следующем шаге прошлый ответ через паттерн render-props .


function FlatDialogExample() {    return (        <Dialog>            <DialogStep content={<Text>Привет, как тебя зовут?</Text>}>                {(name) => (                    <DialogStep                         content={<Text>{`${name}, cколько тебе лет?`}</Text>}                    />                )}            </DialogStep>        </Dialog>    );}

Можно добавить валидацию на каждый шаг.


function FlatDialogExample() {    return (        <Dialog onFinish={(answers) => console.log(answers)}>            <DialogStep                content={<Text>Привет, как тебя зовут?</Text>}                id="name"                validation={{                     isValid: (answer) => answer !== 'Самуэль',                     errorText: 'Самуэль заблокирован.'                 }}            >                // ...            </DialogStep>        </Dialog>    );}

Также возможно построение более сложных диалогов, когда бот отвечает определенным образом в зависимости от ответа пользователя. Для предопределенных ответов можно использовать кнопки.


import React from 'react';import { Dialog, DialogStep, Text, ButtonGroup, Button } from '@urban-bot/core';function TreeDialogExample() {    return (        <Dialog>            <DialogStep                content={                    <ButtonGroup title="Привет, что вы хотите купить?">                        <Button id="hat">Футболка</Button>                        <Button id="glasses">Очки</Button>                    </ButtonGroup>                }            >                <DialogStep                    match="hat"                    content={                        <ButtonGroup title="Футболка какого размера?">                            <Button id="m">S</Button>                            <Button id="s">M</Button>                            <Button id="l">L</Button>                        </ButtonGroup>                    }                />                <DialogStep                    match="glasses"                    content={                        <ButtonGroup title="Очки какого цвета?">                            <Button id="black">Черный</Button>                            <Button id="white">Белый</Button>                        </ButtonGroup>                    }                />            </DialogStep>        </Dialog>    );}

Состояние


Что вы можете использовать для управления состоянием? Все то же что и в любом React приложении. Можете использовать React useState и передавать состояние ниже по дереву компонентов через пропсы или React Context. Можно использовать библиотеки для управления состоянием: Redux (пример), MobX (пример), Apollo и любые другие, которые обычно используют вместе с React, вы можете даже переиспользовать готовые части из готовых React Web или React Native приложений, так как Urban Bot использует тот же чистый React, который работает в миллионах приложений.


Сессия


Urban Bot запускается на сервере, соответсвенно, все логика от всех чатов и пользователей обслуживается на одном железе, что кардинально отличается от стандартных React приложений, которые запускаются на стороне каждого клиента. Urban Bot решает эту проблему на своей стороне и отображает приложение уникальным для каждого пользователя, так что, если вы уже писали на React веб или мобильные приложения, вы не почувствуете разницу.


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


function Counter() {    const [count, setCount] = React.useState(0);    const increment = () => setCount(count + 1);    const decrement = () => setCount(count - 1);    return (        <ButtonGroup title={count} isNewMessageEveryRender={false}>            <Button onClick={increment}>+1</Button>            <Button onClick={decrement}>-1</Button>        </ButtonGroup>    );}

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


function Counter() {    const [count, setCount] = useGlobalCount();   // ...}

Также, в любом месте приложения мы можем получить данные о конкретном чате, какой пользователь написал, с каким никнеймом и т.д. Если чат-бот персональный, то chat и from будут совпадать.


import React from 'react';import { Text, useText, useBotContext } from '@urban-bot/core';function UserId() {    const { chat } = useBotContext();    useText(({ from }) => console.log(`Пришло сообщение от ${from.username}`));   return <Text>Чат id {chat.id}</Text>;}

Типизация


Urban Bot написан на TypeScript, соответсвенно проект полностью типизирован, и если вы пишете на TypeScript, вам будет очень удобно.


Запуск в мессенджерах


Большой плюс Urban Bot, что он не привязан ни к одному мессенджеру. Есть основной пакет @urban-bot/core, который позволяет создавать абстрактных чат-ботов, а уже их подключать к определенным мессенджерам. В данный момент есть поддержка Telegram, Slack, Facebook. В дальнейшем, мы планируем добавлять любые мессенджеры, где есть чат-боты и открытое API. Если вам интересно, и вы хотите писать Urban Bot приложения для других мессенджеров, скажем Viber, Discord или у вас есть свой мессенджер то пишите к нам в группу https://t.me/urbanbotjs, одной просьбы будет достаточно, чтобы появилось большая мотивация реализовать ваш функционал.


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


Скажем, у нас есть готовое приложение App и мы хотим его запустить его в Telegram. Для этого нам понадобится класс UrbanBotTelegram из пакет @urban-bot/telegram. Функция render из @urban-bot/core подобная ReactDOM.render и компонент Root. Мы создаем экземпляр UrbanBotTelegram и передаем туда бот токен из Telegram, также можно передать isPolling, чтобы не настраивать вебхук, и бот работал локально. Готовый экземпляр мы передаем в компонент Root, и оборачиваем наше готовое приложение и, соответсвенно, передаем все в функцию render, которая запустит все процессы.


Более подробная инструкция с видео как разрабатывать локально и деплоить Telegram бота можно прочитать в инструкции.


import React from 'react';import { render, Root } from '@urban-bot/core';import { UrbanBotTelegram } from '@urban-bot/telegram';import { App } from './App';const urbanBotTelegram = new UrbanBotTelegram({    token: 'telegramToken',    isPolling: true,});render(    <Root bot={urbanBotTelegram}>        <App />    </Root>);

Если нам нужно запустить два и более мессенджера, просто используем пакеты других мессенджеров, передаем туда нужные данные и делаем по аналогии с Telegram.


// ...import { UrbanBotSlack } from '@urban-bot/slack';// ...render(    <Root bot={urbanBotTelegram}>        <App />    </Root>);const urbanBotSlack = new UrbanBotSlack({    signingSecret: 'slackSigningSecret',    token: 'slackToken',});render(    <Root bot={urbanBotSlack}>        <App />    </Root>);

Прямой вызов API


С помощью Urban Bot вы можете создавать чат-ботов просто описывая их через компоненты. А что если вам будет нужно вручную вызвать API? Каждый экземпляр UrbanBot* содержит в себе API клиент для активного мессенджера. Рассмотрим пример для Telegram.


Мы можем получить bot с помощью хука useBotContext. bot содержит client и type c типом мессенджера. client будет представлять собой экземпляр библиотеки node-telegram-bot-api . В любом месте приложения можно получить client и вызвать любой метод на ваше усмотрение, скажем блокировать пользователя, если он написал нецензурное сообщение.


import React from 'react';import { useText, useBotContext } from '@urban-bot/core';function SomeComponent() {    const { bot } = useBotContext();    useText(({ text, chat, from }) => {        if (text.includes('бл***')) {            bot.client.kickChatMember(chat.id, from.id);        }    });    // ...}

В каждом мессенджере уникальный API. Если вы разрабатываете несколько мессенджеров одновременно, можно отделять функционал сравнивая bot.type.


import { useBotContext } from '@urban-bot/core';import { UrbanBotTelegram } from '@urban-bot/telegram';import { UrbanBotSlack } from '@urban-bot/slack';function SomeComponent() {    const { bot } = useBotContext();    if (bot.type === UrbanBotTelegram.type) {        // telegram api        bot.client.kickChatMember(/* ... */);    }    if (bot.type === UrbanBotSlack.type) {        // slack api        bot.client.conversations.kick(/* ... */);    }    // ...}

Как попробовать?


У Urban Bot есть стартер, который позволит вам начать разрабатывать чат-ботов за минуту, сделан по аналогии с create-rect-app. Все что вам нужно, чтобы попробовать Urban Bot это выполнить команду в терминале для


TypeScript


npx create-urban-bot my-app

JavaScript


npx create-urban-bot my-app --template js

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


Итого


Несмотря на то что Urban Bot запустился только недавно, на мой взгляд это библиотека с огромным потенциалом. Только представьте, если у вас есть базовые знания React, вы можете написать чат-бот любой сложности на все возможные платформы, создавать и использовать библиотеки с готовым набором компонентов на манер ui-kit, переиспользовать код между вашими другими UI приложеними на React, будь то web или mobile.


Если вы уже разрабатывали чат-ботов, попробуйте Urban Bot, вы почувствуете как библиотека делает за вас кучу работы. Если никогда не разрабатывали, но имеете представление о React, то напишете вашего первого чат-бота за 5 минут. Если вам понравилась идея и хотите, чтобы проект развивался дальше, вступайте в нашу группу в Telegram, ставьте звезду на гитхабе, будем рады любому фидбеку.


Полезные ссылки


Сайт
Github
Группа в Telegram
Наглядный чат-бот в Telegram, с открытым кодом.
Как создать Todo List чат-бот в Telegram с помощью React.js

Подробнее..

Как настроить Facebook Conversion API с помощью GTM Server Side

07.06.2021 22:20:16 | Автор: admin

Отслеживание событий на стороне сервера и Conversion API были доступны на Facebook в течение нескольких лет. Но, начиная с 2021 года, FB стал активнее это продвигать. Если у вас есть свой менеджер в Facebook, помогающий с вашей учетной записью, он, скорее всего, позвонит вам и порекомендует настроить Conversion API.

По этому если с вами уже связались или вы сами решили что вам нужно настроить CAPI (Conversion API) прошу под кат. Там я описываю один из рекомендуемых методов настройки, а именно через Google Tag Manager Server Side.

FB CAPITagFB CAPITag

Для настройки Facebook Conversion API с помощью Google Tag Manager сервер контейнера нужно сначала настроить работу Universal Analytics или GA4 через GTM SS. Все события которые вы хотите отслеживать в Facebook должны быть настроены в UA/GA4 так как вся информация для отправки запроса в FB CAPI будет формироваться на основе событий отправленных в Google Analytics.

В этой статье я не буду рассказывать, как создать и настроить веб контейнер GTM или отслеживание событий с помощью FB web pixel так как предполагается что вы уже хорошо знакомы с настройкой GTM контейнеров.

Что касается изначальной настройки GTM SS это зависит от того какой сервис выбудете использовать для предоставления серверов для вашего серверного контейнера. У каждого есть свои плюсы и минусы. Вы можете выбрать любой подходящий вам это никак не повлияет на работу FB CAPI.

У каждого провайдера серверов для GTM SS есть своя инструкция по настройке контейнера, по этому будем предполагать что вы воспользовались ею и у вас уже есть работающий GTM SS контейнер и ссылка на него.

В текущих реалиях что использовать UA или GA4 для FB CAPI не имеет значения. FB рекомендует GA4 так как он позволяет более легко передавать дополнительные параметры, но с моего опыта нет никаких проблем в передаче дополнительных данных с помощью UA custom dimensions. Так что если у вас не настроен GA4 ничего страшного.

И так после того как разобрались со всеми зависимостями наконец приступим к настройке.

1) Прежде всего, вам необходимо настроить UA или GA4 в GTM Web для отправки событий в GTM SS. Для этого вам нужно установить transport_url параметр указав в качестве значения ссылку на ваш GTM SS сервер.

Для GA4:

GA4 tagGA4 tag

Для UA:

UA tagUA tag

2) Теперь нужно настроить GA на сервер контейнере GTM. Для GA4 создайте тег GA4 a для UA тег Universal Analytics. Также нужно создать триггер в соответствии с вашим типом тега. Тип триггера Custom, выберите Some events. Имя клиента равно Universal Analytics или GA4 в зависимости от выбранного вами типа тега.

Пример тега:

UA Server Side TagUA Server Side Tag

Пример триггера:

UA TriggerUA Trigger

3) Загрузите шаблон тега Facebook из репозитория GitHub и импортируйте его в шаблон тега сервер контейнера. Templates -> Tag Templates -> New. Затем в правом верхнем углу нажмите на точки и выберите импорт. На Github также можно найти и другие FB шаблоны тегов но я использую этот так как он умеет работать с UA а не только с GA4 и имеет больше настроек чем другие.

Server Side Tag ImportServer Side Tag Import

Импорт шаблона:

Server Side TemplateServer Side Template

4) Создайте тег Facebook Conversion API внутри GTM SS контейнера. Tag -> New -> Выберите тег Facebook, который вы импортировали на предыдущем шаге. Добавьте свой идентификатор пикселя Facebook и токен доступа к Facebook API (я рекомендую добавить их в качестве переменных, поскольку вам понадобятся эти значения для каждого Facebook тега). Если вы не знаете свой токен доступа к Facebook API, эта документация поможет вам его найти. Добавьте триггер для тега Facebook Conversion API: new trigger -> custom trigger -> event name equals page_view.

Пример триггера:

5) По такому же принципу вы можете настроить все остальные события которые вас интересуют.

Таким образом у вас будет готова базовая настройка FB CAPI.

Если вы хотите оставить FB Web Pixel вам нужно будет настроить дедупликацию событий. Так как получится что у вас FB web pixel и FB CAPI шлют те же события.

Чтобы настроить дедупликацию FB Conversion API, вам необходимо отправлять уникальный идентификатор события из браузера и с сервера. Одни и те же события из браузера и сервера должны иметь один и тот же идентификатор события. Больше информации про дедупликацию можно найти в документации.

В галерее шаблонов GTM есть Unique Event ID переменная которая создает уникальный ID для каждого события. Используйте эту переменную в FB Web Pixel для отправки event_id а также передавайте ее на сервер с помощью UA custom dimension или GA4 параметра и используйте в FB CAPI теге для отправки того же event_id.

Настройка FB CAPI требует терпения) Так что желаю всем удачи в этом нелегком деле и надеюсь этот пост поможет вам в этом.

Подробнее..

Как узнать, кто отписался в Instagram? И почему мобильные приложения больше не работают

22.09.2020 22:05:57 | Автор: admin

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

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

Как же теперь следить за подписчиками?

Это можно сделать, используя веб-сайт Instagram. Я написал простое приложение, позволяющее следить за подписками/отписками, массово отписываться/подписываться и которое не требует логина/пароля.

Установка приложения делается в 2 шага:

1. Установите расширение для браузера Tampermonkey для Chrome, Microsoft Edge, Safari, Opera или Firefox. Все версии браузеров вы можете найти здесь.

2. Установите Instagram скрипт:

Затем залогиньтесь в веб-версии Instagram и нажмите на кнопку Open app.

Откроется новое окно с тремя кнопками:

Так как мы запустили программу впервые, то выбираем первую кнопку Generate statistics. Откроется таблица с тремя вкладками:

  1. Те, на кого мы обоюдно подписаны

  2. Те, на кого мы подписаны, но они на нас нет

  3. Те, кто подписан на нас, но мы на них нет

Нажмите кнопку Download и сохраните файл в удобное место, чтобы в будущем отслеживать новых подписавшихся/отписавшихся. Затем, в следующий раз, когда захотите увидеть, кто от вас отписался - запустите снова приложение, но на этот раз нажмите вторую кнопку и выберите сохранённый раннее файл.

На этот раз будет две таблицы. Вторая представляет собой отметки времени.

Кликнув по интересующей дате нам будет доступен список подписавшихся/отписавшихся аккаунтов с последней сохранённой даты.

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

Функции массовых отписок/подписок

Данный функционал приложения выходит за рамки данной статьи, но подробно рассказывается в видео:

Исходники кода можно посмотреть здесь.

P.S.: это мой первый пост, прошу прощения, если не так оформил, буду рад услышать критику.

Подробнее..

Recovery mode Как узнать, кто отписался в Instagram? И почему мобильные приложения больше не работают

23.09.2020 00:14:39 | Автор: admin

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

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

Как же теперь следить за подписчиками?

Предупреждение: Не делать на аккаунтах с большим числом подписчиков/подписок (желательно не более тысячи)! Инстаграм посчитает действия подозрительными.

Это можно сделать, используя веб-сайт Instagram. Я написал простое приложение, позволяющее следить за подписками/отписками, массово отписываться/подписываться и которое не требует логина/пароля.

Установка приложения делается в 2 шага:

1. Установите расширение для браузера Tampermonkey для Chrome, Microsoft Edge, Safari, Opera или Firefox. Все версии браузеров вы можете найти здесь.

2. Установите Instagram скрипт:

Затем залогиньтесь в веб-версии Instagram и нажмите на кнопку Open app.

Откроется новое окно с тремя кнопками:

Так как мы запустили программу впервые, то выбираем первую кнопку Generate statistics. Откроется таблица с тремя вкладками:

  1. Те, на кого мы обоюдно подписаны

  2. Те, на кого мы подписаны, но они на нас нет

  3. Те, кто подписан на нас, но мы на них нет

Нажмите кнопку Download и сохраните файл в удобное место, чтобы в будущем отслеживать новых подписавшихся/отписавшихся. Затем, в следующий раз, когда захотите увидеть, кто от вас отписался - запустите снова приложение, но на этот раз нажмите вторую кнопку и выберите сохранённый раннее файл.

На этот раз будет две таблицы. Вторая представляет собой отметки времени.

Кликнув по интересующей дате нам будет доступен список подписавшихся/отписавшихся аккаунтов с последней сохранённой даты.

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

Функции массовых отписок/подписок

Данный функционал приложения выходит за рамки данной статьи, но подробно рассказывается в видео:

Исходники кода можно посмотреть здесь.

P.S.: это мой первый пост, прошу прощения, если не так оформил, буду рад услышать критику.

Подробнее..

Майним еще больше данных настраиваем сбор рекламной статистики TikTok за день

11.06.2021 08:06:47 | Автор: admin

Привет, меня зовут Маша, я работаю маркетинговым аналитиком в Ozon. Наша команда "питонит" и "эскьюэлит" во все руки и ноги во благо всего маркетинга компании. Одной из моих обязанностей является поддержка аналитики для команды медийной рекламы Ozon.

Медийная реклама Ozon представлена на разных площадках: Facebook, Google, MyTarget, TikTok и другие. Для эффективной работы любой рекламной кампании необходима оперативная аналитика. В данной статье речь пойдет о моём опыте сбора рекламных данных с площадки TikTok без посредников и лишних заморочек.

Задача на сбор статистики: вводные

У команды медийной рекламы Ozon есть бизнес-аккаунт TikTok, в котором они управляют всей рекламой на этой площадке. Они долго терпели, сами собирали данные из рекламных кабинетов, но всё-таки настало время, когда терпеть уже больше было нельзя. Так у меня появилась задача на автоматизацию сбора статистики из TikTok.

У нас в базах уже были данные о заказах по кампаниям из TikTok, для эффективной аналитики не хватало данных о расходах.

Итак, весь процесс от "нам нужны данные по расходам из TikTok" до "у нас есть данные по расходам из TikTok" разделился для нас на следующие этапы:

  1. регистрация аккаунта разработчика,

  2. создание приложения,

  3. авторизация бизнес-аккаунта в приложении,

  4. запрос, получение, обработка и загрузка данных.

Рассмотрим каждый из этапов подробнее.

Регистрация разработчика

Мы зарегестрировали аккаунт разработчика на нашего бизнес-менеджера. Перешли на портал TikTok Marketing API, нажали на "My Apps", далее кликнули на "Become a Developer", и началась череда заполнения форм.

TikTok не Facebook, у нас ничего ни разу не отклонял, но всё равно мы были очень внимательны при заполнении полей и не добавляли то, что нам не нужно прямо сейчас. Например, в поле "What services do you provide?" добавили только "Reporting".

Последним пунктом был "Create App". Процесс создания аккаунта разработчика и приложения в первый раз происходит вместе.

Создание приложения

Заполняем имя и описание приложение, callback-address. Далее нужно выбрать разрешения, которые приложение будет запрашивать у авторизирующегося в нем аккаунта. Так же, как и при заполнении полей для аккаунта разработчика, выбрали только пункт "Reporting". Указали ID рекламного аккаунта. После этого отправили приложение на проверку.

Как сообщает TikTok в своей документации, проверка может занять от двух до трех рабочих дней. Мы отправили приложение на проверку в пятницу, в понедельник с утра у нас уже было одобренное приложение и можно было продолжить работу.

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

Авторизация бизнес-аккаунта в приложении

Из всей рутинной работы по заполнению форм, эта часть оказалось самой интересной. У нас не было web-приложения, которое бы отлавливало редирект с авторизационным кодом, поэтому автоматическую авторизацию бизнес-аккаунта сделать не получилось. Но мы оперативно потыкали в кнопки и получили заветный Access Token, с помощью которого собираем данные всех рекламных аккаунтов нашего бизнес-менеджера.

Итак, по порядку, что мы делали не имея сайта, который бы отлавливал callback с авторизационным кодом.

  1. Зашли в приложение и указали Callback Address https://www.ozon.ru.

  2. Скопировали Authorized URL, перешли по нему, авторизовались под аккаунтом бизнес-менеджера.

  3. Согласились на предоставление разрешений для приложения, нажали "Confirm".

  4. Далее нас перекинуло на сайт Ozon, но с дополнительными аргументами в url. Получилось наподобие такого https://www.ozon.ru/?auth_code=XXXXXXXXXXX.

  5. Скопировали значение auth_code, в приложении скопировали secret и app_id и отправили запрос к TikTok на получение long-term Access Token.

curl -H "Content-Type:application/json" -X POST \-d '{    "secret": "SECRET",     "app_id": "APP_ID",     "auth_code": "AUTH_CODE"}' \https://ads.tiktok.com/open_api/v1.2/oauth2/access_token

Получили ответ такого вида:

{    "message": "OK",     "code": 0,     "data": {        "access_token": "XXXXXXXXXXXXXXXXXXXX",         "scope": [4],         "advertiser_ids": [            1111111111111111111,             2222222222222222222]    },     "request_id": "XXXXXXXXXXXXXXX"}

Важно было успеть отправить запрос на получение long-term Access Token как можно быстрее, после редиректа на сайт Ozon. Связано это с временем жизни auth_code 10 минут.

Из полученного ответа необходимо сохранить значения access_token, его нужно использовать при каждом запросе. Если access_token будет потерян или, того хуже, скомпрометирован, нужно будет заново выполнять все пункты по аваторизации аккаунта бизнес-менеджера.

Так же при запросах нам понадобиться список advertiser_ids, но его не обязательно сахранять прямо сейчас список ID аккаунтов всегда можно посмотреть в аккаунте бизнес-менеджера.

Всё, мы готовы писать запросы!

Получение статистики

Когда мы только начинали собирать данные из TikTok, я пользовалась методом, который сейчас depricated, поэтому сразу расскажу о новом.

Итак, у нас есть всё необходимое для получения данных, а именно:

  • access_token,

  • список advertiser_ids.

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

media source -> campaign -> adset -> ad_name

Значение media source всегда неизменно, так как источник один TikTok. По остальным параметрам можно запросить данные из API TikTok.

Теперь нужно было решить, с какой детализацией по времени будем тянуть данные. TikTok позволяет загружать детализацию по часу и дню. Если выгружать детализацию по часу, то, максимум, за один запрос можно получить данные только за один день; если запрашивать детализацию по дням максимум, на один запрос мы получим 30 дней. Конверсии в покупки анализируются за целый день, поэтому и расходы решили собирать за день.

В новом методе получения данных добавили фильтр по типу размещения рекламы: AUCTION и RESERVATION. Ozon использует только AUCTION в своей стратегии ведения кампаний.

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

METRICS = [    "campaign_name", # название кампании    "adgroup_name", # название группы объявлений    "ad_name", # название объявления    "spend", # потраченные деньги (валюта задаётся в рекламном кабинете)    "impressions", # просмотры    "clicks", # клики    "reach", # количество уникальных пользователей, смотревших рекламу    "video_views_p25", # количество просмотров 25% видео    "video_views_p50", # количество просмотров 50% видео    "video_views_p75", # количество просмотров 75% видео    "video_views_p100", # количество просмотров 100% видео    "frequency" # среднее количество просмотра рекламы каждым пользователем]

В документации TikTok для каждого метода API описан пример на языках Java, Python, PHP и также curl-запрос. Я использовала пример на Python с небольшими изменениями.

В примерах из документации TikTok используются две дополнительные библиотеки:

pip install requestspip install six

Библиотека requests необходима для удобной отправки get-запросов. Библиотека six используется для генерации url-адреса запроса.

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

pip install pandaspip install sqlalchemy

В нашей компании для хранения данных используются SQL-подобные хранилища, поэтому я использую pandas для преобразования данных в DataFrame и sqlalchemy для записи DataFrame в базу.

Я использовала функции из примера в документации TikTok для генерации url и отправки запроса.

# генерирует url на основе словаря args с аргументами запросаdef build_url(args: dict) -> str:    query_string = urlencode({k: v if isinstance(v, string_types) else json.dumps(v) for k, v in args.items()})    scheme = "https"    netloc = "ads.tiktok.com"    path = "/open_api/v1.1/reports/integrated/get/"    return urlunparse((scheme, netloc, path, "", query_string, ""))# отправляет запрос к TikTok Marketing API,# возвращает результат в виде преобразованного json в словарьdef get(args: dict, access_token: str) -> dict:    url = build_url(args)    headers = {        "Access-Token": access_token,    }    rsp = requests.get(url, headers=headers)    return rsp.json()

На вход функции get нужно передать список аргументов и access token. Список аргументов под наши цели выглядит следующим образом:

args = {    "metrics": METRICS, # список метрик, описанный выше    "data_level": "AUCTION_AD", # тип рекламы    "start_date": 'YYYY-MM-DD', # начальный день запроса    "end_date": 'YYYY-MM-DD', # конечный день запроса    "page_size": 1000, # размер страницы - количество объектов, которое возвращается за один запрос     "page": 1, # порядковый номер страницы (если данные не поместились в один запрос, аргумент инкрементируется)    "advertiser_id": advertiser_id, # один из ID из advertiser_ids, который мы получили при генерации access token    "report_type": "BASIC", # тип отчета    "dimensions": ["ad_id", "stat_time_day"] # аргументы группировки, вплоть до объявления и за целый день} 

Подробнее про page_size: ответ на запрос может содержать большое количество информации и загружать всё это за один раз не эффективно. Поэтому у TikTok есть ограничение на максимальное количество объектов в ответе 1000. Чтобы получить следующую порцию данных, нужно отправить запрос с теми же входными аргументами на следующую страницу. Подробнее о постраничных запросах ниже.

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

{       # маркер успешности ответа    "message": "OK",    "code": 0,    "data": {        # информация о странице данных        "page_info": {            # общее количество объектов            "total_number": 3000,            # текущая страница            "page": 1,            # количество объектов на одной странице ответа            "page_size": 1000,            # общее количество страниц            "total_page": 3        },        # массив объектов        "list": [            # первый объект            {                # метрики                "metrics": {                    "video_views_p25": "0",                    "video_views_p100": "0",                    "adgroup_name": "adgroup_name",                    "reach": "0",                    "spend": "0.0",                    "frequency": "0.0",                    "video_views_p75": "0",                    "video_views_p50": "0",                    "ad_name": "ad_name",                    "campaign_name": "campaign_name",                    "impressions": "0",                    "clicks": "0"                },                # измерения (по каким параметрам группируем результаты)                "dimensions": {                    "stat_time_day": "YYYY-MM-DD HH: mm: ss",                    "ad_id": 111111111111111                }            },...        ]    },    # id ответа    "request_id": "11111111111111111111111"}

Как я описывала выше, если в ответе получается более 1000 объектов, ответ будет разбит на несколько страниц. В данном случае поле total_page говорит о том, что для получения полного набора данных по указанным параметрам, нужны будут три страницы. Следовательно, запускаем и коллекционируем ответы пока не выгрузим все страницы.

page = 1 # сначала всегда получаем данные по первой страницеresult_dict = {} # словарь, в который будем записывать ответыresult = get(args, access_token) # первый запросresult_dict[advertiser_id] = result['data']['list'] # сохраняем ответ на запрос к первой странице# пока текущая полученная страница page меньше # чем общее количество страниц в последнем ответе resultwhile page < result['data']['page_info']['total_page']:    # увеличиваем значение страницы на 1    page += 1    # обновляем значение текущей страницы в словаре аргументов запроса    args['page'] = page    # запрашиваем ответ по текущей странице page    result = get(args, access_token)    # накапливаем ответ    result_dict[advertiser_id] += result['data']['list']

Такое необходимо повторить для каждого рекламного аккаунта из списка advertiser_ids.

В результате всех вышеописанных манипуляций мы получили для каждого рекламного аккаунта данные по рекламным метрикам. Осталось только преобразовать словарь в pandas.DataFrame и отправить их в базу.

# результирующий DataFrame, который будем записывать в базуdata_df = pd.DataFrame()# для каждого рекламного аккаунта выполнить преобразованиеfor adv_id in advertiser_ids:    # получаем накопленные разультаты для аккаунта из словаря    adv_input_list = result_dict[adv_id]    # временный список    adv_result_list = []    # для каждого объекта    for adv_input_row in adv_input_list:        # берём словарь метрик        metrics = adv_input_row['metrics']        # насыщаем этот словарь словарём измерений        metrics.update(adv_input_row['dimensions'])        # добавляем полученный объект во временный список        adv_result_list.append(metrics)    # преобразуем временный словарь в DataFrame     result_df = pd.DataFrame(adv_result_list)    # добавляем колонку со значением id аккаунта    result_df['account'] = adv_id    # добавляем получившийся DataFrame в результирующий    data_df = data_df.append(        result_df,         ignore_index=True    )## здесь пропущены некоторые манипуляции # по преобразованию строк в числа## запись данных из результирующего DataFrame в базуdata_df.to_sql(    schema=schema,     name=table,     con=connection,    if_exists = 'append',    index = False)

TikTok утверждает, что исторические данные по статистике не меняеются, а если и меняются, то это должна быть экстроординарная ситуации, наподобие аварии в ЦОД. Но на основе опыта получения данных от Facebook, я решила что всё равно буду перезаписывать семь последних дней (цифра семь появилась эмпирически).

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

Полный текст скрипта.
# импорт библиотекimport jsonfrom datetime import datetimefrom datetime import timedeltaimport requestsfrom six import string_typesfrom six.moves.urllib.parse import urlencodefrom six.moves.urllib.parse import urlunparseimport pandas as pdimport sqlalchemy# генерирует url на основе словаря args с аргументами запросаdef build_url(args: dict) -> str:    query_string = urlencode({k: v if isinstance(v, string_types) else json.dumps(v) for k, v in args.items()})    scheme = "https"    netloc = "ads.tiktok.com"    path = "/open_api/v1.1/reports/integrated/get/"    return urlunparse((scheme, netloc, path, "", query_string, ""))# отправляет запрос к TikTok Marketing API,# возвращает результат в виде преобразованного json в словарьdef get(args: dict, access_token: str) -> dict:    url = build_url(args)    headers = {        "Access-Token": access_token,    }    rsp = requests.get(url, headers=headers)    return rsp.json()# обновляет данные в базе за последние семь дней# (или, если указаны start_date и end_date, для периода [start_date, end_date])def update_tiktik_data(    # словарь с доступами к API TikTok    tiktok_conn: dict,    # словарь с доступами к базе данных    db_conn: dict,    # список id рекламных кабинетов    advertiser_ids: list,    # необязательное поле: начало периода    start_date:datetime=None,    # необязательное поле: окончание периода    end_date:datetime=None):    access_token = tiktok_conn['password']    start_date = datetime.now() - timedelta(7) if start_date is None else start_date    end_date = datetime.now() - timedelta(1) if end_date is None else end_date    START_DATE = datetime.strftime(start_date, '%Y-%m-%d')    END_DATE = datetime.strftime(end_date, '%Y-%m-%d')    SCHEMA = "schema"    TABLE = "table"    PAGE_SIZE = 1000    METRICS = [        "campaign_name", # название кампании        "adgroup_name", # название группы объявлений        "ad_name", # название объявления        "spend", # потраченные деньги (валюта задаётся в рекламном кабинете)        "impressions", # просмотры        "clicks", # клики        "reach", # количество уникальных пользователей, смотревших рекламу        "video_views_p25", # количество просмотров 25% видео        "video_views_p50", # количество просмотров 50% видео        "video_views_p75", # количество просмотров 75% видео        "video_views_p100", # количество просмотров 100% видео        "frequency" # среднее количество просмотра рекламы каждым пользователем    ]    result_dict = {} # словарь, в который будем записывать ответы    for advertiser_id in advertiser_ids:        page = 1 # сначала всегда получаем данные по первой странице        args = {            "metrics": METRICS, # список метрик, описанный выше            "data_level": "AUCTION_AD", # тип рекламы            "start_date": START_DATE, # начальный день запроса            "end_date": END_DATE, # конечный день запроса            "page_size": PAGE_SIZE, # размер страницы - количество объектов, которое возвращается за один запрос             "page": 1, # порядковый номер страницы (если данные не поместились в один запрос, аргумент инкрементируется)            "advertiser_id": advertiser_id, # один из ID из advertiser_ids, который мы получили при генерации access token            "report_type": "BASIC", # тип отчета            "dimensions": ["ad_id", "stat_time_day"] # аргументы группировки, вплоть до объявления и за целый день        }        result = get(args, access_token) # первый запрос        result_dict[advertiser_id] = result['data']['list'] # сохраняем ответ на запрос к первой странице        # пока текущая полученная страница page меньше,         # чем общее количество страниц в последнем ответе result        while page < result['data']['page_info']['total_page']:            # увеличиваем значение страницы на 1            page += 1            # обновляем значение текущей страницы в словаре аргументов запроса            args['page'] = page            # запрашиваем ответ по текущей странице page            result = get(args, access_token)            # накапливаем ответ            result_dict[advertiser_id] += result['data']['list']    # результирующий DataFrame, который будем записывать в базу    data_df = pd.DataFrame()    # для каждого рекламного аккаунта выполнить преобразование    for adv_id in advertiser_ids:        # получаем накопленные разультаты для аккаунта из словаря        adv_input_list = result_dict[adv_id]        # временный список        adv_result_list = []        # для каждого объекта        for adv_input_row in adv_input_list:            # берем словарь метрик            metrics = adv_input_row['metrics']            # насыщаем этот словарь словарём измерений            metrics.update(adv_input_row['dimensions'])            # добавляем полученный объект во временный список            adv_result_list.append(metrics)        # преобразуем временный словарь в DataFrame         result_df = pd.DataFrame(adv_result_list)        # добавляем колонку со значением id аккаунта        result_df['account'] = adv_id        # добавляем получившийся DataFrame в результирующий        data_df = data_df.append(            result_df,             ignore_index=True        )    #    # здесь пропущены некоторые манипуляции     # по преобразованию строк в числа    #        # создание подключения к базе    connection = sqlalchemy.create_engine(        '{db_type}://{user}:{pswd}@{host}:{port}/{path}'.format(            db_type=db_conn['db_type'],             user=db_conn['user'],             pswd=db_conn['password'],            host=db_conn['host'],            port=db_conn['port'],            path=db_conn['path']         )    )    # удаление последних семи дней из базы    with connection.connect() as conn:        conn.execute(f"""delete from {SCHEMA}.{TABLE}         where date >= '{START_DATE}' and date <= '{END_DATE}'""")    # запись данных из результирующего DataFrame в базу    data_df.to_sql(        schema=SCHEMA,         name=TABLE,         con=connection,        if_exists = 'append',        index = False    )

Миссия выполнена!

Подведем итоги

Итого, на всевышеописанные действия было потрачено менее одного рабочего дня (не считая времени, которое приложение было на проверке). Надеюсь, мне удалось показать, что уровень вхождения в API TikTok достаточно низкий, и для настройки автоматического сбора данных не нужно обязательно привлекать разработчика или блуждать по лабиринтам документации и запутанной логики.

К слову о лабиринтах, в Facebook тот же самый один рабочий день уходит на то, чтобы создать аккаунт разработчика, протыкать все галочки о политике конфидециальности и условий использования, создать приложение, настроить его и т.д. И в итоге к концу дня у тебя не работающий ETL по сбору данных, а очередной Permission Denied и распухшая голова, в которой крутится только одна мысль "что я делаю не так".

Конечно, сравнивать Facebook и TikTok не очень правильно: второй ещё относительно молод и ему еще только предстоит быть обвешанным хитрыми условиями, запретами и всеми возможными сложностями. Но сейчас всего этого пока нет, так что пользоваться TikTok Marketing API крайне удобно. Надеюсь, моя статья вам немного в этом поможет.

Полезные ссылки

Подробнее..

Как сохранить социальное доказательство при настройке новых объявлений в Facebook Adsс помощью Post ID?

04.04.2021 14:14:58 | Автор: admin

На сегодняшний день Facebook Ads это самый эффективный инструмент для привлечения потенциальных клиентов и генерации продаж. Это, в свою очередь, приводит к росту конкуренции на рекламной площадке, а также к росту стоимости размещения объявления. Теперь чтобы показать рекламное объявление своей целевой аудитории и получить переход на сайт, приходится платить больше.

Отличным способом повысить эффективность рекламной кампании является социальное доказательство или social proof. О том, что это такое, и как использовать его для улучшения показателей рекламных кампаний в Facebook, расскажем в данной статье.

Социальное доказательство что доказывает и кому?

Social Proof (социальное доказательство) это психологическое явление, заключающееся в том, что люди при принятии каких-либо решений руководствуются действиями других, предполагая, что это правильно. Социальное доказательство может проявляться в мнении, поведении, оценках других людей, на которые мы склонны опираться в принятии решений.Если говорить конкретно про Facebook, то СД являются просмотры, лайки, комментарии, репосты.

Зачастую признание другими людьми побуждает покупать сильнее, чем конкретные аргументы и рациональная выгода. Именно поэтому Social proof является распространенным инструментом, который активно используют маркетологи и продавцы.

В действительности на финальное решение клиента о покупке влияет множество факторов: доверие к магазину / бренду, простота навигации на сайте, товары (их актуальность, качество и wow-фактор), а также ряд психологических аспектов, среди которых немаловажную роль играет social proof.

Креативные возможности, связанные социальным доказательством, позволяют значительно повлиять на увеличение конверсии сайта, а также повысить эффективность рекламы в Facebook (и других рекламных площадках).

Далее мы расскажем, как добиться увеличения кликабельности рекламных объявлений в Facebook, благодаря использованию инструмента социального доказательства.

Почему социальное доказательство важно для Facebook?

В прошлом году Facebook пересмотрел показатели измерения эффективности рекламной кампании. Теперь релевантность рекламного объявления определяется тремя показателями, среди которых значится коэффициент вовлеченности (Engagement Rate).

ОценкаEngagement Rateпомогает сравнить ожидаемый коэффициент вовлеченности вашей рекламы и других объявлений, которые таргетированы на ту же аудиторию. Ожидаемый коэффициент вовлеченности это вероятность того, что пользователь нажмет на объявление, раскроет его, отреагирует на него, оставит комментарий или поделится им.

Высокий показатель вовлеченности говорит о том, что ваше рекламное объявление пришлось по вкусу / интересам целевой аудитории, на которую была настроена реклама.

Facebook использует этот показатель наряду сконверсиейикачествомобъявления, чтобы убедиться в пользе рекламы для пользователя. Если все показатели в норме, то стоимость показа рекламы ЦА будет снижена. Социальное доказательство, в свою очередь, помогает поддерживать эти показатели на высоком уровне. Далее расскажем, как этого добиться.

Как сохранить социальное доказательство на всех рекламных объявлениях Facebook?

При создании рекламы в Facebook Ads Manager, платформа присваивает каждому объявлению уникальный идентификатор post ID.

Если вы решите продублировать одно из успешных объявлений, то ему будет присвоен новый идентификационный номер. Таким образом, все лайки, репосты, реакции (элементы социального доказательства) не будут перенесены на новое объявление.

Хорошая новость заключается этом, что способ сохранить накопленные социальные доказательства при дублировании объявления все же есть, что можно сделать, связав новое объявление с исходным.

Стандартная структура рекламной кампании с несколькими группами объявлений выглядит следующим образом:

В одной кампании у вас есть несколько групп объявлений. В каждой группе объявлений как минимум одно объявление (с уникальным идентификатором). Не смотря на то, что объявление может быть абсолютно одинаковым во всех группах, для каждого адсета в ленте Facebook создается отдельный пост.

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

А что если мы скажем, что вы можете сохранить все социальные доказательства в виде реакций при запуске новых групп объявлений?

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

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

4 шага для сохранения накопленной статистики объявления

Стоит отметить, что данный метод применим только для новостной ленты Facebook и Instagram, где и вовлеченность можно увидеть в форме реакций: лайки, репосты, комментарии.

Итак, переходим непосредственно к механике. Откройте свой Facebook Ads Manager и следуйте простым указаниям:

Шаг 1: Выбираем объявление

Вам необходимо заранее найти объявление с наибольшим количеством показов и самым высоким CTR, которое вы хотите использовать повторно. Выберите объявление, на которое вы хотите направить все рекламные объявления и нажмитеEdit.

Шаг 2: Получаем ID объявления


В разделеAd Previewнажмите кнопкуShare Preview, затем Facebook Post with Comments.(Есливы размещаете объявление в Instagram, то нажмитеInstagram Post with Comments).

После загрузки объявления в новой вкладке вы получите URL-адрес. Выделите и скопируйтевторую часть цифр после /posts/.

При работе с объявлением в Instagram, у вас будет всего одна последовательность цифр, которую нужно будет также выделить и скопировать.

Шаг 3: Применяем ID объявления

На данном этапе вам нужно либо создать новую группу объявлений или скопировать уже существующую (что быстрее). Измените в них необходимые параметры (возрастной диапазон, страну, пол, интересы и т. д.) и переходите на уровень рекламных объявлений.

НажмитеEdit, а затем вместо Create Ad нажмите наUse Existing Post.

НажмитеEnter Post IDи вставьте ID объявления из Шага 2.

НажмитеSubmitи необходимое вам объявление загрузится в новую группу объявлений.

Шаг 4: Дублируем группы


Теперь дублируем новую группу с нужным нам объявлением и меняем разные настройки таргетинга при необходимости. Таким образом вы быстро создадите несколько групп с одним и тем же объявлением (с одним и тем же Post ID). Если вы сделали все верно, то вы увидите то самое объявление с уже накопленными показами и реакциями.

Используйте копирование Post ID для сохранения вовлеченности объявлений

Как вы поняли, сохранение социальных доказательств имеет высокое значение при тестировании одного объявления в разных группах и при масштабировании рекламных кампаний в Facebook. Обязательно попробуйте использовать описанный выше метод, и вы точно заметите, как показатели кампаний начнут постепенно улучшаться.

И еще кое-что...

Мы новенькие на Хабр, но у нас уже достаточно внушительный опыт в сфере eCommerce, которым мы с удовольствием готовы делиться. Наша команда действительно старается публиковать самые интересные и актуальные материалы , которые помогут вам быть в курсе текущих трендов и новостей в сфере eCommerce. Мы всегда рады новым читателям и с радостью продолжим делиться своими наблюдениями и наработками. Если статья была полезна, то мы будем благодарны, если вы поддержите наш канал комментарием.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru