agrs-sequelize-sdk 1.4.27 → 1.4.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/models/AdAccount.js +4 -0
- package/models/SingularChannel.js +31 -0
- package/package.json +1 -1
- package/tarzo-skalio-integration-docs.md +691 -0
package/models/AdAccount.js
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module.exports = (sequelize, DataTypes) => {
|
|
2
|
+
const SingularChannel = sequelize.define(
|
|
3
|
+
"SingularChannel",
|
|
4
|
+
{
|
|
5
|
+
channelId: {
|
|
6
|
+
type: DataTypes.STRING,
|
|
7
|
+
allowNull: false,
|
|
8
|
+
unique: true,
|
|
9
|
+
},
|
|
10
|
+
status: {
|
|
11
|
+
type: DataTypes.STRING,
|
|
12
|
+
allowNull: false,
|
|
13
|
+
defaultValue: "free",
|
|
14
|
+
validate: {
|
|
15
|
+
isIn: [["free", "used", "archived"]],
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
connectedCampaigns: {
|
|
19
|
+
type: DataTypes.JSONB,
|
|
20
|
+
allowNull: false,
|
|
21
|
+
defaultValue: [],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
tableName: "singular_rsoc_channels",
|
|
26
|
+
timestamps: true,
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
return SingularChannel;
|
|
31
|
+
};
|
package/package.json
CHANGED
|
@@ -0,0 +1,691 @@
|
|
|
1
|
+
# Tarzo ↔ Skalio Integration — Full Technical Documentation
|
|
2
|
+
|
|
3
|
+
## 🎯 Goal & Introduction
|
|
4
|
+
|
|
5
|
+
The goal of this task is to integrate **Tarzo** (platform.tarzo.io) as a new feed provider inside our **Skalio** dashboard, allowing us to launch Facebook campaigns directly from Skalio into Tarzo without using any official API (since Tarzo does not have one). Instead, we reverse-engineered Tarzo's internal API endpoints and authentication mechanism to operate as a normal logged-in user.
|
|
6
|
+
|
|
7
|
+
**What we want to achieve:**
|
|
8
|
+
1. **Campaign Creation** — Create Tarzo campaigns from Skalio the same way we do for other feed providers (Predicto, Mine, Compado, etc.), using the same Skalio form, naming conventions, and presets.
|
|
9
|
+
2. **Policy Center Sync** — Fetch policy review statuses (approved, in_review, pending, rejected reasons, notes) from Tarzo and reflect them in Skalio's Campaign Logs page.
|
|
10
|
+
3. **Performance Reporting** — Fetch revenue, ad clicks, conversions, and other feed-provider metrics from Tarzo by campaign ID, and merge them with the spend data we already pull from Facebook — exactly as we do for other RSOC feeds.
|
|
11
|
+
4. **Ad Account & Page Sync** — Pull the list of Tarzo ad accounts and Facebook pages into Skalio so they are selectable when creating a Tarzo campaign.
|
|
12
|
+
|
|
13
|
+
**Technical approach:** All communication is server-to-server. The Tarzo user's JWT token (extracted from localStorage on login) is stored securely on our backend. Every API call to Tarzo uses this token in the `Authorization` header. The token auto-refreshes on every response. No browser scraping is needed — all endpoints are standard JSON REST calls.
|
|
14
|
+
|
|
15
|
+
> **Important:** When making requests to Tarzo's system, do not reference our system name, do not mention "API integration", and behave exactly as a regular logged-in Tarzo user would.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Table of Contents
|
|
20
|
+
1. Architecture Overview
|
|
21
|
+
2. Tarzo Authentication
|
|
22
|
+
3. Tarzo API Reference — Campaign Creation
|
|
23
|
+
4. Tarzo API Reference — Policy Center
|
|
24
|
+
5. Tarzo API Reference — Performance / Reporting
|
|
25
|
+
6. Skalio System Overview
|
|
26
|
+
7. Skalio Internal API Reference
|
|
27
|
+
8. Field Mapping: Skalio → Tarzo
|
|
28
|
+
9. Campaign Naming Convention Mapping
|
|
29
|
+
10. New Skalio Feed Provider Entry ("Tarzo - RSOC")
|
|
30
|
+
11. Performance Data Fetch Strategy
|
|
31
|
+
12. Policy Center Integration Strategy
|
|
32
|
+
13. Ad Accounts & Facebook Pages Sync
|
|
33
|
+
14. Implementation Checklist
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 1. Architecture Overview
|
|
38
|
+
|
|
39
|
+
The integration works as follows: Skalio acts as the orchestrator. When a user creates a campaign in Skalio with "Tarzo - RSOC" selected as the feed provider, Skalio's backend must:
|
|
40
|
+
|
|
41
|
+
1. Use the Tarzo user's JWT token (stored in a secure backend config, not exposed to the frontend) to authenticate against Tarzo's internal API at `https://prod.tarzo.click/api/v1`
|
|
42
|
+
2. Pre-check channel availability via `GET /api/v1/channel-management/available`
|
|
43
|
+
3. POST a campaign payload to `POST /api/v1/facebook/creator/campaign/create`
|
|
44
|
+
4. Store the returned Tarzo campaign ID mapped to the Skalio campaign ID
|
|
45
|
+
5. Periodically sync policy status via `GET /api/v1/compliance/feed`
|
|
46
|
+
6. Periodically sync performance data via `GET /api/v1/facebook/hometalk/campaigns/report/campaign?campaignId=...`
|
|
47
|
+
|
|
48
|
+
No browser-side scraping is needed. All communication is server-to-server using the stored JWT token.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 2. Tarzo Authentication
|
|
53
|
+
|
|
54
|
+
**Token source:** The JWT is stored in Tarzo's browser localStorage under the key "authorization". For your integration, a Tarzo account must be set up as a service account, and the token should be extracted once (at login time) and stored securely on your backend. The token auto-refreshes: every response from Tarzo's API includes a refreshed authorization header — your backend must update the stored token on every response.
|
|
55
|
+
|
|
56
|
+
**How to authenticate every request:**
|
|
57
|
+
```
|
|
58
|
+
Authorization: <jwt_token>
|
|
59
|
+
Content-Type: application/json
|
|
60
|
+
Accept: application/json
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**All requests go to:** `https://prod.tarzo.click/api/v1/<endpoint>`
|
|
64
|
+
|
|
65
|
+
**Session validation:** `GET /api/v1/auth/iam` — call this to validate the token and get user info (firstName, id). These are used in campaign naming.
|
|
66
|
+
|
|
67
|
+
**Token refresh logic:**
|
|
68
|
+
- On each response, check if an `authorization` header is returned
|
|
69
|
+
- If yes, update the stored token with the new value
|
|
70
|
+
- If a `deauthorization` header is returned, the session has expired — re-login required
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 3. Tarzo API Reference — Campaign Creation
|
|
75
|
+
|
|
76
|
+
### Pre-flight Checks
|
|
77
|
+
|
|
78
|
+
**Check available Tarzo channels:**
|
|
79
|
+
```
|
|
80
|
+
GET /api/v1/channel-management/available?revenueSource=hometalk
|
|
81
|
+
GET /api/v1/channel-management/available?revenueSource=hometalk&integrationId=<integration_id>
|
|
82
|
+
```
|
|
83
|
+
Returns remaining channel count. Abort if zero.
|
|
84
|
+
|
|
85
|
+
**Get ad accounts:**
|
|
86
|
+
```
|
|
87
|
+
GET /api/v1/facebook/accounts?revenueSource=hometalk
|
|
88
|
+
```
|
|
89
|
+
Returns the list of ad account objects. Each has an id and a display code (e.g. "D-1", "R-1920").
|
|
90
|
+
|
|
91
|
+
**Get integrations:**
|
|
92
|
+
```
|
|
93
|
+
GET /api/v1/integration-management?revenueSource=hometalk&enabled=true&network=facebook
|
|
94
|
+
```
|
|
95
|
+
Returns integration objects including integration ID (needed for domain filtering and the campaign payload).
|
|
96
|
+
|
|
97
|
+
**Get domains:**
|
|
98
|
+
```
|
|
99
|
+
GET /api/v1/domain-management?revenueSource=hometalk&network=facebook
|
|
100
|
+
GET /api/v1/domain-management?revenueSource=hometalk&integrationId=<id>
|
|
101
|
+
```
|
|
102
|
+
Returns available Tarzo domains (e.g. https://www.upgradedhome.com/dcg).
|
|
103
|
+
|
|
104
|
+
**Get topics / offers:**
|
|
105
|
+
```
|
|
106
|
+
GET /api/v1/backoffice/offers
|
|
107
|
+
```
|
|
108
|
+
Returns all topics/verticals (e.g. "internet-providers", "roof-replacement").
|
|
109
|
+
|
|
110
|
+
### Initialize Article (Hometalk)
|
|
111
|
+
|
|
112
|
+
This must be done before campaign creation. It reserves a Tarzo channel and returns an article ID.
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
POST /api/v1/hometalk/assets/initialize-article
|
|
116
|
+
Content-Type: application/json
|
|
117
|
+
|
|
118
|
+
{
|
|
119
|
+
"offer": "internet-providers",
|
|
120
|
+
"domain": "https://www.upgradedhome.com/dcg",
|
|
121
|
+
"language": "en",
|
|
122
|
+
"keyword": "<main keyword, max 80 chars, English only>",
|
|
123
|
+
"articleContent": "<optional comma-separated extra keywords>",
|
|
124
|
+
"terms": []
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
Returns: An article/channel ID used in the campaign creation URL.
|
|
128
|
+
|
|
129
|
+
### Create Campaign
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
POST /api/v1/facebook/creator/campaign/create/<articleId>
|
|
133
|
+
Content-Type: application/json
|
|
134
|
+
|
|
135
|
+
{
|
|
136
|
+
"campaigns": [
|
|
137
|
+
{
|
|
138
|
+
"campaign": {
|
|
139
|
+
"name": "ww-en-fb-tz-tsuf-147-internet-providers-464-[5G Internet Guide]-488",
|
|
140
|
+
"freeText": "",
|
|
141
|
+
"accountId": "act_1234567890",
|
|
142
|
+
"objective": "OUTCOME_SALES",
|
|
143
|
+
"campaignType": "website",
|
|
144
|
+
"specialAdCategories": [],
|
|
145
|
+
"budget": 5,
|
|
146
|
+
"budgetType": "daily",
|
|
147
|
+
"isAdvantagePlus": false
|
|
148
|
+
},
|
|
149
|
+
"adSets": [
|
|
150
|
+
{
|
|
151
|
+
"budget": 5,
|
|
152
|
+
"countries": [],
|
|
153
|
+
"regions": [],
|
|
154
|
+
"language": "en",
|
|
155
|
+
"device": "",
|
|
156
|
+
"platforms": ["facebook", "instagram"],
|
|
157
|
+
"placements": [],
|
|
158
|
+
"os": "",
|
|
159
|
+
"pixelId": "<facebook_pixel_id>",
|
|
160
|
+
"bidStrategy": "LOWEST_COST_WITHOUT_CAP",
|
|
161
|
+
"bidAmount": "",
|
|
162
|
+
"pixelEvent": "PURCHASE",
|
|
163
|
+
"optimizationGoal": "OFFSITE_CONVERSIONS",
|
|
164
|
+
"adType": "SINGLE",
|
|
165
|
+
"startTime": null,
|
|
166
|
+
"attributionSpec": "",
|
|
167
|
+
"ageTargeting": { "min": 18, "max": 65 },
|
|
168
|
+
"genders": [],
|
|
169
|
+
"ads": [
|
|
170
|
+
{
|
|
171
|
+
"status": "ACTIVE",
|
|
172
|
+
"targetUrl": "https://...",
|
|
173
|
+
"urlTag": "",
|
|
174
|
+
"displayUrl": "",
|
|
175
|
+
"pageId": "<facebook_page_id>",
|
|
176
|
+
"pageCredentials": false,
|
|
177
|
+
"primaryText": "...",
|
|
178
|
+
"headlineText": "...",
|
|
179
|
+
"description": "",
|
|
180
|
+
"cta": "LEARN_MORE",
|
|
181
|
+
"selectedCreatives": ["<creative_id>"],
|
|
182
|
+
"translationLanguage": ""
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
],
|
|
187
|
+
"hometalk": {
|
|
188
|
+
"offer": "internet-providers",
|
|
189
|
+
"keyword": "<main keyword>",
|
|
190
|
+
"articleContent": "",
|
|
191
|
+
"domain": "https://www.upgradedhome.com/dcg",
|
|
192
|
+
"language": "en",
|
|
193
|
+
"terms": []
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
]
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**If article was not pre-initialized:** Use `POST /api/v1/facebook/creator/campaign/create` (no trailing ID).
|
|
201
|
+
|
|
202
|
+
**Duplicate an existing campaign:**
|
|
203
|
+
```
|
|
204
|
+
POST /api/v1/facebook/creator/campaign/duplicate/<baseCampaignId>
|
|
205
|
+
Body: { "campaigns": [...] }
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Tarzo Campaign Field Reference
|
|
209
|
+
|
|
210
|
+
**Campaign-level fields:**
|
|
211
|
+
|
|
212
|
+
| Field | Type | Allowed Values |
|
|
213
|
+
|---|---|---|
|
|
214
|
+
| objective | enum | OUTCOME_SALES, OUTCOME_TRAFFIC, OUTCOME_LEADS, OUTCOME_ENGAGEMENT, OUTCOME_AWARENESS, OUTCOME_APP_PROMOTION |
|
|
215
|
+
| campaignType | enum | website, app, website-and-app, messaging-app, calls |
|
|
216
|
+
| specialAdCategories | array | [], ["HOUSING"], ["EMPLOYMENT"], ["FINANCIAL_PRODUCTS_SERVICES"] |
|
|
217
|
+
| budgetType | enum | daily, lifetime |
|
|
218
|
+
| budget | number | Any positive number |
|
|
219
|
+
| isAdvantagePlus | boolean | false (default) |
|
|
220
|
+
|
|
221
|
+
**Ad Set-level fields:**
|
|
222
|
+
|
|
223
|
+
| Field | Type | Allowed Values / Notes |
|
|
224
|
+
|---|---|---|
|
|
225
|
+
| bidStrategy | enum | LOWEST_COST_WITHOUT_CAP, LOWEST_COST_WITH_BID_CAP, COST_CAP, LOWEST_COST_WITH_MIN_ROAS |
|
|
226
|
+
| optimizationGoal | enum | OFFSITE_CONVERSIONS (default), LINK_CLICKS, IMPRESSIONS, LANDING_PAGE_VIEWS |
|
|
227
|
+
| platforms | array | facebook, instagram, messenger, audience_network |
|
|
228
|
+
| adType | enum | SINGLE, FLEXIBLE — NO Carousel support |
|
|
229
|
+
| countries | array | ISO country codes, or empty array for Worldwide |
|
|
230
|
+
| genders | array | ["male"], ["female"], or [] for all |
|
|
231
|
+
| ageTargeting | object | { "min": 18, "max": 65 } |
|
|
232
|
+
| device | string | "desktop", "mobile", or "" for all |
|
|
233
|
+
| os | string | OS filter string or empty |
|
|
234
|
+
| pixelEvent | enum | PURCHASE (default) |
|
|
235
|
+
|
|
236
|
+
**Ad-level fields:**
|
|
237
|
+
|
|
238
|
+
| Field | Type | Notes |
|
|
239
|
+
|---|---|---|
|
|
240
|
+
| cta | enum | LEARN_MORE, WATCH_MORE, WATCH_VIDEO, SHOP_NOW, SIGN_UP, GET_OFFER, APPLY_NOW, GET_QUOTE, SEE_MORE, BOOK_NOW, CONTACT_US, CALLS |
|
|
241
|
+
| headlineText | string | Min 10, max 100 chars |
|
|
242
|
+
| description | string | Optional, min 20 max 250 chars |
|
|
243
|
+
| selectedCreatives | array | Creative IDs from Tarzo's library |
|
|
244
|
+
|
|
245
|
+
**Special categories constraint:** Cannot use HOUSING, EMPLOYMENT, or FINANCIAL_PRODUCTS_SERVICES when targeting Worldwide (empty countries). Enforce this in Skalio before sending.
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## 4. Tarzo API Reference — Policy Center
|
|
250
|
+
|
|
251
|
+
### Fetch policy data (paginated)
|
|
252
|
+
```
|
|
253
|
+
GET /api/v1/compliance/feed
|
|
254
|
+
?revenueSource=hometalk
|
|
255
|
+
&network=facebook
|
|
256
|
+
&search=
|
|
257
|
+
&status=<allowed|in_review|pending|unknown>
|
|
258
|
+
&integrationId=
|
|
259
|
+
&sortBy=
|
|
260
|
+
&offset=0
|
|
261
|
+
&limit=25
|
|
262
|
+
&users[]=<userId>
|
|
263
|
+
&createdAt.from=<ISO date>
|
|
264
|
+
&createdAt.to=<ISO date>
|
|
265
|
+
&lastCheckedAt.from=<ISO date>
|
|
266
|
+
&lastCheckedAt.to=<ISO date>
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Get policy totals
|
|
270
|
+
```
|
|
271
|
+
GET /api/v1/compliance/feed/totals
|
|
272
|
+
?revenueSource=hometalk
|
|
273
|
+
&network=facebook
|
|
274
|
+
&search=
|
|
275
|
+
&status=
|
|
276
|
+
&integrationId=
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Export policy data (up to 25,000 rows)
|
|
280
|
+
```
|
|
281
|
+
POST /api/v1/compliance/feed/export
|
|
282
|
+
Body: same filters as the GET endpoint (JSON)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Policy record fields returned:
|
|
286
|
+
|
|
287
|
+
| Field | Notes |
|
|
288
|
+
|---|---|
|
|
289
|
+
| adId | Tarzo's internal Ad ID |
|
|
290
|
+
| adStatus | Active/Paused status |
|
|
291
|
+
| status | allowed, approved, manual-approved, in_review, pending, unknown |
|
|
292
|
+
| campaignId | Tarzo campaign ID |
|
|
293
|
+
| campaignName | Full Tarzo campaign name |
|
|
294
|
+
| adAccountId | Facebook Ad Account ID |
|
|
295
|
+
| reason | Policy rejection reason |
|
|
296
|
+
| notes | Additional notes from reviewer |
|
|
297
|
+
| adName | Name of the ad |
|
|
298
|
+
| headline | Ad headline |
|
|
299
|
+
| adsManagerLink | Link to Facebook Ads Manager |
|
|
300
|
+
| lastCheck | Timestamp of last policy check |
|
|
301
|
+
| createdAt | Record creation timestamp |
|
|
302
|
+
| user | Which Tarzo user created this ad |
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## 5. Tarzo API Reference — Performance / Reporting
|
|
307
|
+
|
|
308
|
+
All endpoints return: revenue, spend (cost), conversions, feedProviderConversions, feedProviderCpa, networkClicks, impressions, networkRpc, feedProviderSearches, netProfit, roi, roas, ctr, cpc, cpm, rpc, cr, facebookRpc, results.
|
|
309
|
+
|
|
310
|
+
### All campaigns dashboard list
|
|
311
|
+
```
|
|
312
|
+
GET /api/v1/facebook/hometalk/campaigns/report
|
|
313
|
+
?from=YYYY-MM-DD&to=YYYY-MM-DD&limit=25&offset=0&search=&sortBy=&status=&ruleHits=&lastActivity=
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Dashboard totals (all campaigns)
|
|
317
|
+
```
|
|
318
|
+
GET /api/v1/facebook/hometalk/campaigns/report/totals
|
|
319
|
+
?from=YYYY-MM-DD&to=YYYY-MM-DD&search=&status=&ruleHits=&lastActivity=&bidStrategy=
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Single campaign performance by day
|
|
323
|
+
```
|
|
324
|
+
GET /api/v1/facebook/hometalk/campaigns/report/campaign
|
|
325
|
+
?campaignId=<tarzo_campaign_id>&from=YYYY-MM-DD&to=YYYY-MM-DD
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Totals for a specific campaign
|
|
329
|
+
```
|
|
330
|
+
GET /api/v1/facebook/hometalk/campaigns/report/totals
|
|
331
|
+
?campaignId=<tarzo_campaign_id>&from=YYYY-MM-DD&to=YYYY-MM-DD
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Ad set performance
|
|
335
|
+
```
|
|
336
|
+
GET /api/v1/facebook/hometalk/adsets/report
|
|
337
|
+
?campaignIds[]=<tarzo_campaign_id>&from=YYYY-MM-DD&to=YYYY-MM-DD&search=
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Ad-level performance
|
|
341
|
+
```
|
|
342
|
+
GET /api/v1/facebook/hometalk/ads/report
|
|
343
|
+
?campaignIds[]=<tarzo_campaign_id>&from=YYYY-MM-DD&to=YYYY-MM-DD&search=
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### CSV export (max 25,000 rows)
|
|
347
|
+
```
|
|
348
|
+
POST /api/v1/facebook/{entityType}s/export
|
|
349
|
+
entityType: campaign | adset | ad
|
|
350
|
+
Body: filter params as JSON
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Get single campaign details
|
|
354
|
+
```
|
|
355
|
+
GET /api/v1/facebook/campaigns/campaign/<campaignId>
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## 6. Skalio System Overview
|
|
361
|
+
|
|
362
|
+
**Framework:** Next.js (React, Recoil state management, MUI components, Zod validation, Axios HTTP client)
|
|
363
|
+
**Base URL:** https://www.skalio.io
|
|
364
|
+
**Internal API base:** All frontend calls go to /api/... (Next.js API routes, server-side)
|
|
365
|
+
**Auth:** Cookie-based session (Next.js middleware)
|
|
366
|
+
|
|
367
|
+
### Navigation structure:
|
|
368
|
+
- Performance — main campaign performance table
|
|
369
|
+
- Keywords Performance — keyword-level performance
|
|
370
|
+
- Country Breakdown — geo performance
|
|
371
|
+
- Create > Campaigns — general campaign creator
|
|
372
|
+
- Create > Facebook Campaigns — main Facebook creator at /dashboard/facebook
|
|
373
|
+
- Create > Articles — article management
|
|
374
|
+
- Create > Campaign Creation Logs — same as /dashboard/campaign-logs
|
|
375
|
+
- File Manager — media/creative assets
|
|
376
|
+
- Rules Automation — automated rules engine
|
|
377
|
+
- Research — research tools
|
|
378
|
+
- Assets — asset management
|
|
379
|
+
- Generate — AI generation tools
|
|
380
|
+
- Tier2 Business Manager — multi-account management
|
|
381
|
+
|
|
382
|
+
### Campaign creation modes (3 tabs):
|
|
383
|
+
- **Use Existing** — re-use an existing campaign structure (adds Campaign Name search at top)
|
|
384
|
+
- **AI Campaign** — AI-assisted campaign creation
|
|
385
|
+
- **Create New** — manual creation (the primary flow)
|
|
386
|
+
|
|
387
|
+
### Create New form fields:
|
|
388
|
+
| Field | Notes |
|
|
389
|
+
|---|---|
|
|
390
|
+
| Platform | Facebook (fixed for this page) |
|
|
391
|
+
| Media Buyer | Buyer code (e.g. "tsuf", "mark") |
|
|
392
|
+
| Feed Provider | Dropdown from Feed table |
|
|
393
|
+
| Vertical | Topic/vertical slug |
|
|
394
|
+
| Country | Single or multi country, or empty for WW |
|
|
395
|
+
| Language | ISO language code |
|
|
396
|
+
| Notes | Free text, maps to freeText in campaign |
|
|
397
|
+
| Ad Title | Maps to headlineText in ad |
|
|
398
|
+
| Keywords | Main keyword + additional keywords |
|
|
399
|
+
| Campaign Name Preview | Auto-generated: agrs-{feed}-fb-tp-{country}-{language}-{vertical}-{ddmm} |
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## 7. Skalio Internal API Reference
|
|
404
|
+
|
|
405
|
+
### Campaign Management
|
|
406
|
+
| Endpoint | Method | Description |
|
|
407
|
+
|---|---|---|
|
|
408
|
+
| /api/facebook/campaign/create | POST | Create campaign record in Skalio DB |
|
|
409
|
+
| /api/facebook/campaign/read | GET | Read campaign by ID |
|
|
410
|
+
| /api/facebook/campaign/readBatchCampaign | GET | Read multiple campaigns |
|
|
411
|
+
| /api/facebook/campaign/readcampaignHirarchi | GET | Full hierarchy (campaign+adsets+ads) |
|
|
412
|
+
| /api/facebook/campaign/update | PUT | Update campaign |
|
|
413
|
+
| /api/facebook/campaign/delete | DELETE | Delete campaign |
|
|
414
|
+
| /api/facebook/campaign/duplicate | POST | Duplicate campaign |
|
|
415
|
+
| /api/facebook/campaign/publish | POST | Publish to Facebook |
|
|
416
|
+
| /api/facebook/campaign/restore | POST | Restore deleted campaign |
|
|
417
|
+
|
|
418
|
+
### Ad Set Management
|
|
419
|
+
| Endpoint | Method | Description |
|
|
420
|
+
|---|---|---|
|
|
421
|
+
| /api/facebook/adset/create | POST | Create ad set |
|
|
422
|
+
| /api/facebook/adset/read | GET | Read ad set |
|
|
423
|
+
| /api/facebook/adset/readAll | GET | Read all ad sets |
|
|
424
|
+
| /api/facebook/adset/readAllFromCampaignId | GET | Read by campaign ID |
|
|
425
|
+
| /api/facebook/adset/update | PUT | Update ad set |
|
|
426
|
+
| /api/facebook/adset/delete | DELETE | Delete ad set |
|
|
427
|
+
| /api/facebook/adset/duplicate | POST | Duplicate ad set |
|
|
428
|
+
| /api/facebook/adset/publish | POST | Publish to Facebook |
|
|
429
|
+
| /api/facebook/adset/restore | POST | Restore ad set |
|
|
430
|
+
|
|
431
|
+
### Ad Management
|
|
432
|
+
| Endpoint | Method | Description |
|
|
433
|
+
|---|---|---|
|
|
434
|
+
| /api/facebook/ad/create | POST | Create ad |
|
|
435
|
+
| /api/facebook/ad/read | GET | Read ad |
|
|
436
|
+
| /api/facebook/ad/update | PUT | Update ad |
|
|
437
|
+
| /api/facebook/ad/delete | DELETE | Delete ad |
|
|
438
|
+
| /api/facebook/ad/duplicate | POST | Duplicate ad |
|
|
439
|
+
| /api/facebook/ad/publish | POST | Publish to Facebook |
|
|
440
|
+
| /api/newFiles/uploadToFacebook | POST | Upload media to Facebook |
|
|
441
|
+
| /api/newFiles/getAdMedia | GET | Get media for single ad |
|
|
442
|
+
| /api/newFiles/getAdsMedia | GET | Get media for multiple ads |
|
|
443
|
+
|
|
444
|
+
### Feed Campaign Lifecycle
|
|
445
|
+
| Endpoint | Method | Description |
|
|
446
|
+
|---|---|---|
|
|
447
|
+
| /api/feedCampaign/publishDraftCampaign | POST | KEY: Publishes draft to feed provider. This is where Tarzo integration code goes. |
|
|
448
|
+
| /api/feedCampaign/duplicate | POST | Duplicate a feed campaign |
|
|
449
|
+
|
|
450
|
+
### Performance
|
|
451
|
+
| Endpoint | Method | Params |
|
|
452
|
+
|---|---|---|
|
|
453
|
+
| /api/performance/campaign/bydate | GET | page, rowsPerPage, sort, date_range, ad_account, campaign_name, ad_status |
|
|
454
|
+
| /api/performance/campaign/byid | GET | feed, buyer, daterange, filterCampaignByIds, created_times, filterByDate, sortByIds, sortByDate, pageByIds, rowsPerPageByIds, adAccount, campaignName, createdTime, adStatus, country, vertical, roi_range, cost_range, ctr_range, rpc_range, cpa_range |
|
|
455
|
+
| /api/performance/campaign/totals | GET | dates, ad_account, campaign_name, ad_status |
|
|
456
|
+
| /api/performance/campaign/draftbyid | GET | Performance for draft campaigns |
|
|
457
|
+
|
|
458
|
+
### Static / Reference Data
|
|
459
|
+
| Endpoint | Method | Description |
|
|
460
|
+
|---|---|---|
|
|
461
|
+
| /api/static/Feed/findAll | GET | All feed providers |
|
|
462
|
+
| /api/static/Feed/create | POST | Create new feed provider |
|
|
463
|
+
| /api/static/adAccount/findAll | GET | All ad accounts |
|
|
464
|
+
| /api/static/adAccount/create | POST | Create ad account |
|
|
465
|
+
| /api/static/adAccount/update | PUT | Update ad account |
|
|
466
|
+
| /api/static/adAccount/bulk-create | POST | Bulk create ad accounts |
|
|
467
|
+
| /api/static/Pages/findAll | GET | All Facebook pages |
|
|
468
|
+
| /api/static/Pages/create | POST | Create page |
|
|
469
|
+
| /api/static/Pages/update | PUT | Update page |
|
|
470
|
+
| /api/static/Pages/bulk-create | POST | Bulk create pages |
|
|
471
|
+
| /api/static/Buyers/findAll | GET | All media buyers |
|
|
472
|
+
| /api/static/channel/findAll | GET | All channels |
|
|
473
|
+
| /api/static/channel/create | POST | Create channel |
|
|
474
|
+
| /api/static/channel/update | PUT | Update channel |
|
|
475
|
+
| /api/static/channel/bulk-create | POST | Bulk create channels |
|
|
476
|
+
| /api/configuration/getAdConfiguration | GET | Ad-level config. Params: campaignIds, adSetId, adIds |
|
|
477
|
+
| /api/configuration/getAdsetsConfiguration | GET | Adset-level config. Params: campaignIds, adSetIds |
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
## 8. Field Mapping: Skalio → Tarzo
|
|
482
|
+
|
|
483
|
+
### Campaign Creation Form
|
|
484
|
+
|
|
485
|
+
| Skalio Field | Skalio Value Example | Tarzo Field | Tarzo Value |
|
|
486
|
+
|---|---|---|---|
|
|
487
|
+
| platform | "Facebook" | network | "facebook" |
|
|
488
|
+
| feed | "Tarzo - RSOC" | revenueSource | "hometalk" |
|
|
489
|
+
| buyer | "tsuf" | Used in campaign name | Name segment |
|
|
490
|
+
| vertical | "internet-providers" | hometalk.offer | "internet-providers" |
|
|
491
|
+
| country | ["us"] or [] for WW | adSets[].countries | ["US"] or [] |
|
|
492
|
+
| language | ["en"] | hometalk.language | "en" |
|
|
493
|
+
| notes | "test campaign" | campaign.freeText | "test campaign" |
|
|
494
|
+
| adTitle | "5G Internet Guide" | headlineText + in name | "[5G Internet Guide]" |
|
|
495
|
+
| keywords[0] | "5g internet providers" | hometalk.keyword | "5g internet providers" |
|
|
496
|
+
| keywords[1..n] | Additional keywords | hometalk.articleContent | Comma-separated string |
|
|
497
|
+
|
|
498
|
+
### Bid Strategy Mapping
|
|
499
|
+
|
|
500
|
+
| Skalio Preset Label | Tarzo bidStrategy value |
|
|
501
|
+
|---|---|
|
|
502
|
+
| "Lowest Cost" / "LC" | LOWEST_COST_WITHOUT_CAP |
|
|
503
|
+
| "Bid Cap" / "BC" | LOWEST_COST_WITH_BID_CAP |
|
|
504
|
+
| "Cost Cap" / "CC" | COST_CAP |
|
|
505
|
+
| "Target ROAS" / "TROAS" | LOWEST_COST_WITH_MIN_ROAS |
|
|
506
|
+
|
|
507
|
+
### Objective Mapping
|
|
508
|
+
|
|
509
|
+
| Skalio Objective | Tarzo objective |
|
|
510
|
+
|---|---|
|
|
511
|
+
| Sales | OUTCOME_SALES |
|
|
512
|
+
| Traffic | OUTCOME_TRAFFIC |
|
|
513
|
+
| Leads | OUTCOME_LEADS |
|
|
514
|
+
| Engagement | OUTCOME_ENGAGEMENT |
|
|
515
|
+
| Awareness | OUTCOME_AWARENESS |
|
|
516
|
+
| App Promotion | OUTCOME_APP_PROMOTION |
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
## 9. Campaign Naming Convention Mapping
|
|
521
|
+
|
|
522
|
+
### Skalio naming format:
|
|
523
|
+
```
|
|
524
|
+
agrs-{feed}-fb-{buyer}-{country}-{language}-{vertical}-{ddmm}
|
|
525
|
+
```
|
|
526
|
+
Example from live preview: agrs-{feed}-fb-tp-{country}-{language}-{vertical}-0604
|
|
527
|
+
|
|
528
|
+
Where:
|
|
529
|
+
- agrs = system prefix (always fixed)
|
|
530
|
+
- {feed} = feed provider code (propose "tz" for Tarzo)
|
|
531
|
+
- fb = platform
|
|
532
|
+
- {buyer} = media buyer short code (e.g. "tsuf")
|
|
533
|
+
- {country} = ISO code, "mix" (multi-country), or "ww" (worldwide)
|
|
534
|
+
- {language} = language code
|
|
535
|
+
- {vertical} = vertical slug
|
|
536
|
+
- {ddmm} = campaign creation date
|
|
537
|
+
|
|
538
|
+
### Tarzo naming format:
|
|
539
|
+
```
|
|
540
|
+
{country_prefix}-{language}-{platform}-{feed_code}-{buyer_code}-{account_last3}-{topic}-{channel_last3}-[{article_title}]-{user_last3}
|
|
541
|
+
```
|
|
542
|
+
Example: ww-en-fb-tz-tsuf-147-internet-providers-464-[5G Internet Guide]-488
|
|
543
|
+
|
|
544
|
+
Where:
|
|
545
|
+
- ww-en = worldwide + English (0 countries = "ww-en", 1 country = country code, 2+ = "mc-en")
|
|
546
|
+
- fb = facebook
|
|
547
|
+
- tz = Tarzo feed code (fixed)
|
|
548
|
+
- tsuf = buyer/account prefix
|
|
549
|
+
- 147 = last 3 digits of Facebook ad account ID
|
|
550
|
+
- internet-providers = topic slug
|
|
551
|
+
- 464 = last 3 digits of article/channel ID (returned from initialize-article)
|
|
552
|
+
- [5G Internet Guide] = article title in square brackets
|
|
553
|
+
- 488 = last 3 digits of the Tarzo user ID (from /auth/iam)
|
|
554
|
+
|
|
555
|
+
**Rule:** Use Tarzo's naming format in the campaign.name field sent to Tarzo. Store Skalio's own campaign name separately and link both via the Tarzo campaign ID.
|
|
556
|
+
|
|
557
|
+
---
|
|
558
|
+
|
|
559
|
+
## 10. New Skalio Feed Provider Entry
|
|
560
|
+
|
|
561
|
+
To add Tarzo as a feed provider in Skalio:
|
|
562
|
+
|
|
563
|
+
```
|
|
564
|
+
POST /api/static/Feed/create
|
|
565
|
+
Body:
|
|
566
|
+
{
|
|
567
|
+
"feedName": "Tarzo - RSOC",
|
|
568
|
+
"feedType": "rsoc",
|
|
569
|
+
"platform": "Facebook",
|
|
570
|
+
"feedCode": "tz",
|
|
571
|
+
"revenueSource": "hometalk",
|
|
572
|
+
"network": "facebook"
|
|
573
|
+
}
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
The Feed Provider dropdown is populated from GET /api/static/Feed/findAll — once the record is created, it appears automatically.
|
|
577
|
+
|
|
578
|
+
When Tarzo is selected, the publishDraftCampaign handler must detect feedType: "rsoc" + revenueSource: "hometalk" and route to Tarzo's API.
|
|
579
|
+
|
|
580
|
+
---
|
|
581
|
+
|
|
582
|
+
## 11. Performance Data Fetch Strategy
|
|
583
|
+
|
|
584
|
+
**Approach:** Skalio fetches cost/spend from Facebook (existing flow). Tarzo provides revenue and feed-provider metrics only.
|
|
585
|
+
|
|
586
|
+
**Recommended sync:** Every 3 hours per campaign, or on-demand.
|
|
587
|
+
|
|
588
|
+
**Fetch per campaign:**
|
|
589
|
+
```
|
|
590
|
+
GET /api/v1/facebook/hometalk/campaigns/report/campaign
|
|
591
|
+
?campaignId=<tarzo_id>&from=<date>&to=<date>
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
### Performance Column Mapping
|
|
595
|
+
|
|
596
|
+
| Skalio Column | Tarzo Field | Notes |
|
|
597
|
+
|---|---|---|
|
|
598
|
+
| Revenue | revenue | From Tarzo |
|
|
599
|
+
| Cost | — | From Facebook (existing flow) |
|
|
600
|
+
| Ad Clicks | networkClicks | Tarzo's "ad clicks" metric |
|
|
601
|
+
| Conversions | feedProviderConversions | Feed-level conversions |
|
|
602
|
+
| RPC | networkRpc | Feed provider RPC |
|
|
603
|
+
| CPA | feedProviderCpa | Feed-level CPA |
|
|
604
|
+
| TS RPC | networkRpc | Same field |
|
|
605
|
+
| TS CPA | feedProviderCpa | Same field |
|
|
606
|
+
| CTR % | ctr | From Tarzo |
|
|
607
|
+
| CPC | cpc | From Tarzo |
|
|
608
|
+
| CR % | cr | Conversion rate |
|
|
609
|
+
| Net Profit | revenue - cost | Calculated |
|
|
610
|
+
| ROI | (revenue - cost) / cost * 100 | Calculated |
|
|
611
|
+
|
|
612
|
+
---
|
|
613
|
+
|
|
614
|
+
## 12. Policy Center Integration Strategy
|
|
615
|
+
|
|
616
|
+
**Approach:** Daily sync job fetches policy data from Tarzo and stores in Skalio campaign_logs table, keyed by Tarzo adId and campaignId.
|
|
617
|
+
|
|
618
|
+
**Fetch:**
|
|
619
|
+
```
|
|
620
|
+
GET /api/v1/compliance/feed
|
|
621
|
+
?revenueSource=hometalk&network=facebook&offset=0&limit=100
|
|
622
|
+
(paginate until all records fetched)
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
### Mapping to Skalio Campaign Logs
|
|
626
|
+
|
|
627
|
+
| Skalio Column | Tarzo Policy Field |
|
|
628
|
+
|---|---|
|
|
629
|
+
| Campaign Name | campaignName |
|
|
630
|
+
| Status | adStatus (Active/Paused) |
|
|
631
|
+
| Policy Status | status (allowed, in_review, pending, etc.) |
|
|
632
|
+
| Account | adAccountId |
|
|
633
|
+
| Feed | "Tarzo - RSOC" (hardcoded) |
|
|
634
|
+
| Ad | adId |
|
|
635
|
+
| Campaign Details | reason + notes |
|
|
636
|
+
| User | user |
|
|
637
|
+
|
|
638
|
+
Match records to Skalio campaigns using the campaignId stored at creation time.
|
|
639
|
+
|
|
640
|
+
---
|
|
641
|
+
|
|
642
|
+
## 13. Ad Accounts & Facebook Pages Sync
|
|
643
|
+
|
|
644
|
+
**Fetch Tarzo ad accounts:**
|
|
645
|
+
```
|
|
646
|
+
GET /api/v1/facebook/accounts?revenueSource=hometalk
|
|
647
|
+
```
|
|
648
|
+
Returns accounts with id (act_XXXXXXX format) and display name (e.g. "D-1").
|
|
649
|
+
|
|
650
|
+
**Store in Skalio:**
|
|
651
|
+
```
|
|
652
|
+
POST /api/static/adAccount/bulk-create
|
|
653
|
+
Body: { accounts: [{accountId: "act_123...", name: "D-1", feedProvider: "tarzo"}, ...] }
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
**Facebook Pages:** Page IDs are standard Facebook page IDs. Use Skalio's existing page list (GET /api/static/Pages/findAll). When Tarzo is selected as feed provider, show the page selector — the same page IDs work in both systems.
|
|
657
|
+
|
|
658
|
+
---
|
|
659
|
+
|
|
660
|
+
## 14. Implementation Checklist
|
|
661
|
+
|
|
662
|
+
### Backend
|
|
663
|
+
|
|
664
|
+
- [ ] Create tarzo.service.ts with: base URL (https://prod.tarzo.click/api/v1), token management (read/refresh on every response), and all endpoint wrappers from sections 3–5
|
|
665
|
+
- [ ] Add Tarzo JWT token to secure env/secrets storage; implement auto-refresh logic on every response
|
|
666
|
+
- [ ] Create "Tarzo - RSOC" feed record via POST /api/static/Feed/create
|
|
667
|
+
- [ ] Extend /api/feedCampaign/publishDraftCampaign — add Tarzo branch: detect revenueSource "hometalk", call initialize-article first, then create campaign, save returned Tarzo campaign ID against Skalio campaign ID
|
|
668
|
+
- [ ] Sync Tarzo ad accounts via GET /api/v1/facebook/accounts?revenueSource=hometalk → store with feedProvider: "tarzo" tag
|
|
669
|
+
- [ ] Extend /api/performance/campaign/byid — when feed = "tarzo-rsoc", fetch revenue metrics from Tarzo and merge with Facebook cost data
|
|
670
|
+
- [ ] Create policy sync cron job: call GET /api/v1/compliance/feed paginated → write to campaign_logs table
|
|
671
|
+
- [ ] Fetch and cache Tarzo domain list (GET /api/v1/domain-management?revenueSource=hometalk)
|
|
672
|
+
- [ ] Enforce validation: block HOUSING/EMPLOYMENT/FINANCIAL special categories when countries is empty (Worldwide)
|
|
673
|
+
- [ ] Add tarzo_campaign_id column to Skalio campaigns table
|
|
674
|
+
|
|
675
|
+
### Frontend
|
|
676
|
+
|
|
677
|
+
- [ ] "Tarzo - RSOC" will appear in Feed Provider dropdown automatically once DB record is created
|
|
678
|
+
- [ ] Show Tarzo-specific fields when Tarzo is selected: Domain selector, Article Content Query (max 80 chars, English), Terms (optional)
|
|
679
|
+
- [ ] Add Facebook Page selector when Tarzo is feed provider (required for ad creation)
|
|
680
|
+
- [ ] Show only Tarzo-tagged ad accounts when Tarzo is feed
|
|
681
|
+
- [ ] Show Tarzo channel availability count (from channel-management/available) before submit
|
|
682
|
+
- [ ] Update Campaign Name Preview to show Tarzo naming format alongside Skalio format
|
|
683
|
+
- [ ] Map Tarzo policy statuses in Campaign Logs: allowed = green, in_review = yellow, pending = orange, unknown = grey
|
|
684
|
+
- [ ] Add "Tarzo" filter option in Performance page Feed dropdown
|
|
685
|
+
|
|
686
|
+
### Still to confirm
|
|
687
|
+
|
|
688
|
+
1. **Creative upload to Tarzo** — The upload endpoint is likely POST /api/v1/creatives/library/save/v2 (multipart). Confirm exact field names by capturing a network request when clicking "Upload Media" in the Tarzo Creatives Library. Recommended approach: pre-upload creatives via Tarzo UI, store creative IDs in Skalio, expose a Tarzo Creative selector in the form.
|
|
689
|
+
2. **Tarzo service account** — Confirm which Tarzo account to use as the service account for the integration.
|
|
690
|
+
3. **tarzo_campaign_id storage** — Confirm schema changes to store Tarzo campaign ID linked to Skalio campaign ID.
|
|
691
|
+
4. **Keywords sync** — Planned for a later phase. Tarzo has keyword-level data available via the ads/report endpoint.
|