zernio-sdk 0.0.813 → 0.0.815
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.
- checksums.yaml +4 -4
- data/docs/AdCampaignsApi.md +2 -0
- data/docs/AdTargetingApi.md +3 -3
- data/docs/CreateStandaloneAdRequest.md +6 -0
- data/docs/GetInboxConversationMessages200ResponseMessagesInner.md +2 -2
- data/docs/SendInboxMessageRequest.md +1 -1
- data/docs/TargetingSpec.md +8 -2
- data/docs/UpdateAdRequestCreative.md +8 -2
- data/docs/WebhookEventsApi.md +1 -1
- data/docs/WebhookPayloadMessageMetadata.md +1 -1
- data/docs/WebhookPayloadMessageSentMetadata.md +1 -1
- data/lib/zernio-sdk/api/ad_campaigns_api.rb +3 -0
- data/lib/zernio-sdk/api/ad_targeting_api.rb +5 -5
- data/lib/zernio-sdk/api/webhook_events_api.rb +2 -2
- data/lib/zernio-sdk/models/create_standalone_ad_request.rb +37 -1
- data/lib/zernio-sdk/models/get_inbox_conversation_messages200_response_messages_inner.rb +2 -1
- data/lib/zernio-sdk/models/send_inbox_message_request.rb +1 -1
- data/lib/zernio-sdk/models/targeting_spec.rb +39 -3
- data/lib/zernio-sdk/models/update_ad_request_creative.rb +55 -6
- data/lib/zernio-sdk/models/webhook_payload_message_metadata.rb +1 -1
- data/lib/zernio-sdk/models/webhook_payload_message_sent_metadata.rb +1 -1
- data/lib/zernio-sdk/version.rb +1 -1
- data/openapi.yaml +128 -27
- data/spec/api/ad_campaigns_api_spec.rb +1 -0
- data/spec/api/ad_targeting_api_spec.rb +2 -2
- data/spec/models/create_standalone_ad_request_spec.rb +18 -0
- data/spec/models/targeting_spec_spec.rb +18 -0
- data/spec/models/update_ad_request_creative_spec.rb +18 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 58045d34896a5c91c25ccad3b21495bdcac380d942c06f216efe5028555edd7e
|
|
4
|
+
data.tar.gz: 0f1a451006b824316bccc20f8a21ffe85a3691438a0e65443268ea4228cbc956
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c088a3d77c2f4b957301c0d18e082c728b7cb2bcd15dd0f2269c9f57f04982859aedeb974fb1764920325ccca61c88dc2b78923644cb380159cbd54a981c9f3f
|
|
7
|
+
data.tar.gz: b6d34757c383d41e561828e96360903668c9fb1292a16e77636180872610606bf7b59cf7a6ded1f0d14a53e3a6847f14a807672823651114eb27eecfe5fb1b3a
|
data/docs/AdCampaignsApi.md
CHANGED
|
@@ -1368,6 +1368,7 @@ opts = {
|
|
|
1368
1368
|
page_id: 'page_id_example', # String | Meta only: Facebook Page ID. Returns only ads whose creative is backed by this Page (a Meta ad account serves ads for every Page in the Business Manager). Matches each ad's `creative.pageId`; ads with no page signal (rare IG-only creatives) never match. Mirrors the same filter on /v1/ads/campaigns and /v1/ads/tree.
|
|
1369
1369
|
profile_id: 'profile_id_example', # String | Profile ID
|
|
1370
1370
|
campaign_id: 'campaign_id_example', # String | Platform campaign ID (filter ads within a campaign)
|
|
1371
|
+
ad_set_id: 'ad_set_id_example', # String | Platform ad set ID (filter ads within an ad set, the /{adset_id}/ads read of an adset-centric dashboard).
|
|
1371
1372
|
platform_ad_id: 'platform_ad_id_example', # String | Meta ad ID. Returns the ad with this platform-side ad ID.
|
|
1372
1373
|
effective_object_story_id: 'effective_object_story_id_example', # String | Facebook `{pageId}_{postId}` of the post the ad's engagement lives on (Meta `effective_object_story_id`). Use to map a Business-Manager-visible post back to the Zernio ad.
|
|
1373
1374
|
effective_instagram_media_id: 'effective_instagram_media_id_example', # String | Instagram media ID of the boosted post (Meta `effective_instagram_media_id`). Use to map a Business-Manager-visible IG post back to the Zernio ad.
|
|
@@ -1416,6 +1417,7 @@ end
|
|
|
1416
1417
|
| **page_id** | **String** | Meta only: Facebook Page ID. Returns only ads whose creative is backed by this Page (a Meta ad account serves ads for every Page in the Business Manager). Matches each ad's `creative.pageId`; ads with no page signal (rare IG-only creatives) never match. Mirrors the same filter on /v1/ads/campaigns and /v1/ads/tree. | [optional] |
|
|
1417
1418
|
| **profile_id** | **String** | Profile ID | [optional] |
|
|
1418
1419
|
| **campaign_id** | **String** | Platform campaign ID (filter ads within a campaign) | [optional] |
|
|
1420
|
+
| **ad_set_id** | **String** | Platform ad set ID (filter ads within an ad set, the /{adset_id}/ads read of an adset-centric dashboard). | [optional] |
|
|
1419
1421
|
| **platform_ad_id** | **String** | Meta ad ID. Returns the ad with this platform-side ad ID. | [optional] |
|
|
1420
1422
|
| **effective_object_story_id** | **String** | Facebook `{pageId}_{postId}` of the post the ad's engagement lives on (Meta `effective_object_story_id`). Use to map a Business-Manager-visible post back to the Zernio ad. | [optional] |
|
|
1421
1423
|
| **effective_instagram_media_id** | **String** | Instagram media ID of the boosted post (Meta `effective_instagram_media_id`). Use to map a Business-Manager-visible IG post back to the Zernio ad. | [optional] |
|
data/docs/AdTargetingApi.md
CHANGED
|
@@ -295,7 +295,7 @@ end
|
|
|
295
295
|
|
|
296
296
|
Search targeting options
|
|
297
297
|
|
|
298
|
-
Resolve a human-readable query into the platform's opaque targeting ids used in the `TargetingSpec` (`countries`/`regions`/`cities`/`zips`/`metros` geo keys, and `interests`/`behaviors` entity ids) on `POST /v1/ads/create`, `POST /v1/ads/targeting/reach-estimate`, and `saved_targeting` audiences. The `dimension` param selects what is searched, `geo` (locations, further scoped by `geoType`), `interest`, `behavior`, or `
|
|
298
|
+
Resolve a human-readable query into the platform's opaque targeting ids used in the `TargetingSpec` (`countries`/`regions`/`cities`/`zips`/`metros` geo keys, and `interests`/`behaviors` entity ids) on `POST /v1/ads/create`, `POST /v1/ads/targeting/reach-estimate`, and `saved_targeting` audiences. The `dimension` param selects what is searched, `geo` (locations, further scoped by `geoType`), `interest`, `behavior`, `income`, or the Meta-only work demographics `workPosition`, `workEmployer` and `workIndustry` (their ids feed `TargetingSpec.workPositions`/`workEmployers`/`workIndustries`). Availability of each dimension varies by platform (e.g. behaviours are Meta/TikTok only). Work industries are a fixed ~30-entry Meta catalog with no server-side query, so `workIndustry` matching, ranking and `limit` happen in Zernio. Results are normalized across platforms into a single shape, so the same client code consumes Meta, TikTok, LinkedIn, X, Pinterest, and Google results. TikTok geo searches return every matching level in one list (`type` is `country`, `region`, `city`, `district`, or `metro` for DMA areas) — `geoType` is not applied. Results are scoped to the advertiser's targetable markets, and every id is usable in `regions`/`cities`/`metros` keys on `POST /v1/ads/create`. LinkedIn geo searches also return every matching level in one list, and neither `geoType` nor `countryCode` is applied: LinkedIn's typeahead only returns a name and a URN per result, with no level or country field to filter on. Every result has `type` set to `location`, and its id is a `urn:li:geo:*` URN usable as a `regions[].key` on `POST /v1/ads/create`, `POST /v1/ads/boost` and `POST /v1/ads/targeting/reach-estimate`. Google geo searches resolve against Google's geoTargetConstants and return every matching level in one list; `geoType` is not applied (Google's `target_type` is an open taxonomy that does not map one-to-one onto the `geoType` enum), so filter client-side on the returned `type` (`country`, `region`, `city`, `zip`, `metro`, or the lowercased Google target type for rarer levels). `countryCode` scopes the search to one country. Each id is Google's numeric criterion id, usable as a `regions`/`cities`/`zips`/`metros` `key` on `POST /v1/ads/create`. Google city radius is not supported (pass a `customLocations` lat/lng pin for a radius); country targeting also accepts plain ISO codes via `countries` with no search call. Pinterest resolves against three whole-catalog endpoints (interests, locations, regions) with no server-side query or pagination, so matching, ranking and the `limit` cutoff all happen in Zernio; the catalog is independent of any ad account and results never carry `audienceSize`. Names come back localized to the connected Pinterest account's language (there is no way to force a locale), so match against whatever language that account returns. `geoType` routes to a different catalog: `country` and `metro_area` read the locations catalog (`type` is `country` or `metro`); `region` reads the regions catalog (`type` is `region`, its id a `regions[].key` on `POST /v1/ads/create`); `all` and the default `city` merge both catalogs with honest per-entry `type`s, since Pinterest has no city-level catalog and `city` is an alias for `all`, not a literal city search. `zip`, `subcity`, `neighborhood`, `place` and `geo_market` return a 400: Pinterest exposes no postal-code catalog, pass postal codes directly as `targeting.zips: [{ key }]` on `POST /v1/ads/create`. For geo queries, `q` should contain only the locality name (e.g. `\"Amsterdam\"`, not `\"Amsterdam, NL\"`). Use `countryCode` to disambiguate.
|
|
299
299
|
|
|
300
300
|
### Examples
|
|
301
301
|
|
|
@@ -312,7 +312,7 @@ api_instance = Zernio::AdTargetingApi.new
|
|
|
312
312
|
account_id = 'account_id_example' # String | Social account ID (a connected account on the target ad platform).
|
|
313
313
|
q = 'q_example' # String | Search query. For geo, the locality name only (no region/country suffix).
|
|
314
314
|
opts = {
|
|
315
|
-
dimension: 'geo', # String | What to search. `geo` resolves locations (scope further with `geoType`), `interest`/`behavior` resolve audience entities, `income` resolves income-tier options. Defaults to `interest` for backward compatibility with the deprecated /v1/ads/interests alias.
|
|
315
|
+
dimension: 'geo', # String | What to search. `geo` resolves locations (scope further with `geoType`), `interest`/`behavior` resolve audience entities, `income` resolves income-tier options, `workPosition`/`workEmployer`/`workIndustry` resolve Meta work demographics. Defaults to `interest` for backward compatibility with the deprecated /v1/ads/interests alias.
|
|
316
316
|
geo_type: 'all', # String | Only used when `dimension=geo`. The kind of location to resolve. `all` searches every type in one relevance-ranked call. Defaults to `city`.
|
|
317
317
|
country_code: 'country_code_example', # String | ISO 3166-1 alpha-2 country code (e.g. NL) to scope a geo search.
|
|
318
318
|
limit: 56 # Integer | Maximum results to return.
|
|
@@ -351,7 +351,7 @@ end
|
|
|
351
351
|
| ---- | ---- | ----------- | ----- |
|
|
352
352
|
| **account_id** | **String** | Social account ID (a connected account on the target ad platform). | |
|
|
353
353
|
| **q** | **String** | Search query. For geo, the locality name only (no region/country suffix). | |
|
|
354
|
-
| **dimension** | **String** | What to search. `geo` resolves locations (scope further with `geoType`), `interest`/`behavior` resolve audience entities, `income` resolves income-tier options. Defaults to `interest` for backward compatibility with the deprecated /v1/ads/interests alias. | [optional][default to 'interest'] |
|
|
354
|
+
| **dimension** | **String** | What to search. `geo` resolves locations (scope further with `geoType`), `interest`/`behavior` resolve audience entities, `income` resolves income-tier options, `workPosition`/`workEmployer`/`workIndustry` resolve Meta work demographics. Defaults to `interest` for backward compatibility with the deprecated /v1/ads/interests alias. | [optional][default to 'interest'] |
|
|
355
355
|
| **geo_type** | **String** | Only used when `dimension=geo`. The kind of location to resolve. `all` searches every type in one relevance-ranked call. Defaults to `city`. | [optional][default to 'city'] |
|
|
356
356
|
| **country_code** | **String** | ISO 3166-1 alpha-2 country code (e.g. NL) to scope a geo search. | [optional] |
|
|
357
357
|
| **limit** | **Integer** | Maximum results to return. | [optional][default to 25] |
|
|
@@ -53,6 +53,9 @@
|
|
|
53
53
|
| **metros** | [**Array<BoostPostRequestTargetingRegionsInner>**](BoostPostRequestTargetingRegionsInner.md) | DMA / metro-area geo targeting (Meta and TikTok). `key` is the platform's metro ID from /v1/ads/targeting/search?dimension=geo&geoType=metro (TikTok metros appear as type `metro`, e.g. the New York DMA). | [optional] |
|
|
54
54
|
| **custom_locations** | [**Array<CreateStandaloneAdRequestCustomLocationsInner>**](CreateStandaloneAdRequestCustomLocationsInner.md) | Point-radius (lat/lng) geo targeting. Meta only (custom_locations). Rejected on platforms without radius support. | [optional] |
|
|
55
55
|
| **behaviors** | [**Array<CreateStandaloneAdRequestBehaviorsInner>**](CreateStandaloneAdRequestBehaviorsInner.md) | Behaviour entities from /v1/ads/targeting/search?dimension=behavior. Supported on Meta and TikTok. Each must include id. | [optional] |
|
|
56
|
+
| **work_positions** | [**Array<CreateStandaloneAdRequestBehaviorsInner>**](CreateStandaloneAdRequestBehaviorsInner.md) | Meta only. Job title entities from /v1/ads/targeting/search?dimension=workPosition. Each must include id. Rejected on other platforms (use LinkedIn's `jobTitles` there). | [optional] |
|
|
57
|
+
| **work_employers** | [**Array<CreateStandaloneAdRequestBehaviorsInner>**](CreateStandaloneAdRequestBehaviorsInner.md) | Meta only. Employer entities from /v1/ads/targeting/search?dimension=workEmployer. Each must include id. | [optional] |
|
|
58
|
+
| **work_industries** | [**Array<CreateStandaloneAdRequestBehaviorsInner>**](CreateStandaloneAdRequestBehaviorsInner.md) | Meta only. Work-industry entities from /v1/ads/targeting/search?dimension=workIndustry. Each must include id. Rejected on other platforms (use LinkedIn's `industries` there). | [optional] |
|
|
56
59
|
| **income_tier** | **String** | Normalized household-income tier. Meta and TikTok express all four; Google maps only `top_10`; rejected on LinkedIn, X, and Pinterest. On Meta, income targeting is incompatible with housing/employment/credit `specialAdCategories`. | [optional] |
|
|
57
60
|
| **languages** | **Array<String>** | Language codes restricting the audience by language. On Meta, ISO 639-1 codes (e.g. ['en'], ['de']); a bare code targets all regional variants (\"en\" = all English), or use a region-qualified code for a specific one (\"en_GB\", \"pt_BR\", \"zh_TW\"). Unknown codes are rejected. Other ad platforms use their own language-code systems. | [optional] |
|
|
58
61
|
| **placements** | [**CreateStandaloneAdRequestPlacements**](CreateStandaloneAdRequestPlacements.md) | | [optional] |
|
|
@@ -148,6 +151,9 @@ instance = Zernio::CreateStandaloneAdRequest.new(
|
|
|
148
151
|
metros: null,
|
|
149
152
|
custom_locations: null,
|
|
150
153
|
behaviors: null,
|
|
154
|
+
work_positions: null,
|
|
155
|
+
work_employers: null,
|
|
156
|
+
work_industries: null,
|
|
151
157
|
income_tier: null,
|
|
152
158
|
languages: null,
|
|
153
159
|
placements: null,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
| Name | Type | Description | Notes |
|
|
6
6
|
| ---- | ---- | ----------- | ----- |
|
|
7
|
-
| **id** | **String** | | [optional] |
|
|
7
|
+
| **id** | **String** | The platform's own message id: the `wamid` on WhatsApp, the `mid` on Instagram and Facebook Messenger. This is what `metadata.quotedMessageId` points at, the value to pass as `replyTo` on the platforms that support quote-replies, and the `{messageId}` segment of the attachment-resolve URL. Webhooks deliver the same value as `message.platformMessageId`; this response has no field by that name. | [optional] |
|
|
8
8
|
| **conversation_id** | **String** | | [optional] |
|
|
9
9
|
| **account_id** | **String** | | [optional] |
|
|
10
10
|
| **platform** | **String** | | [optional] |
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
| **sent_at** | **Time** | Original send time for outgoing messages (used for Messenger watermark queries). | [optional] |
|
|
31
31
|
| **delivery_error** | [**GetInboxConversationMessages200ResponseMessagesInnerDeliveryError**](GetInboxConversationMessages200ResponseMessagesInnerDeliveryError.md) | | [optional] |
|
|
32
32
|
| **reactions** | [**Array<GetInboxConversationMessages200ResponseMessagesInnerReactionsInner>**](GetInboxConversationMessages200ResponseMessagesInnerReactionsInner.md) | Emoji reactions on this message (WhatsApp / Telegram). At most one per party in a 1:1 thread. | [optional] |
|
|
33
|
-
| **metadata** | **Hash<String, Object>** | Platform-specific extras. Free-form, but commonly includes: `quotedMessageId` (
|
|
33
|
+
| **metadata** | **Hash<String, Object>** | Platform-specific extras. Free-form, but commonly includes: `quotedMessageId` (the `id` of the message this one replies to, delivered as `message.platformMessageId` on webhooks), `waInteractive` (a compact descriptor of WhatsApp interactive content sent: buttons / list / cta_url / flow / location_request), and for inbound interactive taps `interactiveType` / `interactiveId`. It can also carry `source` (`whatsapp_business_app` / `coexistence_history` on a WhatsApp Coexistence number, `bulk-api` on a POST /v1/whatsapp/bulk send), which is where the message reached us from rather than who produced it: read `sentVia` for that. | [optional] |
|
|
34
34
|
| **sent_via** | **String** | Which Zernio surface produced this outgoing message: `human` (an operator in the Zernio inbox), `api` (a call to this API), `broadcast`, `sequence`, `workflow`, `comment_automation`, or `bulk-api` (POST /v1/whatsapp/bulk). Same vocabulary as the `source` filter on the inbox analytics endpoints. Always present, and `null` whenever the lineage is unknown: every incoming message, any outgoing message sent from the platform's own app, and every message stored before this field shipped (2026-08). Existing messages are NOT backfilled, so treat `null` as \"unknown\", never as \"sent by a human\". | [optional] |
|
|
35
35
|
|
|
36
36
|
## Example
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
| **reply_markup** | [**SendInboxMessageRequestReplyMarkup**](SendInboxMessageRequestReplyMarkup.md) | | [optional] |
|
|
20
20
|
| **messaging_type** | **String** | Facebook messaging type. Required when using messageTag. | [optional] |
|
|
21
21
|
| **message_tag** | **String** | Facebook message tag for messaging outside 24h window. Requires messagingType MESSAGE_TAG. Instagram only supports HUMAN_AGENT. | [optional] |
|
|
22
|
-
| **reply_to** | **String** | Platform message ID to quote-reply to. For WhatsApp, pass the wamid; for Telegram, the Telegram message ID (
|
|
22
|
+
| **reply_to** | **String** | Platform message ID to quote-reply to. For WhatsApp, pass the wamid; for Telegram, the Telegram message ID (delivered as message.platformMessageId on webhooks, and as `id` on each entry of the list-messages endpoint). On Slack it threads the reply (thread_ts) instead of quoting. Silently ignored on platforms without send-side reply support, including Instagram and Facebook Messenger (Meta's Send API rejects reply_to on Instagram and does not expose it on Messenger). | [optional] |
|
|
23
23
|
| **location** | [**SendInboxMessageRequestLocation**](SendInboxMessageRequestLocation.md) | | [optional] |
|
|
24
24
|
| **contacts** | [**Array<SendInboxMessageRequestContactsInner>**](SendInboxMessageRequestContactsInner.md) | WhatsApp-only. Send one or more contact cards. | [optional] |
|
|
25
25
|
|
data/docs/TargetingSpec.md
CHANGED
|
@@ -18,12 +18,15 @@
|
|
|
18
18
|
| **languages** | **Array<String>** | Language codes restricting the audience by language. On Meta, ISO 639-1 codes (e.g. ['en']); a bare code targets all regional variants (\"en\" = all English), or use a region-qualified code (\"en_GB\", \"pt_BR\") for a specific one. Unknown codes are rejected. | [optional] |
|
|
19
19
|
| **interests** | [**Array<CreateStandaloneAdRequestBehaviorsInner>**](CreateStandaloneAdRequestBehaviorsInner.md) | Interest entities from /v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id. | [optional] |
|
|
20
20
|
| **behaviors** | [**Array<CreateStandaloneAdRequestBehaviorsInner>**](CreateStandaloneAdRequestBehaviorsInner.md) | Behaviour entities from /v1/ads/targeting/search?dimension=behavior. Supported on Meta and TikTok. | [optional] |
|
|
21
|
+
| **work_positions** | [**Array<CreateStandaloneAdRequestBehaviorsInner>**](CreateStandaloneAdRequestBehaviorsInner.md) | Meta only. Job title entities from /v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments. | [optional] |
|
|
22
|
+
| **work_employers** | [**Array<CreateStandaloneAdRequestBehaviorsInner>**](CreateStandaloneAdRequestBehaviorsInner.md) | Meta only. Employer entities from /v1/ads/targeting/search?dimension=workEmployer. | [optional] |
|
|
23
|
+
| **work_industries** | [**Array<CreateStandaloneAdRequestBehaviorsInner>**](CreateStandaloneAdRequestBehaviorsInner.md) | Meta only. Work-industry entities from /v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments. | [optional] |
|
|
21
24
|
| **industries** | **Array<String>** | LinkedIn B2B only. Industry URN id fragments. | [optional] |
|
|
22
25
|
| **company_sizes** | **Array<String>** | LinkedIn B2B only. | [optional] |
|
|
23
26
|
| **seniorities** | **Array<String>** | LinkedIn B2B only. | [optional] |
|
|
24
27
|
| **job_functions** | **Array<String>** | LinkedIn B2B only. | [optional] |
|
|
25
|
-
| **audience_include** | **Array<String>** | Platform audience IDs to include
|
|
26
|
-
| **audience_exclude** | **Array<String>** | Platform audience IDs to exclude. Not supported on
|
|
28
|
+
| **audience_include** | **Array<String>** | Platform audience IDs to include, as returned by GET /v1/ads/audiences (Meta custom audience ids, TikTok audience ids, Pinterest customer list ids, LinkedIn segment ids (bare, urn:li:adSegment or urn:li:dmpSegment forms accepted), Google user list ids, X custom audience ids). Not supported on OpenAI (400). | [optional] |
|
|
29
|
+
| **audience_exclude** | **Array<String>** | Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400). | [optional] |
|
|
27
30
|
|
|
28
31
|
## Example
|
|
29
32
|
|
|
@@ -45,6 +48,9 @@ instance = Zernio::TargetingSpec.new(
|
|
|
45
48
|
languages: null,
|
|
46
49
|
interests: null,
|
|
47
50
|
behaviors: null,
|
|
51
|
+
work_positions: null,
|
|
52
|
+
work_employers: null,
|
|
53
|
+
work_industries: null,
|
|
48
54
|
industries: null,
|
|
49
55
|
company_sizes: null,
|
|
50
56
|
seniorities: null,
|
|
@@ -4,12 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
| Name | Type | Description | Notes |
|
|
6
6
|
| ---- | ---- | ----------- | ----- |
|
|
7
|
-
| **headline** | **String** | Meta
|
|
7
|
+
| **headline** | **String** | Meta and LinkedIn (TikTok has no headline slot) | [optional] |
|
|
8
8
|
| **body** | **String** | | [optional] |
|
|
9
|
+
| **description** | **String** | Link description slot (Meta `link_data.description` / `video_data.link_description`, LinkedIn creative description). | [optional] |
|
|
9
10
|
| **call_to_action** | **String** | | [optional] |
|
|
10
11
|
| **link_url** | **String** | | [optional] |
|
|
11
12
|
| **image_url** | **String** | | [optional] |
|
|
12
13
|
| **video_url** | **String** | | [optional] |
|
|
14
|
+
| **video_id** | **String** | Meta only. Reuse an already-uploaded ad video (from POST /v1/ads/videos or GET /v1/ads/videos) instead of re-uploading via videoUrl. | [optional] |
|
|
15
|
+
| **existing_creative_id** | **String** | Meta only. Repoint the ad at an existing library creative (from GET /v1/ads/creatives); all other creative fields are ignored. | [optional] |
|
|
13
16
|
|
|
14
17
|
## Example
|
|
15
18
|
|
|
@@ -19,10 +22,13 @@ require 'zernio-sdk'
|
|
|
19
22
|
instance = Zernio::UpdateAdRequestCreative.new(
|
|
20
23
|
headline: null,
|
|
21
24
|
body: null,
|
|
25
|
+
description: null,
|
|
22
26
|
call_to_action: null,
|
|
23
27
|
link_url: null,
|
|
24
28
|
image_url: null,
|
|
25
|
-
video_url: null
|
|
29
|
+
video_url: null,
|
|
30
|
+
video_id: null,
|
|
31
|
+
existing_creative_id: null
|
|
26
32
|
)
|
|
27
33
|
```
|
|
28
34
|
|
data/docs/WebhookEventsApi.md
CHANGED
|
@@ -1219,7 +1219,7 @@ nil (empty response body)
|
|
|
1219
1219
|
|
|
1220
1220
|
Message sent event
|
|
1221
1221
|
|
|
1222
|
-
Fired when a message is sent via the API, or from the WhatsApp Business app on Coexistence numbers. Sends that carry platform-specific context deliver it under `metadata`, so a quote-reply arrives with `metadata.quotedMessageId` and mirroring CRMs can thread it without a lookup.
|
|
1222
|
+
Fired when a message is sent via the API, or from the WhatsApp Business app on Coexistence numbers. Sends that carry platform-specific context deliver it under `metadata`, so a quote-reply sent through the API arrives with `metadata.quotedMessageId` and mirroring CRMs can thread it without a lookup. Which surfaces actually carry that reference is documented on `WebhookPayloadMessageSent.metadata.quotedMessageId`; a quote-reply sent from the WhatsApp Business or Instagram app is not one of them.
|
|
1223
1223
|
|
|
1224
1224
|
### Examples
|
|
1225
1225
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
| Name | Type | Description | Notes |
|
|
6
6
|
| ---- | ---- | ----------- | ----- |
|
|
7
|
-
| **quoted_message_id** | **String** | platformMessageId of the message this one is a quote-reply to. WhatsApp (`context.id`), Instagram and Facebook Messenger (`reply_to.mid`).
|
|
7
|
+
| **quoted_message_id** | **String** | platformMessageId of the message this one is a quote-reply to. WhatsApp (`context.id`), Instagram and Facebook Messenger (`reply_to.mid`). On outgoing messages the same field appears on `message.sent`, but only on some surfaces: see WebhookPayloadMessageSent.metadata.quotedMessageId. | [optional] |
|
|
8
8
|
| **quick_reply_payload** | **String** | Payload from a quick reply tap (Facebook/Instagram Messenger). | [optional] |
|
|
9
9
|
| **postback_payload** | **String** | Payload from a postback button tap (Facebook/Instagram Messenger). | [optional] |
|
|
10
10
|
| **postback_title** | **String** | Title of the tapped postback button (Facebook/Instagram Messenger). | [optional] |
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
| Name | Type | Description | Notes |
|
|
6
6
|
| ---- | ---- | ----------- | ----- |
|
|
7
|
-
| **quoted_message_id** | **String** | platformMessageId of the message this send is a quote-reply to.
|
|
7
|
+
| **quoted_message_id** | **String** | `platformMessageId` of the message this send is a quote-reply to. Present when the reply was sent through Zernio with `replyTo` on the inbox send API (WhatsApp and Telegram). A WhatsApp API send fires its `message.sent` off the delivery status, and the quote reference is forwarded from the stored send there, so it arrives on the same `message.sent` as any other WhatsApp send. Not delivered on Instagram echoes. Zernio forwards `reply_to.mid` whenever Meta puts it on an echo, but on Instagram Meta does not send it, so a reply the operator quoted in the Instagram app arrives with no `quotedMessageId`. Facebook Messenger rides a separate subscription (`message_echoes`) and has not been measured, so treat it as unverified rather than supported. Absent on WhatsApp Coexistence echoes. Meta omits the quote context from `smb_message_echoes`, so a reply the operator sent from the WhatsApp Business app arrives with no `quotedMessageId` even though WhatsApp shows it as a quote-reply. Do not read the absence of this field as \"not a reply\". | [optional] |
|
|
8
8
|
| **thread_ts** | **String** | Slack only. Parent thread ts of the sent message. Pass it back as `replyTo` on the inbox send API to keep replying inside the thread. | [optional] |
|
|
9
9
|
|
|
10
10
|
## Example
|
|
@@ -1435,6 +1435,7 @@ module Zernio
|
|
|
1435
1435
|
# @option opts [String] :page_id Meta only: Facebook Page ID. Returns only ads whose creative is backed by this Page (a Meta ad account serves ads for every Page in the Business Manager). Matches each ad's `creative.pageId`; ads with no page signal (rare IG-only creatives) never match. Mirrors the same filter on /v1/ads/campaigns and /v1/ads/tree.
|
|
1436
1436
|
# @option opts [String] :profile_id Profile ID
|
|
1437
1437
|
# @option opts [String] :campaign_id Platform campaign ID (filter ads within a campaign)
|
|
1438
|
+
# @option opts [String] :ad_set_id Platform ad set ID (filter ads within an ad set, the /{adset_id}/ads read of an adset-centric dashboard).
|
|
1438
1439
|
# @option opts [String] :platform_ad_id Meta ad ID. Returns the ad with this platform-side ad ID.
|
|
1439
1440
|
# @option opts [String] :effective_object_story_id Facebook `{pageId}_{postId}` of the post the ad's engagement lives on (Meta `effective_object_story_id`). Use to map a Business-Manager-visible post back to the Zernio ad.
|
|
1440
1441
|
# @option opts [String] :effective_instagram_media_id Instagram media ID of the boosted post (Meta `effective_instagram_media_id`). Use to map a Business-Manager-visible IG post back to the Zernio ad.
|
|
@@ -1459,6 +1460,7 @@ module Zernio
|
|
|
1459
1460
|
# @option opts [String] :page_id Meta only: Facebook Page ID. Returns only ads whose creative is backed by this Page (a Meta ad account serves ads for every Page in the Business Manager). Matches each ad's `creative.pageId`; ads with no page signal (rare IG-only creatives) never match. Mirrors the same filter on /v1/ads/campaigns and /v1/ads/tree.
|
|
1460
1461
|
# @option opts [String] :profile_id Profile ID
|
|
1461
1462
|
# @option opts [String] :campaign_id Platform campaign ID (filter ads within a campaign)
|
|
1463
|
+
# @option opts [String] :ad_set_id Platform ad set ID (filter ads within an ad set, the /{adset_id}/ads read of an adset-centric dashboard).
|
|
1462
1464
|
# @option opts [String] :platform_ad_id Meta ad ID. Returns the ad with this platform-side ad ID.
|
|
1463
1465
|
# @option opts [String] :effective_object_story_id Facebook `{pageId}_{postId}` of the post the ad's engagement lives on (Meta `effective_object_story_id`). Use to map a Business-Manager-visible post back to the Zernio ad.
|
|
1464
1466
|
# @option opts [String] :effective_instagram_media_id Instagram media ID of the boosted post (Meta `effective_instagram_media_id`). Use to map a Business-Manager-visible IG post back to the Zernio ad.
|
|
@@ -1504,6 +1506,7 @@ module Zernio
|
|
|
1504
1506
|
query_params[:'pageId'] = opts[:'page_id'] if !opts[:'page_id'].nil?
|
|
1505
1507
|
query_params[:'profileId'] = opts[:'profile_id'] if !opts[:'profile_id'].nil?
|
|
1506
1508
|
query_params[:'campaignId'] = opts[:'campaign_id'] if !opts[:'campaign_id'].nil?
|
|
1509
|
+
query_params[:'adSetId'] = opts[:'ad_set_id'] if !opts[:'ad_set_id'].nil?
|
|
1507
1510
|
query_params[:'platformAdId'] = opts[:'platform_ad_id'] if !opts[:'platform_ad_id'].nil?
|
|
1508
1511
|
query_params[:'effectiveObjectStoryId'] = opts[:'effective_object_story_id'] if !opts[:'effective_object_story_id'].nil?
|
|
1509
1512
|
query_params[:'effectiveInstagramMediaId'] = opts[:'effective_instagram_media_id'] if !opts[:'effective_instagram_media_id'].nil?
|
|
@@ -295,11 +295,11 @@ module Zernio
|
|
|
295
295
|
end
|
|
296
296
|
|
|
297
297
|
# Search targeting options
|
|
298
|
-
# Resolve a human-readable query into the platform's opaque targeting ids used in the `TargetingSpec` (`countries`/`regions`/`cities`/`zips`/`metros` geo keys, and `interests`/`behaviors` entity ids) on `POST /v1/ads/create`, `POST /v1/ads/targeting/reach-estimate`, and `saved_targeting` audiences. The `dimension` param selects what is searched, `geo` (locations, further scoped by `geoType`), `interest`, `behavior`, or `
|
|
298
|
+
# Resolve a human-readable query into the platform's opaque targeting ids used in the `TargetingSpec` (`countries`/`regions`/`cities`/`zips`/`metros` geo keys, and `interests`/`behaviors` entity ids) on `POST /v1/ads/create`, `POST /v1/ads/targeting/reach-estimate`, and `saved_targeting` audiences. The `dimension` param selects what is searched, `geo` (locations, further scoped by `geoType`), `interest`, `behavior`, `income`, or the Meta-only work demographics `workPosition`, `workEmployer` and `workIndustry` (their ids feed `TargetingSpec.workPositions`/`workEmployers`/`workIndustries`). Availability of each dimension varies by platform (e.g. behaviours are Meta/TikTok only). Work industries are a fixed ~30-entry Meta catalog with no server-side query, so `workIndustry` matching, ranking and `limit` happen in Zernio. Results are normalized across platforms into a single shape, so the same client code consumes Meta, TikTok, LinkedIn, X, Pinterest, and Google results. TikTok geo searches return every matching level in one list (`type` is `country`, `region`, `city`, `district`, or `metro` for DMA areas) — `geoType` is not applied. Results are scoped to the advertiser's targetable markets, and every id is usable in `regions`/`cities`/`metros` keys on `POST /v1/ads/create`. LinkedIn geo searches also return every matching level in one list, and neither `geoType` nor `countryCode` is applied: LinkedIn's typeahead only returns a name and a URN per result, with no level or country field to filter on. Every result has `type` set to `location`, and its id is a `urn:li:geo:*` URN usable as a `regions[].key` on `POST /v1/ads/create`, `POST /v1/ads/boost` and `POST /v1/ads/targeting/reach-estimate`. Google geo searches resolve against Google's geoTargetConstants and return every matching level in one list; `geoType` is not applied (Google's `target_type` is an open taxonomy that does not map one-to-one onto the `geoType` enum), so filter client-side on the returned `type` (`country`, `region`, `city`, `zip`, `metro`, or the lowercased Google target type for rarer levels). `countryCode` scopes the search to one country. Each id is Google's numeric criterion id, usable as a `regions`/`cities`/`zips`/`metros` `key` on `POST /v1/ads/create`. Google city radius is not supported (pass a `customLocations` lat/lng pin for a radius); country targeting also accepts plain ISO codes via `countries` with no search call. Pinterest resolves against three whole-catalog endpoints (interests, locations, regions) with no server-side query or pagination, so matching, ranking and the `limit` cutoff all happen in Zernio; the catalog is independent of any ad account and results never carry `audienceSize`. Names come back localized to the connected Pinterest account's language (there is no way to force a locale), so match against whatever language that account returns. `geoType` routes to a different catalog: `country` and `metro_area` read the locations catalog (`type` is `country` or `metro`); `region` reads the regions catalog (`type` is `region`, its id a `regions[].key` on `POST /v1/ads/create`); `all` and the default `city` merge both catalogs with honest per-entry `type`s, since Pinterest has no city-level catalog and `city` is an alias for `all`, not a literal city search. `zip`, `subcity`, `neighborhood`, `place` and `geo_market` return a 400: Pinterest exposes no postal-code catalog, pass postal codes directly as `targeting.zips: [{ key }]` on `POST /v1/ads/create`. For geo queries, `q` should contain only the locality name (e.g. `\"Amsterdam\"`, not `\"Amsterdam, NL\"`). Use `countryCode` to disambiguate.
|
|
299
299
|
# @param account_id [String] Social account ID (a connected account on the target ad platform).
|
|
300
300
|
# @param q [String] Search query. For geo, the locality name only (no region/country suffix).
|
|
301
301
|
# @param [Hash] opts the optional parameters
|
|
302
|
-
# @option opts [String] :dimension What to search. `geo` resolves locations (scope further with `geoType`), `interest`/`behavior` resolve audience entities, `income` resolves income-tier options. Defaults to `interest` for backward compatibility with the deprecated /v1/ads/interests alias. (default to 'interest')
|
|
302
|
+
# @option opts [String] :dimension What to search. `geo` resolves locations (scope further with `geoType`), `interest`/`behavior` resolve audience entities, `income` resolves income-tier options, `workPosition`/`workEmployer`/`workIndustry` resolve Meta work demographics. Defaults to `interest` for backward compatibility with the deprecated /v1/ads/interests alias. (default to 'interest')
|
|
303
303
|
# @option opts [String] :geo_type Only used when `dimension=geo`. The kind of location to resolve. `all` searches every type in one relevance-ranked call. Defaults to `city`. (default to 'city')
|
|
304
304
|
# @option opts [String] :country_code ISO 3166-1 alpha-2 country code (e.g. NL) to scope a geo search.
|
|
305
305
|
# @option opts [Integer] :limit Maximum results to return. (default to 25)
|
|
@@ -310,11 +310,11 @@ module Zernio
|
|
|
310
310
|
end
|
|
311
311
|
|
|
312
312
|
# Search targeting options
|
|
313
|
-
# Resolve a human-readable query into the platform's opaque targeting ids used in the `TargetingSpec` (`countries`/`regions`/`cities`/`zips`/`metros` geo keys, and `interests`/`behaviors` entity ids) on `POST /v1/ads/create`, `POST /v1/ads/targeting/reach-estimate`, and `saved_targeting` audiences. The `dimension` param selects what is searched, `geo` (locations, further scoped by `geoType`), `interest`, `behavior`, or `
|
|
313
|
+
# Resolve a human-readable query into the platform's opaque targeting ids used in the `TargetingSpec` (`countries`/`regions`/`cities`/`zips`/`metros` geo keys, and `interests`/`behaviors` entity ids) on `POST /v1/ads/create`, `POST /v1/ads/targeting/reach-estimate`, and `saved_targeting` audiences. The `dimension` param selects what is searched, `geo` (locations, further scoped by `geoType`), `interest`, `behavior`, `income`, or the Meta-only work demographics `workPosition`, `workEmployer` and `workIndustry` (their ids feed `TargetingSpec.workPositions`/`workEmployers`/`workIndustries`). Availability of each dimension varies by platform (e.g. behaviours are Meta/TikTok only). Work industries are a fixed ~30-entry Meta catalog with no server-side query, so `workIndustry` matching, ranking and `limit` happen in Zernio. Results are normalized across platforms into a single shape, so the same client code consumes Meta, TikTok, LinkedIn, X, Pinterest, and Google results. TikTok geo searches return every matching level in one list (`type` is `country`, `region`, `city`, `district`, or `metro` for DMA areas) — `geoType` is not applied. Results are scoped to the advertiser's targetable markets, and every id is usable in `regions`/`cities`/`metros` keys on `POST /v1/ads/create`. LinkedIn geo searches also return every matching level in one list, and neither `geoType` nor `countryCode` is applied: LinkedIn's typeahead only returns a name and a URN per result, with no level or country field to filter on. Every result has `type` set to `location`, and its id is a `urn:li:geo:*` URN usable as a `regions[].key` on `POST /v1/ads/create`, `POST /v1/ads/boost` and `POST /v1/ads/targeting/reach-estimate`. Google geo searches resolve against Google's geoTargetConstants and return every matching level in one list; `geoType` is not applied (Google's `target_type` is an open taxonomy that does not map one-to-one onto the `geoType` enum), so filter client-side on the returned `type` (`country`, `region`, `city`, `zip`, `metro`, or the lowercased Google target type for rarer levels). `countryCode` scopes the search to one country. Each id is Google's numeric criterion id, usable as a `regions`/`cities`/`zips`/`metros` `key` on `POST /v1/ads/create`. Google city radius is not supported (pass a `customLocations` lat/lng pin for a radius); country targeting also accepts plain ISO codes via `countries` with no search call. Pinterest resolves against three whole-catalog endpoints (interests, locations, regions) with no server-side query or pagination, so matching, ranking and the `limit` cutoff all happen in Zernio; the catalog is independent of any ad account and results never carry `audienceSize`. Names come back localized to the connected Pinterest account's language (there is no way to force a locale), so match against whatever language that account returns. `geoType` routes to a different catalog: `country` and `metro_area` read the locations catalog (`type` is `country` or `metro`); `region` reads the regions catalog (`type` is `region`, its id a `regions[].key` on `POST /v1/ads/create`); `all` and the default `city` merge both catalogs with honest per-entry `type`s, since Pinterest has no city-level catalog and `city` is an alias for `all`, not a literal city search. `zip`, `subcity`, `neighborhood`, `place` and `geo_market` return a 400: Pinterest exposes no postal-code catalog, pass postal codes directly as `targeting.zips: [{ key }]` on `POST /v1/ads/create`. For geo queries, `q` should contain only the locality name (e.g. `\"Amsterdam\"`, not `\"Amsterdam, NL\"`). Use `countryCode` to disambiguate.
|
|
314
314
|
# @param account_id [String] Social account ID (a connected account on the target ad platform).
|
|
315
315
|
# @param q [String] Search query. For geo, the locality name only (no region/country suffix).
|
|
316
316
|
# @param [Hash] opts the optional parameters
|
|
317
|
-
# @option opts [String] :dimension What to search. `geo` resolves locations (scope further with `geoType`), `interest`/`behavior` resolve audience entities, `income` resolves income-tier options. Defaults to `interest` for backward compatibility with the deprecated /v1/ads/interests alias. (default to 'interest')
|
|
317
|
+
# @option opts [String] :dimension What to search. `geo` resolves locations (scope further with `geoType`), `interest`/`behavior` resolve audience entities, `income` resolves income-tier options, `workPosition`/`workEmployer`/`workIndustry` resolve Meta work demographics. Defaults to `interest` for backward compatibility with the deprecated /v1/ads/interests alias. (default to 'interest')
|
|
318
318
|
# @option opts [String] :geo_type Only used when `dimension=geo`. The kind of location to resolve. `all` searches every type in one relevance-ranked call. Defaults to `city`. (default to 'city')
|
|
319
319
|
# @option opts [String] :country_code ISO 3166-1 alpha-2 country code (e.g. NL) to scope a geo search.
|
|
320
320
|
# @option opts [Integer] :limit Maximum results to return. (default to 25)
|
|
@@ -331,7 +331,7 @@ module Zernio
|
|
|
331
331
|
if @api_client.config.client_side_validation && q.nil?
|
|
332
332
|
fail ArgumentError, "Missing the required parameter 'q' when calling AdTargetingApi.search_ad_targeting"
|
|
333
333
|
end
|
|
334
|
-
allowable_values = ["geo", "interest", "behavior", "income"]
|
|
334
|
+
allowable_values = ["geo", "interest", "behavior", "income", "workPosition", "workEmployer", "workIndustry"]
|
|
335
335
|
if @api_client.config.client_side_validation && opts[:'dimension'] && !allowable_values.include?(opts[:'dimension'])
|
|
336
336
|
fail ArgumentError, "invalid value for \"dimension\", must be one of #{allowable_values}"
|
|
337
337
|
end
|
|
@@ -1142,7 +1142,7 @@ module Zernio
|
|
|
1142
1142
|
end
|
|
1143
1143
|
|
|
1144
1144
|
# Message sent event
|
|
1145
|
-
# Fired when a message is sent via the API, or from the WhatsApp Business app on Coexistence numbers. Sends that carry platform-specific context deliver it under `metadata`, so a quote-reply arrives with `metadata.quotedMessageId` and mirroring CRMs can thread it without a lookup.
|
|
1145
|
+
# Fired when a message is sent via the API, or from the WhatsApp Business app on Coexistence numbers. Sends that carry platform-specific context deliver it under `metadata`, so a quote-reply sent through the API arrives with `metadata.quotedMessageId` and mirroring CRMs can thread it without a lookup. Which surfaces actually carry that reference is documented on `WebhookPayloadMessageSent.metadata.quotedMessageId`; a quote-reply sent from the WhatsApp Business or Instagram app is not one of them.
|
|
1146
1146
|
# @param webhook_payload_message_sent [WebhookPayloadMessageSent]
|
|
1147
1147
|
# @param [Hash] opts the optional parameters
|
|
1148
1148
|
# @return [nil]
|
|
@@ -1152,7 +1152,7 @@ module Zernio
|
|
|
1152
1152
|
end
|
|
1153
1153
|
|
|
1154
1154
|
# Message sent event
|
|
1155
|
-
# Fired when a message is sent via the API, or from the WhatsApp Business app on Coexistence numbers. Sends that carry platform-specific context deliver it under `metadata`, so a quote-reply arrives with `metadata.quotedMessageId` and mirroring CRMs can thread it without a lookup.
|
|
1155
|
+
# Fired when a message is sent via the API, or from the WhatsApp Business app on Coexistence numbers. Sends that carry platform-specific context deliver it under `metadata`, so a quote-reply sent through the API arrives with `metadata.quotedMessageId` and mirroring CRMs can thread it without a lookup. Which surfaces actually carry that reference is documented on `WebhookPayloadMessageSent.metadata.quotedMessageId`; a quote-reply sent from the WhatsApp Business or Instagram app is not one of them.
|
|
1156
1156
|
# @param webhook_payload_message_sent [WebhookPayloadMessageSent]
|
|
1157
1157
|
# @param [Hash] opts the optional parameters
|
|
1158
1158
|
# @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
|
|
@@ -154,6 +154,15 @@ module Zernio
|
|
|
154
154
|
# Behaviour entities from /v1/ads/targeting/search?dimension=behavior. Supported on Meta and TikTok. Each must include id.
|
|
155
155
|
attr_accessor :behaviors
|
|
156
156
|
|
|
157
|
+
# Meta only. Job title entities from /v1/ads/targeting/search?dimension=workPosition. Each must include id. Rejected on other platforms (use LinkedIn's `jobTitles` there).
|
|
158
|
+
attr_accessor :work_positions
|
|
159
|
+
|
|
160
|
+
# Meta only. Employer entities from /v1/ads/targeting/search?dimension=workEmployer. Each must include id.
|
|
161
|
+
attr_accessor :work_employers
|
|
162
|
+
|
|
163
|
+
# Meta only. Work-industry entities from /v1/ads/targeting/search?dimension=workIndustry. Each must include id. Rejected on other platforms (use LinkedIn's `industries` there).
|
|
164
|
+
attr_accessor :work_industries
|
|
165
|
+
|
|
157
166
|
# Normalized household-income tier. Meta and TikTok express all four; Google maps only `top_10`; rejected on LinkedIn, X, and Pinterest. On Meta, income targeting is incompatible with housing/employment/credit `specialAdCategories`.
|
|
158
167
|
attr_accessor :income_tier
|
|
159
168
|
|
|
@@ -339,6 +348,9 @@ module Zernio
|
|
|
339
348
|
:'metros' => :'metros',
|
|
340
349
|
:'custom_locations' => :'customLocations',
|
|
341
350
|
:'behaviors' => :'behaviors',
|
|
351
|
+
:'work_positions' => :'workPositions',
|
|
352
|
+
:'work_employers' => :'workEmployers',
|
|
353
|
+
:'work_industries' => :'workIndustries',
|
|
342
354
|
:'income_tier' => :'incomeTier',
|
|
343
355
|
:'languages' => :'languages',
|
|
344
356
|
:'placements' => :'placements',
|
|
@@ -443,6 +455,9 @@ module Zernio
|
|
|
443
455
|
:'metros' => :'Array<BoostPostRequestTargetingRegionsInner>',
|
|
444
456
|
:'custom_locations' => :'Array<CreateStandaloneAdRequestCustomLocationsInner>',
|
|
445
457
|
:'behaviors' => :'Array<CreateStandaloneAdRequestBehaviorsInner>',
|
|
458
|
+
:'work_positions' => :'Array<CreateStandaloneAdRequestBehaviorsInner>',
|
|
459
|
+
:'work_employers' => :'Array<CreateStandaloneAdRequestBehaviorsInner>',
|
|
460
|
+
:'work_industries' => :'Array<CreateStandaloneAdRequestBehaviorsInner>',
|
|
446
461
|
:'income_tier' => :'String',
|
|
447
462
|
:'languages' => :'Array<String>',
|
|
448
463
|
:'placements' => :'CreateStandaloneAdRequestPlacements',
|
|
@@ -731,6 +746,24 @@ module Zernio
|
|
|
731
746
|
end
|
|
732
747
|
end
|
|
733
748
|
|
|
749
|
+
if attributes.key?(:'work_positions')
|
|
750
|
+
if (value = attributes[:'work_positions']).is_a?(Array)
|
|
751
|
+
self.work_positions = value
|
|
752
|
+
end
|
|
753
|
+
end
|
|
754
|
+
|
|
755
|
+
if attributes.key?(:'work_employers')
|
|
756
|
+
if (value = attributes[:'work_employers']).is_a?(Array)
|
|
757
|
+
self.work_employers = value
|
|
758
|
+
end
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
if attributes.key?(:'work_industries')
|
|
762
|
+
if (value = attributes[:'work_industries']).is_a?(Array)
|
|
763
|
+
self.work_industries = value
|
|
764
|
+
end
|
|
765
|
+
end
|
|
766
|
+
|
|
734
767
|
if attributes.key?(:'income_tier')
|
|
735
768
|
self.income_tier = attributes[:'income_tier']
|
|
736
769
|
end
|
|
@@ -1643,6 +1676,9 @@ module Zernio
|
|
|
1643
1676
|
metros == o.metros &&
|
|
1644
1677
|
custom_locations == o.custom_locations &&
|
|
1645
1678
|
behaviors == o.behaviors &&
|
|
1679
|
+
work_positions == o.work_positions &&
|
|
1680
|
+
work_employers == o.work_employers &&
|
|
1681
|
+
work_industries == o.work_industries &&
|
|
1646
1682
|
income_tier == o.income_tier &&
|
|
1647
1683
|
languages == o.languages &&
|
|
1648
1684
|
placements == o.placements &&
|
|
@@ -1693,7 +1729,7 @@ module Zernio
|
|
|
1693
1729
|
# Calculates hash code according to all attributes.
|
|
1694
1730
|
# @return [Integer] Hash code
|
|
1695
1731
|
def hash
|
|
1696
|
-
[account_id, ad_account_id, name, campaign_name, ad_set_name, ad_name, tracking, goal, optimization_goal, billing_event, buying_type, rf_prediction_id, creative_features, multi_advertiser, validate_only, budget_amount, budget_type, status, campaign_status, budget_level, currency, headline, long_headline, body, description, call_to_action, link_url, lead_gen_form_id, image_url, images, video, creatives, ad_set_id, existing_campaign_id, existing_creative_id, business_name, board_id, organization_id, targeting, countries, cities, regions, age_min, age_max, interests, zips, metros, custom_locations, behaviors, income_tier, languages, placements, saved_targeting_id, raw_targeting, special_ad_categories, special_ad_category_country, end_date, start_date, instagram_account_id, dynamic_creative, carousel_cards, default_locale, translations, placement_assets, audience_id, campaign_type, keywords, negative_keywords, additional_headlines, additional_descriptions, sitelinks, callouts, structured_snippets, advantage_audience, attribution_spec, gender, bid_strategy, bid_amount, roas_average_floor, value_rule_set_id, value_rules_applied, platform_specific_data, dsa_beneficiary, dsa_payor, brand_identity, identity_type, smart_plus, promoted_object].hash
|
|
1732
|
+
[account_id, ad_account_id, name, campaign_name, ad_set_name, ad_name, tracking, goal, optimization_goal, billing_event, buying_type, rf_prediction_id, creative_features, multi_advertiser, validate_only, budget_amount, budget_type, status, campaign_status, budget_level, currency, headline, long_headline, body, description, call_to_action, link_url, lead_gen_form_id, image_url, images, video, creatives, ad_set_id, existing_campaign_id, existing_creative_id, business_name, board_id, organization_id, targeting, countries, cities, regions, age_min, age_max, interests, zips, metros, custom_locations, behaviors, work_positions, work_employers, work_industries, income_tier, languages, placements, saved_targeting_id, raw_targeting, special_ad_categories, special_ad_category_country, end_date, start_date, instagram_account_id, dynamic_creative, carousel_cards, default_locale, translations, placement_assets, audience_id, campaign_type, keywords, negative_keywords, additional_headlines, additional_descriptions, sitelinks, callouts, structured_snippets, advantage_audience, attribution_spec, gender, bid_strategy, bid_amount, roas_average_floor, value_rule_set_id, value_rules_applied, platform_specific_data, dsa_beneficiary, dsa_payor, brand_identity, identity_type, smart_plus, promoted_object].hash
|
|
1697
1733
|
end
|
|
1698
1734
|
|
|
1699
1735
|
# Builds the object from hash
|
|
@@ -15,6 +15,7 @@ require 'time'
|
|
|
15
15
|
|
|
16
16
|
module Zernio
|
|
17
17
|
class GetInboxConversationMessages200ResponseMessagesInner < ApiModelBase
|
|
18
|
+
# The platform's own message id: the `wamid` on WhatsApp, the `mid` on Instagram and Facebook Messenger. This is what `metadata.quotedMessageId` points at, the value to pass as `replyTo` on the platforms that support quote-replies, and the `{messageId}` segment of the attachment-resolve URL. Webhooks deliver the same value as `message.platformMessageId`; this response has no field by that name.
|
|
18
19
|
attr_accessor :id
|
|
19
20
|
|
|
20
21
|
attr_accessor :conversation_id
|
|
@@ -79,7 +80,7 @@ module Zernio
|
|
|
79
80
|
# Emoji reactions on this message (WhatsApp / Telegram). At most one per party in a 1:1 thread.
|
|
80
81
|
attr_accessor :reactions
|
|
81
82
|
|
|
82
|
-
# Platform-specific extras. Free-form, but commonly includes: `quotedMessageId` (
|
|
83
|
+
# Platform-specific extras. Free-form, but commonly includes: `quotedMessageId` (the `id` of the message this one replies to, delivered as `message.platformMessageId` on webhooks), `waInteractive` (a compact descriptor of WhatsApp interactive content sent: buttons / list / cta_url / flow / location_request), and for inbound interactive taps `interactiveType` / `interactiveId`. It can also carry `source` (`whatsapp_business_app` / `coexistence_history` on a WhatsApp Coexistence number, `bulk-api` on a POST /v1/whatsapp/bulk send), which is where the message reached us from rather than who produced it: read `sentVia` for that.
|
|
83
84
|
attr_accessor :metadata
|
|
84
85
|
|
|
85
86
|
# Which Zernio surface produced this outgoing message: `human` (an operator in the Zernio inbox), `api` (a call to this API), `broadcast`, `sequence`, `workflow`, `comment_automation`, or `bulk-api` (POST /v1/whatsapp/bulk). Same vocabulary as the `source` filter on the inbox analytics endpoints. Always present, and `null` whenever the lineage is unknown: every incoming message, any outgoing message sent from the platform's own app, and every message stored before this field shipped (2026-08). Existing messages are NOT backfilled, so treat `null` as \"unknown\", never as \"sent by a human\".
|
|
@@ -57,7 +57,7 @@ module Zernio
|
|
|
57
57
|
# Facebook message tag for messaging outside 24h window. Requires messagingType MESSAGE_TAG. Instagram only supports HUMAN_AGENT.
|
|
58
58
|
attr_accessor :message_tag
|
|
59
59
|
|
|
60
|
-
# Platform message ID to quote-reply to. For WhatsApp, pass the wamid; for Telegram, the Telegram message ID (
|
|
60
|
+
# Platform message ID to quote-reply to. For WhatsApp, pass the wamid; for Telegram, the Telegram message ID (delivered as message.platformMessageId on webhooks, and as `id` on each entry of the list-messages endpoint). On Slack it threads the reply (thread_ts) instead of quoting. Silently ignored on platforms without send-side reply support, including Instagram and Facebook Messenger (Meta's Send API rejects reply_to on Instagram and does not expose it on Messenger).
|
|
61
61
|
attr_accessor :reply_to
|
|
62
62
|
|
|
63
63
|
attr_accessor :location
|
|
@@ -57,6 +57,15 @@ module Zernio
|
|
|
57
57
|
# Behaviour entities from /v1/ads/targeting/search?dimension=behavior. Supported on Meta and TikTok.
|
|
58
58
|
attr_accessor :behaviors
|
|
59
59
|
|
|
60
|
+
# Meta only. Job title entities from /v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.
|
|
61
|
+
attr_accessor :work_positions
|
|
62
|
+
|
|
63
|
+
# Meta only. Employer entities from /v1/ads/targeting/search?dimension=workEmployer.
|
|
64
|
+
attr_accessor :work_employers
|
|
65
|
+
|
|
66
|
+
# Meta only. Work-industry entities from /v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.
|
|
67
|
+
attr_accessor :work_industries
|
|
68
|
+
|
|
60
69
|
# LinkedIn B2B only. Industry URN id fragments.
|
|
61
70
|
attr_accessor :industries
|
|
62
71
|
|
|
@@ -69,10 +78,10 @@ module Zernio
|
|
|
69
78
|
# LinkedIn B2B only.
|
|
70
79
|
attr_accessor :job_functions
|
|
71
80
|
|
|
72
|
-
# Platform audience IDs to include
|
|
81
|
+
# Platform audience IDs to include, as returned by GET /v1/ads/audiences (Meta custom audience ids, TikTok audience ids, Pinterest customer list ids, LinkedIn segment ids (bare, urn:li:adSegment or urn:li:dmpSegment forms accepted), Google user list ids, X custom audience ids). Not supported on OpenAI (400).
|
|
73
82
|
attr_accessor :audience_include
|
|
74
83
|
|
|
75
|
-
# Platform audience IDs to exclude. Not supported on
|
|
84
|
+
# Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400).
|
|
76
85
|
attr_accessor :audience_exclude
|
|
77
86
|
|
|
78
87
|
class EnumAttributeValidator
|
|
@@ -114,6 +123,9 @@ module Zernio
|
|
|
114
123
|
:'languages' => :'languages',
|
|
115
124
|
:'interests' => :'interests',
|
|
116
125
|
:'behaviors' => :'behaviors',
|
|
126
|
+
:'work_positions' => :'workPositions',
|
|
127
|
+
:'work_employers' => :'workEmployers',
|
|
128
|
+
:'work_industries' => :'workIndustries',
|
|
117
129
|
:'industries' => :'industries',
|
|
118
130
|
:'company_sizes' => :'companySizes',
|
|
119
131
|
:'seniorities' => :'seniorities',
|
|
@@ -150,6 +162,9 @@ module Zernio
|
|
|
150
162
|
:'languages' => :'Array<String>',
|
|
151
163
|
:'interests' => :'Array<CreateStandaloneAdRequestBehaviorsInner>',
|
|
152
164
|
:'behaviors' => :'Array<CreateStandaloneAdRequestBehaviorsInner>',
|
|
165
|
+
:'work_positions' => :'Array<CreateStandaloneAdRequestBehaviorsInner>',
|
|
166
|
+
:'work_employers' => :'Array<CreateStandaloneAdRequestBehaviorsInner>',
|
|
167
|
+
:'work_industries' => :'Array<CreateStandaloneAdRequestBehaviorsInner>',
|
|
153
168
|
:'industries' => :'Array<String>',
|
|
154
169
|
:'company_sizes' => :'Array<String>',
|
|
155
170
|
:'seniorities' => :'Array<String>',
|
|
@@ -255,6 +270,24 @@ module Zernio
|
|
|
255
270
|
end
|
|
256
271
|
end
|
|
257
272
|
|
|
273
|
+
if attributes.key?(:'work_positions')
|
|
274
|
+
if (value = attributes[:'work_positions']).is_a?(Array)
|
|
275
|
+
self.work_positions = value
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
if attributes.key?(:'work_employers')
|
|
280
|
+
if (value = attributes[:'work_employers']).is_a?(Array)
|
|
281
|
+
self.work_employers = value
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
if attributes.key?(:'work_industries')
|
|
286
|
+
if (value = attributes[:'work_industries']).is_a?(Array)
|
|
287
|
+
self.work_industries = value
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
258
291
|
if attributes.key?(:'industries')
|
|
259
292
|
if (value = attributes[:'industries']).is_a?(Array)
|
|
260
293
|
self.industries = value
|
|
@@ -406,6 +439,9 @@ module Zernio
|
|
|
406
439
|
languages == o.languages &&
|
|
407
440
|
interests == o.interests &&
|
|
408
441
|
behaviors == o.behaviors &&
|
|
442
|
+
work_positions == o.work_positions &&
|
|
443
|
+
work_employers == o.work_employers &&
|
|
444
|
+
work_industries == o.work_industries &&
|
|
409
445
|
industries == o.industries &&
|
|
410
446
|
company_sizes == o.company_sizes &&
|
|
411
447
|
seniorities == o.seniorities &&
|
|
@@ -423,7 +459,7 @@ module Zernio
|
|
|
423
459
|
# Calculates hash code according to all attributes.
|
|
424
460
|
# @return [Integer] Hash code
|
|
425
461
|
def hash
|
|
426
|
-
[countries, regions, cities, zips, metros, custom_locations, excluded_locations, age_min, age_max, gender, income_tier, languages, interests, behaviors, industries, company_sizes, seniorities, job_functions, audience_include, audience_exclude].hash
|
|
462
|
+
[countries, regions, cities, zips, metros, custom_locations, excluded_locations, age_min, age_max, gender, income_tier, languages, interests, behaviors, work_positions, work_employers, work_industries, industries, company_sizes, seniorities, job_functions, audience_include, audience_exclude].hash
|
|
427
463
|
end
|
|
428
464
|
|
|
429
465
|
# Builds the object from hash
|
|
@@ -14,13 +14,16 @@ require 'date'
|
|
|
14
14
|
require 'time'
|
|
15
15
|
|
|
16
16
|
module Zernio
|
|
17
|
-
# Replace the ad's creative. Meta, TikTok, and LinkedIn. - **Meta**:
|
|
17
|
+
# Replace or patch the ad's creative. Meta, TikTok, and LinkedIn. - **Meta**: patch-style. Pass any subset — fields you omit are preserved from the live creative, including media (`image_hash`/`video_id` are reused, no re-upload) and `url_tags`. Sending the full set (`headline`, `body`, `callToAction`, `linkUrl`, `imageUrl`) rebuilds the creative from scratch instead. Partial patching reads the live `object_story_spec`, which Meta strips on SHARE / page-post / dark / asset_feed creatives — those return 422 asking for the full set. A `videoUrl`/`videoId` on an image creative is a type change and also needs the full set. `existingCreativeId` repoints the ad at a creative from GET /v1/ads/creatives and ignores every other field. Meta creatives are immutable, so any change creates a new creative and repoints the ad; the old creative is retained on the ad account for historical reporting. - **TikTok**: patch-style. Pass any subset; `headline` is ignored (TikTok creatives have no headline slot). `body` becomes the in-feed `ad_text`; `linkUrl` becomes `landing_page_url`; `videoUrl` triggers a fresh upload. `description`, `videoId` and `existingCreativeId` are Meta-only and return 400. - **LinkedIn**: uploads new media (image via `imageUrl` or video via `videoUrl`), creates a new inline media creative on the same campaign, and pauses the old creative (best-effort). The old creative is retained for historical reporting. `videoId` and `existingCreativeId` are Meta-only and return 400.
|
|
18
18
|
class UpdateAdRequestCreative < ApiModelBase
|
|
19
|
-
# Meta
|
|
19
|
+
# Meta and LinkedIn (TikTok has no headline slot)
|
|
20
20
|
attr_accessor :headline
|
|
21
21
|
|
|
22
22
|
attr_accessor :body
|
|
23
23
|
|
|
24
|
+
# Link description slot (Meta `link_data.description` / `video_data.link_description`, LinkedIn creative description).
|
|
25
|
+
attr_accessor :description
|
|
26
|
+
|
|
24
27
|
attr_accessor :call_to_action
|
|
25
28
|
|
|
26
29
|
attr_accessor :link_url
|
|
@@ -29,15 +32,24 @@ module Zernio
|
|
|
29
32
|
|
|
30
33
|
attr_accessor :video_url
|
|
31
34
|
|
|
35
|
+
# Meta only. Reuse an already-uploaded ad video (from POST /v1/ads/videos or GET /v1/ads/videos) instead of re-uploading via videoUrl.
|
|
36
|
+
attr_accessor :video_id
|
|
37
|
+
|
|
38
|
+
# Meta only. Repoint the ad at an existing library creative (from GET /v1/ads/creatives); all other creative fields are ignored.
|
|
39
|
+
attr_accessor :existing_creative_id
|
|
40
|
+
|
|
32
41
|
# Attribute mapping from ruby-style variable name to JSON key.
|
|
33
42
|
def self.attribute_map
|
|
34
43
|
{
|
|
35
44
|
:'headline' => :'headline',
|
|
36
45
|
:'body' => :'body',
|
|
46
|
+
:'description' => :'description',
|
|
37
47
|
:'call_to_action' => :'callToAction',
|
|
38
48
|
:'link_url' => :'linkUrl',
|
|
39
49
|
:'image_url' => :'imageUrl',
|
|
40
|
-
:'video_url' => :'videoUrl'
|
|
50
|
+
:'video_url' => :'videoUrl',
|
|
51
|
+
:'video_id' => :'videoId',
|
|
52
|
+
:'existing_creative_id' => :'existingCreativeId'
|
|
41
53
|
}
|
|
42
54
|
end
|
|
43
55
|
|
|
@@ -56,10 +68,13 @@ module Zernio
|
|
|
56
68
|
{
|
|
57
69
|
:'headline' => :'String',
|
|
58
70
|
:'body' => :'String',
|
|
71
|
+
:'description' => :'String',
|
|
59
72
|
:'call_to_action' => :'String',
|
|
60
73
|
:'link_url' => :'String',
|
|
61
74
|
:'image_url' => :'String',
|
|
62
|
-
:'video_url' => :'String'
|
|
75
|
+
:'video_url' => :'String',
|
|
76
|
+
:'video_id' => :'String',
|
|
77
|
+
:'existing_creative_id' => :'String'
|
|
63
78
|
}
|
|
64
79
|
end
|
|
65
80
|
|
|
@@ -93,6 +108,10 @@ module Zernio
|
|
|
93
108
|
self.body = attributes[:'body']
|
|
94
109
|
end
|
|
95
110
|
|
|
111
|
+
if attributes.key?(:'description')
|
|
112
|
+
self.description = attributes[:'description']
|
|
113
|
+
end
|
|
114
|
+
|
|
96
115
|
if attributes.key?(:'call_to_action')
|
|
97
116
|
self.call_to_action = attributes[:'call_to_action']
|
|
98
117
|
end
|
|
@@ -108,6 +127,14 @@ module Zernio
|
|
|
108
127
|
if attributes.key?(:'video_url')
|
|
109
128
|
self.video_url = attributes[:'video_url']
|
|
110
129
|
end
|
|
130
|
+
|
|
131
|
+
if attributes.key?(:'video_id')
|
|
132
|
+
self.video_id = attributes[:'video_id']
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
if attributes.key?(:'existing_creative_id')
|
|
136
|
+
self.existing_creative_id = attributes[:'existing_creative_id']
|
|
137
|
+
end
|
|
111
138
|
end
|
|
112
139
|
|
|
113
140
|
# Show invalid properties with the reasons. Usually used together with valid?
|
|
@@ -115,6 +142,10 @@ module Zernio
|
|
|
115
142
|
def list_invalid_properties
|
|
116
143
|
warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
|
|
117
144
|
invalid_properties = Array.new
|
|
145
|
+
if !@description.nil? && @description.to_s.length > 255
|
|
146
|
+
invalid_properties.push('invalid value for "description", the character length must be smaller than or equal to 255.')
|
|
147
|
+
end
|
|
148
|
+
|
|
118
149
|
invalid_properties
|
|
119
150
|
end
|
|
120
151
|
|
|
@@ -122,9 +153,24 @@ module Zernio
|
|
|
122
153
|
# @return true if the model is valid
|
|
123
154
|
def valid?
|
|
124
155
|
warn '[DEPRECATED] the `valid?` method is obsolete'
|
|
156
|
+
return false if !@description.nil? && @description.to_s.length > 255
|
|
125
157
|
true
|
|
126
158
|
end
|
|
127
159
|
|
|
160
|
+
# Custom attribute writer method with validation
|
|
161
|
+
# @param [Object] description Value to be assigned
|
|
162
|
+
def description=(description)
|
|
163
|
+
if description.nil?
|
|
164
|
+
fail ArgumentError, 'description cannot be nil'
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
if description.to_s.length > 255
|
|
168
|
+
fail ArgumentError, 'invalid value for "description", the character length must be smaller than or equal to 255.'
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
@description = description
|
|
172
|
+
end
|
|
173
|
+
|
|
128
174
|
# Checks equality by comparing each attribute.
|
|
129
175
|
# @param [Object] Object to be compared
|
|
130
176
|
def ==(o)
|
|
@@ -132,10 +178,13 @@ module Zernio
|
|
|
132
178
|
self.class == o.class &&
|
|
133
179
|
headline == o.headline &&
|
|
134
180
|
body == o.body &&
|
|
181
|
+
description == o.description &&
|
|
135
182
|
call_to_action == o.call_to_action &&
|
|
136
183
|
link_url == o.link_url &&
|
|
137
184
|
image_url == o.image_url &&
|
|
138
|
-
video_url == o.video_url
|
|
185
|
+
video_url == o.video_url &&
|
|
186
|
+
video_id == o.video_id &&
|
|
187
|
+
existing_creative_id == o.existing_creative_id
|
|
139
188
|
end
|
|
140
189
|
|
|
141
190
|
# @see the `==` method
|
|
@@ -147,7 +196,7 @@ module Zernio
|
|
|
147
196
|
# Calculates hash code according to all attributes.
|
|
148
197
|
# @return [Integer] Hash code
|
|
149
198
|
def hash
|
|
150
|
-
[headline, body, call_to_action, link_url, image_url, video_url].hash
|
|
199
|
+
[headline, body, description, call_to_action, link_url, image_url, video_url, video_id, existing_creative_id].hash
|
|
151
200
|
end
|
|
152
201
|
|
|
153
202
|
# Builds the object from hash
|
|
@@ -16,7 +16,7 @@ require 'time'
|
|
|
16
16
|
module Zernio
|
|
17
17
|
# Platform-specific message context (present when the message is a quick reply tap, postback button tap, inline keyboard callback, or a quote-reply to an earlier message)
|
|
18
18
|
class WebhookPayloadMessageMetadata < ApiModelBase
|
|
19
|
-
# platformMessageId of the message this one is a quote-reply to. WhatsApp (`context.id`), Instagram and Facebook Messenger (`reply_to.mid`).
|
|
19
|
+
# platformMessageId of the message this one is a quote-reply to. WhatsApp (`context.id`), Instagram and Facebook Messenger (`reply_to.mid`). On outgoing messages the same field appears on `message.sent`, but only on some surfaces: see WebhookPayloadMessageSent.metadata.quotedMessageId.
|
|
20
20
|
attr_accessor :quoted_message_id
|
|
21
21
|
|
|
22
22
|
# Payload from a quick reply tap (Facebook/Instagram Messenger).
|
|
@@ -16,7 +16,7 @@ require 'time'
|
|
|
16
16
|
module Zernio
|
|
17
17
|
# Platform-specific context for the sent message. The key is present only when the send carried some context, and absent otherwise: it is never null and never an empty object.
|
|
18
18
|
class WebhookPayloadMessageSentMetadata < ApiModelBase
|
|
19
|
-
# platformMessageId of the message this send is a quote-reply to.
|
|
19
|
+
# `platformMessageId` of the message this send is a quote-reply to. Present when the reply was sent through Zernio with `replyTo` on the inbox send API (WhatsApp and Telegram). A WhatsApp API send fires its `message.sent` off the delivery status, and the quote reference is forwarded from the stored send there, so it arrives on the same `message.sent` as any other WhatsApp send. Not delivered on Instagram echoes. Zernio forwards `reply_to.mid` whenever Meta puts it on an echo, but on Instagram Meta does not send it, so a reply the operator quoted in the Instagram app arrives with no `quotedMessageId`. Facebook Messenger rides a separate subscription (`message_echoes`) and has not been measured, so treat it as unverified rather than supported. Absent on WhatsApp Coexistence echoes. Meta omits the quote context from `smb_message_echoes`, so a reply the operator sent from the WhatsApp Business app arrives with no `quotedMessageId` even though WhatsApp shows it as a quote-reply. Do not read the absence of this field as \"not a reply\".
|
|
20
20
|
attr_accessor :quoted_message_id
|
|
21
21
|
|
|
22
22
|
# Slack only. Parent thread ts of the sent message. Pass it back as `replyTo` on the inbox send API to keep replying inside the thread.
|
data/lib/zernio-sdk/version.rb
CHANGED
data/openapi.yaml
CHANGED
|
@@ -3749,8 +3749,9 @@ components:
|
|
|
3749
3749
|
description: |
|
|
3750
3750
|
platformMessageId of the message this one is a quote-reply to.
|
|
3751
3751
|
WhatsApp (`context.id`), Instagram and Facebook Messenger
|
|
3752
|
-
(`reply_to.mid`).
|
|
3753
|
-
`message.sent
|
|
3752
|
+
(`reply_to.mid`). On outgoing messages the same field appears on
|
|
3753
|
+
`message.sent`, but only on some surfaces: see
|
|
3754
|
+
WebhookPayloadMessageSent.metadata.quotedMessageId.
|
|
3754
3755
|
quickReplyPayload:
|
|
3755
3756
|
type: string
|
|
3756
3757
|
description: Payload from a quick reply tap (Facebook/Instagram Messenger).
|
|
@@ -4142,13 +4143,27 @@ components:
|
|
|
4142
4143
|
quotedMessageId:
|
|
4143
4144
|
type: string
|
|
4144
4145
|
description: |
|
|
4145
|
-
platformMessageId of the message this send is a quote-reply to.
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
other WhatsApp send.
|
|
4146
|
+
`platformMessageId` of the message this send is a quote-reply to.
|
|
4147
|
+
|
|
4148
|
+
Present when the reply was sent through Zernio with `replyTo` on
|
|
4149
|
+
the inbox send API (WhatsApp and Telegram). A WhatsApp API send
|
|
4150
|
+
fires its `message.sent` off the delivery status, and the quote
|
|
4151
|
+
reference is forwarded from the stored send there, so it arrives
|
|
4152
|
+
on the same `message.sent` as any other WhatsApp send.
|
|
4153
|
+
|
|
4154
|
+
Not delivered on Instagram echoes. Zernio forwards
|
|
4155
|
+
`reply_to.mid` whenever Meta puts it on an echo, but on
|
|
4156
|
+
Instagram Meta does not send it, so a reply the operator quoted
|
|
4157
|
+
in the Instagram app arrives with no `quotedMessageId`.
|
|
4158
|
+
Facebook Messenger rides a separate subscription
|
|
4159
|
+
(`message_echoes`) and has not been measured, so treat it as
|
|
4160
|
+
unverified rather than supported.
|
|
4161
|
+
|
|
4162
|
+
Absent on WhatsApp Coexistence echoes. Meta omits the quote
|
|
4163
|
+
context from `smb_message_echoes`, so a reply the operator sent
|
|
4164
|
+
from the WhatsApp Business app arrives with no `quotedMessageId`
|
|
4165
|
+
even though WhatsApp shows it as a quote-reply. Do not read the
|
|
4166
|
+
absence of this field as "not a reply".
|
|
4152
4167
|
threadTs:
|
|
4153
4168
|
type: string
|
|
4154
4169
|
description: |
|
|
@@ -8412,12 +8427,39 @@ components:
|
|
|
8412
8427
|
properties:
|
|
8413
8428
|
id: { type: string }
|
|
8414
8429
|
name: { type: string }
|
|
8430
|
+
workPositions:
|
|
8431
|
+
type: array
|
|
8432
|
+
description: "Meta only. Job title entities from /v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments."
|
|
8433
|
+
items:
|
|
8434
|
+
type: object
|
|
8435
|
+
required: [id]
|
|
8436
|
+
properties:
|
|
8437
|
+
id: { type: string }
|
|
8438
|
+
name: { type: string }
|
|
8439
|
+
workEmployers:
|
|
8440
|
+
type: array
|
|
8441
|
+
description: "Meta only. Employer entities from /v1/ads/targeting/search?dimension=workEmployer."
|
|
8442
|
+
items:
|
|
8443
|
+
type: object
|
|
8444
|
+
required: [id]
|
|
8445
|
+
properties:
|
|
8446
|
+
id: { type: string }
|
|
8447
|
+
name: { type: string }
|
|
8448
|
+
workIndustries:
|
|
8449
|
+
type: array
|
|
8450
|
+
description: "Meta only. Work-industry entities from /v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments."
|
|
8451
|
+
items:
|
|
8452
|
+
type: object
|
|
8453
|
+
required: [id]
|
|
8454
|
+
properties:
|
|
8455
|
+
id: { type: string }
|
|
8456
|
+
name: { type: string }
|
|
8415
8457
|
industries: { type: array, items: { type: string }, description: "LinkedIn B2B only. Industry URN id fragments." }
|
|
8416
8458
|
companySizes: { type: array, items: { type: string }, description: "LinkedIn B2B only." }
|
|
8417
8459
|
seniorities: { type: array, items: { type: string }, description: "LinkedIn B2B only." }
|
|
8418
8460
|
jobFunctions: { type: array, items: { type: string }, description: "LinkedIn B2B only." }
|
|
8419
|
-
audienceInclude: { type: array, items: { type: string }, description: 'Platform audience IDs to include
|
|
8420
|
-
audienceExclude: { type: array, items: { type: string }, description: 'Platform audience IDs to exclude. Not supported on
|
|
8461
|
+
audienceInclude: { type: array, items: { type: string }, description: 'Platform audience IDs to include, as returned by GET /v1/ads/audiences (Meta custom audience ids, TikTok audience ids, Pinterest customer list ids, LinkedIn segment ids (bare, urn:li:adSegment or urn:li:dmpSegment forms accepted), Google user list ids, X custom audience ids). Not supported on OpenAI (400).' }
|
|
8462
|
+
audienceExclude: { type: array, items: { type: string }, description: 'Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400).' }
|
|
8421
8463
|
Ad:
|
|
8422
8464
|
type: object
|
|
8423
8465
|
properties:
|
|
@@ -9496,8 +9538,11 @@ webhooks:
|
|
|
9496
9538
|
description: |
|
|
9497
9539
|
Fired when a message is sent via the API, or from the WhatsApp Business app on
|
|
9498
9540
|
Coexistence numbers. Sends that carry platform-specific context deliver it under
|
|
9499
|
-
`metadata`, so a quote-reply
|
|
9500
|
-
CRMs can thread it without a lookup.
|
|
9541
|
+
`metadata`, so a quote-reply sent through the API arrives with
|
|
9542
|
+
`metadata.quotedMessageId` and mirroring CRMs can thread it without a lookup.
|
|
9543
|
+
Which surfaces actually carry that reference is documented on
|
|
9544
|
+
`WebhookPayloadMessageSent.metadata.quotedMessageId`; a quote-reply sent from
|
|
9545
|
+
the WhatsApp Business or Instagram app is not one of them.
|
|
9501
9546
|
tags: [Webhook Events]
|
|
9502
9547
|
requestBody:
|
|
9503
9548
|
required: true
|
|
@@ -26846,7 +26891,16 @@ paths:
|
|
|
26846
26891
|
items:
|
|
26847
26892
|
type: object
|
|
26848
26893
|
properties:
|
|
26849
|
-
id:
|
|
26894
|
+
id:
|
|
26895
|
+
type: string
|
|
26896
|
+
description: |
|
|
26897
|
+
The platform's own message id: the `wamid` on WhatsApp, the
|
|
26898
|
+
`mid` on Instagram and Facebook Messenger. This is what
|
|
26899
|
+
`metadata.quotedMessageId` points at, the value to pass as
|
|
26900
|
+
`replyTo` on the platforms that support quote-replies, and the
|
|
26901
|
+
`{messageId}` segment of the attachment-resolve URL. Webhooks
|
|
26902
|
+
deliver the same value as `message.platformMessageId`; this
|
|
26903
|
+
response has no field by that name.
|
|
26850
26904
|
conversationId: { type: string }
|
|
26851
26905
|
accountId: { type: string }
|
|
26852
26906
|
platform: { type: string }
|
|
@@ -26941,7 +26995,8 @@ paths:
|
|
|
26941
26995
|
type: object
|
|
26942
26996
|
description: |
|
|
26943
26997
|
Platform-specific extras. Free-form, but commonly includes:
|
|
26944
|
-
`quotedMessageId` (
|
|
26998
|
+
`quotedMessageId` (the `id` of the message this one replies to,
|
|
26999
|
+
delivered as `message.platformMessageId` on webhooks),
|
|
26945
27000
|
`waInteractive` (a compact descriptor of WhatsApp interactive
|
|
26946
27001
|
content sent: buttons / list / cta_url / flow / location_request),
|
|
26947
27002
|
and for inbound interactive taps `interactiveType` / `interactiveId`.
|
|
@@ -27478,7 +27533,7 @@ paths:
|
|
|
27478
27533
|
description: Facebook message tag for messaging outside 24h window. Requires messagingType MESSAGE_TAG. Instagram only supports HUMAN_AGENT.
|
|
27479
27534
|
replyTo:
|
|
27480
27535
|
type: string
|
|
27481
|
-
description: 'Platform message ID to quote-reply to. For WhatsApp, pass the wamid; for Telegram, the Telegram message ID (
|
|
27536
|
+
description: 'Platform message ID to quote-reply to. For WhatsApp, pass the wamid; for Telegram, the Telegram message ID (delivered as message.platformMessageId on webhooks, and as `id` on each entry of the list-messages endpoint). On Slack it threads the reply (thread_ts) instead of quoting. Silently ignored on platforms without send-side reply support, including Instagram and Facebook Messenger (Meta''s Send API rejects reply_to on Instagram and does not expose it on Messenger).'
|
|
27482
27537
|
location:
|
|
27483
27538
|
type: object
|
|
27484
27539
|
description: WhatsApp-only. Send a location pin.
|
|
@@ -27568,7 +27623,7 @@ paths:
|
|
|
27568
27623
|
description: Message tag (requires messagingType MESSAGE_TAG)
|
|
27569
27624
|
replyTo:
|
|
27570
27625
|
type: string
|
|
27571
|
-
description: 'Platform message ID to quote-reply to. For WhatsApp, pass the wamid; for Telegram, the Telegram message ID (
|
|
27626
|
+
description: 'Platform message ID to quote-reply to. For WhatsApp, pass the wamid; for Telegram, the Telegram message ID (delivered as message.platformMessageId on webhooks, and as `id` on each entry of the list-messages endpoint). On Slack it threads the reply (thread_ts) instead of quoting. Silently ignored on platforms without send-side reply support, including Instagram and Facebook Messenger (Meta''s Send API rejects reply_to on Instagram and does not expose it on Messenger).'
|
|
27572
27627
|
voiceNote:
|
|
27573
27628
|
type: string
|
|
27574
27629
|
enum: ['true']
|
|
@@ -40209,6 +40264,7 @@ paths:
|
|
|
40209
40264
|
- { name: pageId, in: query, schema: { type: string }, description: "Meta only: Facebook Page ID. Returns only ads whose creative is backed by this Page (a Meta ad account serves ads for every Page in the Business Manager). Matches each ad's `creative.pageId`; ads with no page signal (rare IG-only creatives) never match. Mirrors the same filter on /v1/ads/campaigns and /v1/ads/tree." }
|
|
40210
40265
|
- { name: profileId, in: query, schema: { type: string }, description: Profile ID }
|
|
40211
40266
|
- { name: campaignId, in: query, schema: { type: string }, description: Platform campaign ID (filter ads within a campaign) }
|
|
40267
|
+
- { name: adSetId, in: query, schema: { type: string }, description: "Platform ad set ID (filter ads within an ad set, the /{adset_id}/ads read of an adset-centric dashboard)." }
|
|
40212
40268
|
- { name: platformAdId, in: query, schema: { type: string }, description: "Meta ad ID. Returns the ad with this platform-side ad ID." }
|
|
40213
40269
|
- { name: effectiveObjectStoryId, in: query, schema: { type: string }, description: "Facebook `{pageId}_{postId}` of the post the ad's engagement lives on (Meta `effective_object_story_id`). Use to map a Business-Manager-visible post back to the Zernio ad." }
|
|
40214
40270
|
- { name: effectiveInstagramMediaId, in: query, schema: { type: string }, description: "Instagram media ID of the boosted post (Meta `effective_instagram_media_id`). Use to map a Business-Manager-visible IG post back to the Zernio ad." }
|
|
@@ -41589,24 +41645,37 @@ paths:
|
|
|
41589
41645
|
creative:
|
|
41590
41646
|
type: object
|
|
41591
41647
|
description: |
|
|
41592
|
-
Replace the ad's creative. Meta, TikTok, and LinkedIn.
|
|
41593
|
-
|
|
41594
|
-
- **Meta**:
|
|
41595
|
-
|
|
41596
|
-
|
|
41648
|
+
Replace or patch the ad's creative. Meta, TikTok, and LinkedIn.
|
|
41649
|
+
|
|
41650
|
+
- **Meta**: patch-style. Pass any subset — fields you omit are preserved from the
|
|
41651
|
+
live creative, including media (`image_hash`/`video_id` are reused, no re-upload)
|
|
41652
|
+
and `url_tags`. Sending the full set (`headline`, `body`, `callToAction`,
|
|
41653
|
+
`linkUrl`, `imageUrl`) rebuilds the creative from scratch instead. Partial
|
|
41654
|
+
patching reads the live `object_story_spec`, which Meta strips on SHARE /
|
|
41655
|
+
page-post / dark / asset_feed creatives — those return 422 asking for the full
|
|
41656
|
+
set. A `videoUrl`/`videoId` on an image creative is a type change and also
|
|
41657
|
+
needs the full set. `existingCreativeId` repoints the ad at a creative from
|
|
41658
|
+
GET /v1/ads/creatives and ignores every other field. Meta creatives are
|
|
41659
|
+
immutable, so any change creates a new creative and repoints the ad; the old
|
|
41660
|
+
creative is retained on the ad account for historical reporting.
|
|
41597
41661
|
- **TikTok**: patch-style. Pass any subset; `headline` is ignored (TikTok creatives
|
|
41598
41662
|
have no headline slot). `body` becomes the in-feed `ad_text`; `linkUrl` becomes
|
|
41599
|
-
`landing_page_url`; `videoUrl` triggers a fresh upload.
|
|
41663
|
+
`landing_page_url`; `videoUrl` triggers a fresh upload. `description`, `videoId`
|
|
41664
|
+
and `existingCreativeId` are Meta-only and return 400.
|
|
41600
41665
|
- **LinkedIn**: uploads new media (image via `imageUrl` or video via `videoUrl`),
|
|
41601
41666
|
creates a new inline media creative on the same campaign, and pauses the old
|
|
41602
41667
|
creative (best-effort). The old creative is retained for historical reporting.
|
|
41668
|
+
`videoId` and `existingCreativeId` are Meta-only and return 400.
|
|
41603
41669
|
properties:
|
|
41604
|
-
headline: { type: string, description: "Meta
|
|
41670
|
+
headline: { type: string, description: "Meta and LinkedIn (TikTok has no headline slot)" }
|
|
41605
41671
|
body: { type: string }
|
|
41672
|
+
description: { type: string, maxLength: 255, description: "Link description slot (Meta `link_data.description` / `video_data.link_description`, LinkedIn creative description)." }
|
|
41606
41673
|
callToAction: { type: string }
|
|
41607
41674
|
linkUrl: { type: string, format: uri }
|
|
41608
41675
|
imageUrl: { type: string, format: uri }
|
|
41609
41676
|
videoUrl: { type: string, format: uri }
|
|
41677
|
+
videoId: { type: string, description: "Meta only. Reuse an already-uploaded ad video (from POST /v1/ads/videos or GET /v1/ads/videos) instead of re-uploading via videoUrl." }
|
|
41678
|
+
existingCreativeId: { type: string, description: "Meta only. Repoint the ad at an existing library creative (from GET /v1/ads/creatives); all other creative fields are ignored." }
|
|
41610
41679
|
name: { type: string, maxLength: 255, description: "Rename the ad. Now propagated to Meta (POST /{ad-id}); non-Meta platforms return 501." }
|
|
41611
41680
|
responses:
|
|
41612
41681
|
'200':
|
|
@@ -44277,6 +44346,33 @@ paths:
|
|
|
44277
44346
|
properties:
|
|
44278
44347
|
id: { type: string }
|
|
44279
44348
|
name: { type: string }
|
|
44349
|
+
workPositions:
|
|
44350
|
+
type: array
|
|
44351
|
+
description: "Meta only. Job title entities from /v1/ads/targeting/search?dimension=workPosition. Each must include id. Rejected on other platforms (use LinkedIn's `jobTitles` there)."
|
|
44352
|
+
items:
|
|
44353
|
+
type: object
|
|
44354
|
+
required: [id]
|
|
44355
|
+
properties:
|
|
44356
|
+
id: { type: string }
|
|
44357
|
+
name: { type: string }
|
|
44358
|
+
workEmployers:
|
|
44359
|
+
type: array
|
|
44360
|
+
description: "Meta only. Employer entities from /v1/ads/targeting/search?dimension=workEmployer. Each must include id."
|
|
44361
|
+
items:
|
|
44362
|
+
type: object
|
|
44363
|
+
required: [id]
|
|
44364
|
+
properties:
|
|
44365
|
+
id: { type: string }
|
|
44366
|
+
name: { type: string }
|
|
44367
|
+
workIndustries:
|
|
44368
|
+
type: array
|
|
44369
|
+
description: "Meta only. Work-industry entities from /v1/ads/targeting/search?dimension=workIndustry. Each must include id. Rejected on other platforms (use LinkedIn's `industries` there)."
|
|
44370
|
+
items:
|
|
44371
|
+
type: object
|
|
44372
|
+
required: [id]
|
|
44373
|
+
properties:
|
|
44374
|
+
id: { type: string }
|
|
44375
|
+
name: { type: string }
|
|
44280
44376
|
incomeTier:
|
|
44281
44377
|
type: string
|
|
44282
44378
|
enum: [top_5, top_10, top_10_25, top_25_50]
|
|
@@ -45623,8 +45719,13 @@ paths:
|
|
|
45623
45719
|
`POST /v1/ads/targeting/reach-estimate`, and `saved_targeting` audiences.
|
|
45624
45720
|
|
|
45625
45721
|
The `dimension` param selects what is searched, `geo` (locations, further scoped
|
|
45626
|
-
by `geoType`), `interest`, `behavior`,
|
|
45627
|
-
|
|
45722
|
+
by `geoType`), `interest`, `behavior`, `income`, or the Meta-only work
|
|
45723
|
+
demographics `workPosition`, `workEmployer` and `workIndustry` (their ids feed
|
|
45724
|
+
`TargetingSpec.workPositions`/`workEmployers`/`workIndustries`). Availability of
|
|
45725
|
+
each dimension varies by platform (e.g. behaviours are Meta/TikTok only).
|
|
45726
|
+
Work industries are a fixed ~30-entry Meta catalog with no server-side query,
|
|
45727
|
+
so `workIndustry` matching, ranking and `limit` happen in Zernio.
|
|
45728
|
+
Results are normalized
|
|
45628
45729
|
across platforms into a single shape, so the same client code consumes Meta,
|
|
45629
45730
|
TikTok, LinkedIn, X, Pinterest, and Google results.
|
|
45630
45731
|
|
|
@@ -45674,7 +45775,7 @@ paths:
|
|
|
45674
45775
|
parameters:
|
|
45675
45776
|
- { name: accountId, in: query, required: true, schema: { type: string }, description: "Social account ID (a connected account on the target ad platform)." }
|
|
45676
45777
|
- { name: q, in: query, required: true, schema: { type: string }, description: "Search query. For geo, the locality name only (no region/country suffix)." }
|
|
45677
|
-
- { name: dimension, in: query, required: false, schema: { type: string, enum: [geo, interest, behavior, income], default: interest }, description: "What to search. `geo` resolves locations (scope further with `geoType`), `interest`/`behavior` resolve audience entities, `income` resolves income-tier options. Defaults to `interest` for backward compatibility with the deprecated /v1/ads/interests alias." }
|
|
45778
|
+
- { name: dimension, in: query, required: false, schema: { type: string, enum: [geo, interest, behavior, income, workPosition, workEmployer, workIndustry], default: interest }, description: "What to search. `geo` resolves locations (scope further with `geoType`), `interest`/`behavior` resolve audience entities, `income` resolves income-tier options, `workPosition`/`workEmployer`/`workIndustry` resolve Meta work demographics. Defaults to `interest` for backward compatibility with the deprecated /v1/ads/interests alias." }
|
|
45678
45779
|
- { name: geoType, in: query, required: false, schema: { type: string, enum: [all, country, region, city, subcity, neighborhood, place, zip, metro_area, geo_market], default: city }, description: "Only used when `dimension=geo`. The kind of location to resolve. `all` searches every type in one relevance-ranked call. Defaults to `city`." }
|
|
45679
45780
|
- { name: countryCode, in: query, required: false, schema: { type: string, minLength: 2, maxLength: 2 }, description: "ISO 3166-1 alpha-2 country code (e.g. NL) to scope a geo search." }
|
|
45680
45781
|
- { name: limit, in: query, required: false, schema: { type: integer, minimum: 1, maximum: 100, default: 25 }, description: "Maximum results to return." }
|
|
@@ -306,6 +306,7 @@ describe 'AdCampaignsApi' do
|
|
|
306
306
|
# @option opts [String] :page_id Meta only: Facebook Page ID. Returns only ads whose creative is backed by this Page (a Meta ad account serves ads for every Page in the Business Manager). Matches each ad's `creative.pageId`; ads with no page signal (rare IG-only creatives) never match. Mirrors the same filter on /v1/ads/campaigns and /v1/ads/tree.
|
|
307
307
|
# @option opts [String] :profile_id Profile ID
|
|
308
308
|
# @option opts [String] :campaign_id Platform campaign ID (filter ads within a campaign)
|
|
309
|
+
# @option opts [String] :ad_set_id Platform ad set ID (filter ads within an ad set, the /{adset_id}/ads read of an adset-centric dashboard).
|
|
309
310
|
# @option opts [String] :platform_ad_id Meta ad ID. Returns the ad with this platform-side ad ID.
|
|
310
311
|
# @option opts [String] :effective_object_story_id Facebook `{pageId}_{postId}` of the post the ad's engagement lives on (Meta `effective_object_story_id`). Use to map a Business-Manager-visible post back to the Zernio ad.
|
|
311
312
|
# @option opts [String] :effective_instagram_media_id Instagram media ID of the boosted post (Meta `effective_instagram_media_id`). Use to map a Business-Manager-visible IG post back to the Zernio ad.
|
|
@@ -83,11 +83,11 @@ describe 'AdTargetingApi' do
|
|
|
83
83
|
|
|
84
84
|
# unit tests for search_ad_targeting
|
|
85
85
|
# Search targeting options
|
|
86
|
-
# Resolve a human-readable query into the platform's opaque targeting ids used in the `TargetingSpec` (`countries`/`regions`/`cities`/`zips`/`metros` geo keys, and `interests`/`behaviors` entity ids) on `POST /v1/ads/create`, `POST /v1/ads/targeting/reach-estimate`, and `saved_targeting` audiences. The `dimension` param selects what is searched, `geo` (locations, further scoped by `geoType`), `interest`, `behavior`, or `
|
|
86
|
+
# Resolve a human-readable query into the platform's opaque targeting ids used in the `TargetingSpec` (`countries`/`regions`/`cities`/`zips`/`metros` geo keys, and `interests`/`behaviors` entity ids) on `POST /v1/ads/create`, `POST /v1/ads/targeting/reach-estimate`, and `saved_targeting` audiences. The `dimension` param selects what is searched, `geo` (locations, further scoped by `geoType`), `interest`, `behavior`, `income`, or the Meta-only work demographics `workPosition`, `workEmployer` and `workIndustry` (their ids feed `TargetingSpec.workPositions`/`workEmployers`/`workIndustries`). Availability of each dimension varies by platform (e.g. behaviours are Meta/TikTok only). Work industries are a fixed ~30-entry Meta catalog with no server-side query, so `workIndustry` matching, ranking and `limit` happen in Zernio. Results are normalized across platforms into a single shape, so the same client code consumes Meta, TikTok, LinkedIn, X, Pinterest, and Google results. TikTok geo searches return every matching level in one list (`type` is `country`, `region`, `city`, `district`, or `metro` for DMA areas) — `geoType` is not applied. Results are scoped to the advertiser's targetable markets, and every id is usable in `regions`/`cities`/`metros` keys on `POST /v1/ads/create`. LinkedIn geo searches also return every matching level in one list, and neither `geoType` nor `countryCode` is applied: LinkedIn's typeahead only returns a name and a URN per result, with no level or country field to filter on. Every result has `type` set to `location`, and its id is a `urn:li:geo:*` URN usable as a `regions[].key` on `POST /v1/ads/create`, `POST /v1/ads/boost` and `POST /v1/ads/targeting/reach-estimate`. Google geo searches resolve against Google's geoTargetConstants and return every matching level in one list; `geoType` is not applied (Google's `target_type` is an open taxonomy that does not map one-to-one onto the `geoType` enum), so filter client-side on the returned `type` (`country`, `region`, `city`, `zip`, `metro`, or the lowercased Google target type for rarer levels). `countryCode` scopes the search to one country. Each id is Google's numeric criterion id, usable as a `regions`/`cities`/`zips`/`metros` `key` on `POST /v1/ads/create`. Google city radius is not supported (pass a `customLocations` lat/lng pin for a radius); country targeting also accepts plain ISO codes via `countries` with no search call. Pinterest resolves against three whole-catalog endpoints (interests, locations, regions) with no server-side query or pagination, so matching, ranking and the `limit` cutoff all happen in Zernio; the catalog is independent of any ad account and results never carry `audienceSize`. Names come back localized to the connected Pinterest account's language (there is no way to force a locale), so match against whatever language that account returns. `geoType` routes to a different catalog: `country` and `metro_area` read the locations catalog (`type` is `country` or `metro`); `region` reads the regions catalog (`type` is `region`, its id a `regions[].key` on `POST /v1/ads/create`); `all` and the default `city` merge both catalogs with honest per-entry `type`s, since Pinterest has no city-level catalog and `city` is an alias for `all`, not a literal city search. `zip`, `subcity`, `neighborhood`, `place` and `geo_market` return a 400: Pinterest exposes no postal-code catalog, pass postal codes directly as `targeting.zips: [{ key }]` on `POST /v1/ads/create`. For geo queries, `q` should contain only the locality name (e.g. `\"Amsterdam\"`, not `\"Amsterdam, NL\"`). Use `countryCode` to disambiguate.
|
|
87
87
|
# @param account_id Social account ID (a connected account on the target ad platform).
|
|
88
88
|
# @param q Search query. For geo, the locality name only (no region/country suffix).
|
|
89
89
|
# @param [Hash] opts the optional parameters
|
|
90
|
-
# @option opts [String] :dimension What to search. `geo` resolves locations (scope further with `geoType`), `interest`/`behavior` resolve audience entities, `income` resolves income-tier options. Defaults to `interest` for backward compatibility with the deprecated /v1/ads/interests alias.
|
|
90
|
+
# @option opts [String] :dimension What to search. `geo` resolves locations (scope further with `geoType`), `interest`/`behavior` resolve audience entities, `income` resolves income-tier options, `workPosition`/`workEmployer`/`workIndustry` resolve Meta work demographics. Defaults to `interest` for backward compatibility with the deprecated /v1/ads/interests alias.
|
|
91
91
|
# @option opts [String] :geo_type Only used when `dimension=geo`. The kind of location to resolve. `all` searches every type in one relevance-ranked call. Defaults to `city`.
|
|
92
92
|
# @option opts [String] :country_code ISO 3166-1 alpha-2 country code (e.g. NL) to scope a geo search.
|
|
93
93
|
# @option opts [Integer] :limit Maximum results to return.
|
|
@@ -357,6 +357,24 @@ describe Zernio::CreateStandaloneAdRequest do
|
|
|
357
357
|
end
|
|
358
358
|
end
|
|
359
359
|
|
|
360
|
+
describe 'test attribute "work_positions"' do
|
|
361
|
+
it 'should work' do
|
|
362
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
describe 'test attribute "work_employers"' do
|
|
367
|
+
it 'should work' do
|
|
368
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
describe 'test attribute "work_industries"' do
|
|
373
|
+
it 'should work' do
|
|
374
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
|
|
360
378
|
describe 'test attribute "income_tier"' do
|
|
361
379
|
it 'should work' do
|
|
362
380
|
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
@@ -119,6 +119,24 @@ describe Zernio::TargetingSpec do
|
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
+
describe 'test attribute "work_positions"' do
|
|
123
|
+
it 'should work' do
|
|
124
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
describe 'test attribute "work_employers"' do
|
|
129
|
+
it 'should work' do
|
|
130
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
describe 'test attribute "work_industries"' do
|
|
135
|
+
it 'should work' do
|
|
136
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
122
140
|
describe 'test attribute "industries"' do
|
|
123
141
|
it 'should work' do
|
|
124
142
|
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
@@ -39,6 +39,12 @@ describe Zernio::UpdateAdRequestCreative do
|
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
describe 'test attribute "description"' do
|
|
43
|
+
it 'should work' do
|
|
44
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
42
48
|
describe 'test attribute "call_to_action"' do
|
|
43
49
|
it 'should work' do
|
|
44
50
|
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
@@ -63,4 +69,16 @@ describe Zernio::UpdateAdRequestCreative do
|
|
|
63
69
|
end
|
|
64
70
|
end
|
|
65
71
|
|
|
72
|
+
describe 'test attribute "video_id"' do
|
|
73
|
+
it 'should work' do
|
|
74
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe 'test attribute "existing_creative_id"' do
|
|
79
|
+
it 'should work' do
|
|
80
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
66
84
|
end
|