Написати Node.js демон для роботи з Instagram Graph API
11 500 UAHОпис
Створити NodeJS демон (cron job) який через Instagram Graph API збирає дані про аудиторію користувача, кількість читачів та зберігає цю інформацію в базі даних.
Вимоги:
- Дані про аудиторію користувача та кількість читачів мають зберігатись в окрмих колекціях в MongoDB: audience_analytics (regular collection) та followers_analytics (time series collection).
- Дані про аудиторію користувача мають збиратися один раз на добу для кожного окремого Інстаграм акаунта та оновлюватися в колекції audience_analytics
- Дані про кількість читачів мають збиратися щогодини і записуватися як новий запис в followers_analytics. Новий запис створюється щогодини для кожного Інстаграм акаунта користувача.
Технічні замітки
Facebook API
Щоб збирати дані через Facebook API необхідно отримати перманентний токен з такими дозволами: pages_show_list, instagram_basic, instagram_manage_insights, pages_read_engagement, pages_manage_metadata, public_profile.
Як отримати перманентний токен
00000000000000000 - замінити на Instagram user id
followers_analytics збирається через Facebook graph api endpoint:
v14.0/00000000000000000/insights?metric=follower_count&period=day&since=1662377839 (респонс містить кількість нових читачів щодня, починаючи з дати since).
Важливо: дані надаються із запізненням на 2 дні. Приклад - сьогодні 10 вересня. Дані про нових читачів будуть за 8 і раніше. 9 та 10 вересня будуть нульові показники і оновляться у відповіді тільки 11 та 12 вересня. Нам потрібно брати дані за останні 7 днів.
v14.0/00000000000000000?fields=followers_count (загальна кількість читачів на момент запиту)
audience_analytics збирається через Facebook graph api endpoint:
v14.0/00000000000000000/insights?metric=audience_city,audience_country,audience_gender_age,audience_locale,online_followers&period=lifetime
Структура колекції в MongoDB
Схема followers_analytics time series колекції
{
"_id": ObjectId, // generated automatically by mongo
"timestamp": ISODate, //
"metadata": {
"user_id": Number, // instagram user id
},
"followers_count": Number, // total number of followers for that day.
"followers_change": [ // Array of followers change for current and previous day
{
"value": Number,
"end_time": String
},
{
"value": Number,
"end_time": String
}
]
}followers_count - беремо з v14.0/00000000000000000?fields=followers_count API response.
followers_change - беремо з v14.0/00000000000000000/insights?metric=follower_count&period=day&since=0000000000 API response data[0].values Array.
Приклад відповіді від Фейсбук v14.0/00000000000000000/insights?metric=follower_count&period=day&since=1662377839
Facebook API response:
{
"data": [
{
"name": "follower_count",
"period": "day",
"values": [
{
"value": 5,
"end_time": "2022-09-06T07:00:00+0000"
},
{
"value": 5,
"end_time": "2022-09-07T07:00:00+0000"
},
{
"value": 5,
"end_time": "2022-09-08T07:00:00+0000"
},
{
"value": 6,
"end_time": "2022-09-09T07:00:00+0000"
},
{
"value": 4,
"end_time": "2022-09-10T07:00:00+0000"
},
{
"value": 0,
"end_time": "2022-09-11T07:00:00+0000"
},
{
"value": 0,
"end_time": "2022-09-12T07:00:00+0000"
}
],
"title": "Число подписчиков",
"description": "Общее количество уникальных аккаунтов, подписанных на этот профиль",
"id": "17841411749422633/insights/follower_count/day"
}
],
"paging": {
"previous": "https://graph.facebook.com/v14.0/17841411749422633/insights?access_token=EAAH2ZCdHE5IcBAMEXIhnA8W6Tmuo21NWY2MMMmOZBxsWvu5UpdZCDBcUettGUrZAtwiaSNRbZAvZBrBVHRLWukDgZC45QgWkZA0TcttFKgkbxLjGSW1ui2IxQdy94LPJiSylZC9dElHpAMSlt80UYe7NCrbFgjakRpJdGeyim4jViJZA4G4oCxOZAo7mmlgRZAIQNlSYlMCzqmTUZBGk7dOKi622HEtiP6ZCCK5UUZD&pretty=0&since=1661767386&metric=follower_count&period=day&until=1662377838",
"next": "https://graph.facebook.com/v14.0/17841411749422633/insights?access_token=EAAH2ZCdHE5IcBAMEXIhnA8W6Tmuo21NWY2MMMmOZBxsWvu5UpdZCDBcUettGUrZAtwiaSNRbZAvZBrBVHRLWukDgZC45QgWkZA0TcttFKgkbxLjGSW1ui2IxQdy94LPJiSylZC9dElHpAMSlt80UYe7NCrbFgjakRpJdGeyim4jViJZA4G4oCxOZAo7mmlgRZAIQNlSYlMCzqmTUZBGk7dOKi622HEtiP6ZCCK5UUZD&pretty=0&since=1662988292&metric=follower_count&period=day&until=1663598744"
}
}Схема audience_analytics
{
"_id": ObjectId, // generated automatically by mongo
"timestamp": ISODate, //
"metadata": {
"user_id": Number, // instagram user id
},
"audience_city": Array, // Array of values from API response
"audience_country": Array, // Array of values from API response
"audience_gender_age": Array, // Array of values from API response
"audience_locale": Array, // Array of values from API response
"online_followers": Array // Array of values from API response
}Приклад v14.0/00000000000000000/insights?metric=audience_city,audience_country,audience_gender_age,audience_locale,online_followers&period=lifetime
Facebook API response:
{
"data": [
{
"name": "audience_city",
"period": "lifetime",
"values": [
{
"value": {
"London, England": 3,
"Almere, Flevoland": 2,
"Odessa, Odessa Oblast": 7,
"Kharkiv, Kharkiv Oblast": 40,
"Barcelona, Cataluña": 4,
"Sumy, Sumy Oblast": 2,
"Amsterdam, Noord-Holland": 4,
"Kamianets-Podilskyi, Khmelnytskyi Oblast": 3,
"Alanya, Antalya Province": 2,
"Cherkasy, Cherkasy Oblast": 2,
"Lisbon, Lisbon District": 2,
"Berlin, Berlin": 18,
"Khmelnytskyi, Khmelnytskyi Oblast": 4,
"Valky, Kharkiv Oblast": 3,
"Lviv, Lviv Oblast": 23,
"Kyiv, Kyiv": 86,
"Prague, Prague": 3,
"Merefa, Kharkiv Oblast": 3,
"Moscow, Moscow": 2,
"Cologne, Nordrhein-Westfalen": 3,
"Uzhhorod, Zakarpattia Oblast": 5,
"Rivne, Rivne Oblast": 2,
"Vladivostok, Primorsky Krai": 2,
"Dnipro, Dnipropetrovsk Oblast": 6,
"Warsaw, Masovian Voivodeship": 13,
"Hoogeveen, Drenthe": 2,
"Stockholm, Stockholm County": 2,
"Dikanka, Poltava Oblast": 3,
"Chernivtsi, Chernivtsi Oblast": 6,
"Kraków, Lesser Poland Voivodeship": 2,
"Ivano-Frankivsk, Ivano-Frankivsk Oblast": 7,
"Hannoversch Münden, Niedersachsen": 2,
"Korotych, Kharkiv Oblast": 2,
"Ternopil, Ternopil Oblast": 5,
"Wroclaw, Lower Silesian Voivodeship": 8,
"Istanbul, Istanbul Province": 3,
"Toronto, Ontario": 2,
"Vinnytsia, Vinnytsia Oblast": 7,
"Frankfurt, Hessen": 2,
"Mukacheve, Zakarpattia Oblast": 2,
"Gdansk, Pomeranian Voivodeship": 2,
"Lyubotyn, Kharkiv Oblast": 2,
"Chortkiv, Ternopil Oblast": 2,
"Poltava, Poltava Oblast": 11,
"Okhtyrka, Sumy Oblast": 2
}
}
],
"title": "Audience City",
"description": "The cities of this profile's followers",
"id": "00000000000000000/insights/audience_city/lifetime"
},
{
"name": "audience_country",
"period": "lifetime",
"values": [
{
"value": {
"DE": 38,
"BE": 2,
"RU": 7,
"PT": 5,
"DK": 1,
"HR": 2,
"FR": 3,
"UA": 252,
"HU": 1,
"QA": 1,
"BR": 2,
"SE": 4,
"SK": 1,
"GB": 6,
"IE": 2,
"GE": 2,
"CA": 4,
"US": 4,
"EE": 1,
"IL": 2,
"AE": 1,
"CH": 3,
"MX": 1,
"CN": 1,
"IT": 2,
"ES": 8,
"AT": 1,
"CZ": 5,
"PH": 1,
"PK": 1,
"PL": 32,
"RO": 1,
"TR": 7,
"NL": 11,
"BA": 1
}
}
],
"title": "Audience Country",
"description": "The countries of this profile's followers",
"id": "00000000000000000/insights/audience_country/lifetime"
},
{
"name": "audience_gender_age",
"period": "lifetime",
"values": [
{
"value": {
"F.18-24": 15,
"F.25-34": 117,
"F.35-44": 15,
"F.45-54": 1,
"F.55-64": 3,
"F.65+": 2,
"M.18-24": 19,
"M.25-34": 135,
"M.35-44": 33,
"M.45-54": 2,
"M.55-64": 2,
"M.65+": 2,
"U.13-17": 1,
"U.18-24": 10,
"U.25-34": 55,
"U.35-44": 3,
"U.65+": 1
}
}
],
"title": "Gender and Age",
"description": "The gender and age distribution of this profile's followers",
"id": "00000000000000000/insights/audience_gender_age/lifetime"
},
{
"name": "audience_locale",
"period": "lifetime",
"values": [
{
"value": {
"it_IT": 1,
"es_LA": 1,
"ru_RU": 163,
"pl_PL": 7,
"da_DK": 1,
"tr_TR": 2,
"fr_FR": 3,
"de_DE": 6,
"ar_AR": 1,
"en_GB": 7,
"ru_UA": 1,
"en_US": 133,
"uk_UA": 84,
"zh_CN": 1,
"es_ES": 2,
"pt_PT": 1
}
}
],
"title": "Location",
"description": "The locales by country codes of this profile's followers",
"id": "00000000000000000/insights/audience_locale/lifetime"
},
{
"name": "online_followers",
"period": "lifetime",
"values": [
{
"value": {
},
"end_time": "2022-08-31T07:00:00+0000"
}
],
"title": "Online Followers",
"description": "Total number of this profile's followers that were online during the specified period",
"id": "00000000000000000/insights/online_followers/lifetime"
}
]
}Архітектура
Analytics planner
Потрібно також зробити планер, який буде додавати Instagram id в чергу на оновлення аналітики користувачів, раз на добу або раз на годину в залежності від типу аналітики
Acceptance criteria:
- Використовується останній Yarn package manager.
- Використовується остання стабільна версія NodeJS.
- Raw MongoDB driver використовуєтьяс для з'єднання з MongoDB.
- Analytics daemon створюється як пакет всередені yarn workspace.
- Analytics Data (followers_analytics) зберігаєтьяс в MongoDB як time series collection https://www.mongodb.com/docs/manual/core/timeseries-collections/
- Analytics daemon збирає дані щогодини та використовує чергу щоб визначити які саме Інстаграм профілі потрібно оновити. Профілі додаються в чергу щогодини. Черга може бути поділена поміж декількох копій демона.
- Mongo Collection має використовуватися як черга (якщо можливо). Якщо це неможливо, використовувати Kafka фбо RabbitMq(краще Kafka).
Відгук замовника про співпрацю з Андрієм Цапенком
Написати Node.js демон для роботи з Instagram Graph APIВсе було швидко і якісно. Рекомендую. Дякую!
Відгук фрилансера про співпрацю з Константиним Роговенком
Написати Node.js демон для роботи з Instagram Graph APIДуже професійний замовник, було приємно співпрацювати. Одразу чітко поставлене ТЗ з усіма деталями, на додаткові питання швидко відповідав, роботу перевірив також швидко та одразу завершив проєкт, виплатив винагороду. Однозначно рекомендую до співпраці
-
3232 37 3 Добрий день, Константин!
Мене зацікавив ваш проєкт, маю всі необхідні компетенції для його виконання та реалізую його з урахуванням усіх вимог та з високою якістю коду.
У вас дуже докладне ТЗ, приємно, що одразу можна проаналізувати всі деталі, це рідкість. Але все ж є одна незрозуміла деталь, на яку також звернув увагу Роман — який механізм отримання нових Instagram ID в Analytics planner'а? Це має бути REST API?
Окрім цього всі деталі проєкту зрозумілі, чергу можна реалізувати в колекції Mongo, це не проблема. Я вже урахував деплой проєкту, але цей момент треба буде обговорити. Якщо це не потрібно, то ціна буде зменшена, або якщо є якісь додаткові деталі цього, вона може бути трохи збільшена.
В мене вже підготовлена таблиця з декомпозицією проєкту з оцінкою часу кожного пункту. Напишіть мені, та я вам її надішлю, щоб ви розуміли як сформувалася ціна за проєкт
Буду радий співпраці, пишіть та я реалізую все у кращому вигляді
-
1558 10 1 1 Привіт, займаюся Web розробкою понад 3 роки.
Можете бути впевнені, що роботу буде зроблено якісно.
Веб розробник
Резюме кваліфікацій
• більше 3 років досвіду в розробці Full-Stack на JavaScript.
• - Мови: HTML / CSS, JavaScript,
• -Платформи: Node.js,
• -Бібліотеки: React.js, Bootstrap,
… • -Frameworks: Angular 2, Express.js, LoopBack.
-Я дуже віддана і відповідальна людина.
• Ви можете бути впевнені, що ваша робота буде виконана вчасно та якісно.
Навички
Мови програмування / Технології
• JavaScript
• HTML/CSS
• TypeScript
• Node.js
• MongoDB
• MySQL
• Postgresql
• REST API
• Axios
• Express
• Socket.io
Інструменти розробки
• Git
• ESLint
• Webpack
• Bitbucket
• Стилізовані компоненти
• React.js
• Redux
• Redux-Saga
• Bootstrap
Загальні навички
• ООП
Інструменти керування
• Jira
• Slack
• Trello
Мови
• Англійська - вільно
• Українська - Рідна
• Російська – вільно
Якщо ціна не влаштовує, то можемо домовитись.
-
558 10 4 Добрий день, Констянтин, зацікавив ваш проект зв'язаний з аналітикою Instagram і Facebook!
Завдання зрозумів!
Маю декілька уточнень: як демон буде отримувати користувачів? Що ви маєте на увазі під тим, щоб поділити чергу на декілька копій демона?
Чи правильно Я розумію, що Ви кажете про отримування користувачів з файлу? І декілька демонів - це Ви маєте на увазі запущено декілька проектів?
Буду радий співпраці!
-
Добрий день, Костя. Чому ви повторно опублікували цей проект українською мовою? Які ваші очікування по ціні і тривалості виконання?
-
Актуальні фриланс-проєкти в категорії Javascript та Typescript
Верстка React/Tailwind компонента для друку бланка А4Потрібно поправити UI/UX дизайн та геометрію одного React-компонента (шаблон клінічної карти для друку в PDF) Весь функціонал, масиви даних та логіка вже написані й працюють — потрібна суто косметика, правильні відступи та позиціонування елементів за допомогою Tailwind CSS Стек… HTML та CSS верстання, Javascript та Typescript ∙ 4 години 59 хвилин тому ∙ 40 ставок |
Шукаю досвідченого Full Stack розробника для створення SaaS-сервісу для інтернет-магазинів.Ідея сервісу: Клієнт завантажує посилання на свій товарний фід (XML або CSV). Сервіс автоматично отримує товари, бере їхні фотографії та створює нові рекламні зображення за готовими шаблонами: ціна, знижка, логотип, акційні плашки тощо. Також у сервісі має бути простий редактор… Javascript та Typescript, Веб-програмування ∙ 1 день 2 години тому ∙ 74 ставки |
Розробка WebGL/Three.js сцени з генерацією та експортом 3D (снапшот) з анімованого шейдераОпис об'єкта:Проект являє собою дизайнерський стіл, виконаний у формі реалістичного, глибокого водовороту (центральна воронка, яка плавно переходить з широкої горизонтальної стільниці в тонку витончену ніжку). Суть задачі:Потрібен WebGL / Creative Coding розробник для створення… Javascript та Typescript, Веб-програмування ∙ 1 день 22 години тому ∙ 29 ставок |
Підтримка та розвиток сайту клінінгової компанії
906 UAH
Шукаю веб-розробника / вебмайстра для довгострокової підтримки та розвитку сайту клінінгової компанії. Сайт: https://donely.ca Про проєкт DoneLy Home Services — компанія з надання послуг прибирання в Канаді, яка активно розвивається та розширює географію роботи. Шукаю… Javascript та Typescript, Веб-програмування ∙ 4 дні тому ∙ 63 ставки |
Розробка сайту по ТЗ на FramerПотрібно зробити сайт по цим параметрам що в тз https://docs.google.com/document/d/1ODO2C9Krb4AaMiJz9wfbNzWlAyA2FwCCHL8r0biajUY/edit?usp=sharing Називайте реальний рейт на основі цього дизайну HTML та CSS верстання, Javascript та Typescript ∙ 5 днів 1 година тому ∙ 28 ставок |
