|
28 | 28 | ) |
29 | 29 |
|
30 | 30 |
|
31 | | -# Breakdowns Meta rejects when combined with the default action_breakdowns |
32 | | -# (which is [action_type]). Picking any of these auto-drops the action-typed |
33 | | -# fields below so the request still succeeds. Meta error path is |
34 | | -# "(#100) Current combination of data breakdown columns (action_type, X) is invalid". |
35 | | -_BREAKDOWNS_INCOMPATIBLE_WITH_ACTION_TYPE = frozenset({ |
36 | | - "platform_position", |
37 | | -}) |
38 | | - |
39 | 31 | # Breakdowns that collide with the default action_breakdowns=[action_type] but |
40 | 32 | # are real Meta fields (so we explicitly clear action_breakdowns instead of |
41 | 33 | # dropping the action-typed response fields). For non-DCO ads this returns |
|
44 | 36 | "media_type", |
45 | 37 | }) |
46 | 38 |
|
47 | | -_ACTION_TYPED_FIELDS = frozenset({ |
48 | | - "actions", |
49 | | - "action_values", |
50 | | - "cost_per_action_type", |
51 | | - "conversions", |
52 | | -}) |
53 | | - |
54 | 39 |
|
55 | 40 | def _strip_redundant_actions(row: dict) -> dict: |
56 | 41 | """Remove redundant action-type entries from a single insight row.""" |
@@ -97,10 +82,10 @@ async def get_insights(object_id: str = "", access_token: Optional[str] = None, |
97 | 82 | Demographic: age, gender, country, region, dma |
98 | 83 | Platform/Device: device_platform, platform_position, publisher_platform, impression_device |
99 | 84 | NOTE: platform_position is a Meta-restricted breakdown — Meta requires it to be paired |
100 | | - with publisher_platform and is incompatible with the default action_breakdowns=[action_type]. |
101 | | - When you pass platform_position, this tool auto-adds publisher_platform and drops the |
102 | | - action-typed fields (actions, action_values, conversions, cost_per_action_type) from the |
103 | | - response. Use publisher_platform alone if you need action data alongside placement. |
| 85 | + with publisher_platform (otherwise "(#100) ... (action_type, platform_position) is invalid"). |
| 86 | + When you pass platform_position, this tool auto-adds publisher_platform, and the |
| 87 | + action-typed fields (actions, action_values, conversions, cost_per_action_type) are |
| 88 | + returned per placement, so you get leads/CPL/conversions broken down by placement. |
104 | 89 | Creative Assets: ad_format_asset, body_asset, call_to_action_asset, description_asset, |
105 | 90 | image_asset, link_url_asset, title_asset, video_asset, media_type, |
106 | 91 | creative_relaxation_asset_type, flexible_format_asset_type, |
@@ -168,17 +153,17 @@ async def get_insights(object_id: str = "", access_token: Optional[str] = None, |
168 | 153 | "unique_clicks", "cost_per_action_type", |
169 | 154 | ] |
170 | 155 |
|
171 | | - # Meta rejects platform_position alone or with the default |
172 | | - # action_breakdowns=[action_type]: it must be paired with publisher_platform, |
173 | | - # and the action-typed fields must be dropped. Auto-fix both so the request |
174 | | - # succeeds with placement-level metrics. |
| 156 | + # Meta rejects platform_position on its own: it must be paired with |
| 157 | + # publisher_platform, otherwise "(#100) Current combination of data breakdown |
| 158 | + # columns (action_type, platform_position) is invalid". Auto-add |
| 159 | + # publisher_platform so the request succeeds with placement-level metrics — |
| 160 | + # including the action-typed fields (actions, cost_per_action_type, etc.), |
| 161 | + # which Meta returns per placement once the pairing is in place. |
175 | 162 | breakdown_values = [b.strip() for b in breakdown.split(",") if b.strip()] if breakdown else [] |
176 | 163 | breakdown_set = set(breakdown_values) |
177 | 164 | if "platform_position" in breakdown_set and "publisher_platform" not in breakdown_set: |
178 | 165 | breakdown_values = ["publisher_platform", *breakdown_values] |
179 | 166 | breakdown_set.add("publisher_platform") |
180 | | - if breakdown_set & _BREAKDOWNS_INCOMPATIBLE_WITH_ACTION_TYPE: |
181 | | - fields = [f for f in fields if f not in _ACTION_TYPED_FIELDS] |
182 | 167 | # media_type collides with action_breakdowns=[action_type] but is a real |
183 | 168 | # field — override action_breakdowns to empty so the request succeeds with |
184 | 169 | # the action-typed metrics intact. |
|
0 commit comments