Search by

silvershop-suite / product-feed-meta

RVXD

Meta (Facebook & Instagram) catalog channel connector for silvershop-suite/product-feed (CMS 6): an RSS 2.0 + g: namespace serializer and field map that turns the shared CatalogProductData into a Meta Commerce catalog feed for Facebook Shops, Instagram Shopping and Advantage+/dynamic ads. Reuses Goo

Package info

github.com/silvershop-suite/silvershop-product-feed-meta

Type:silverstripe-vendormodule

pkg:composer/silvershop-suite/product-feed-meta

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-10-24 12:18 UTC

This package is not auto-updated.

Last update: 2026-10-24 13:29:32 UTC


README

CI

The Meta (Facebook & Instagram) Commerce channel connector for silvershop-suite/product-feed on Silverstripe CMS 6. It plugs a Meta Commerce catalog channel (Facebook Shops, Instagram Shopping, Advantage+/dynamic ads) into the feed core's registry seam: an RSS 2.0 + g: namespace serializer, the CatalogProductData → g:* field map, and a per-category fb_product_category mapping. No core change — the connector registers itself.

product-feed core ──(registry)──▶ MetaChannelFeed.mapItem() ──▶ RssGFormat ──▶ public/feeds/meta.xml
                                   (g: attribute map)            (RSS 2.0 + g:)   served at /feed/meta

Meta's RSS-XML catalog feed deliberately reuses Google Merchant's g: field vocabulary — the RSS root declares xmlns:g="http://base.google.com/ns/1.0" and the item fields are g:-prefixed — so this connector mirrors silvershop-suite/product-feed-google almost verbatim, with a handful of Meta-specific deltas (below). It carries no dependency on the Google connector: it ships its own copy of the RSS+g: serializer.

Requirements

  • PHP 8.3+, silverstripe/framework ^6, silverstripe/cms ^6, silvershop/core ^6.2
  • silvershop-suite/product-feed ^1 (the feed core; pulls in silvershop-suite/catalog-data transitively)

Installation

composer require silvershop-suite/product-feed-meta

Then dev/build?flush=all. This:

  • adds the per-category Meta product category (fb_product_category) field to ProductCategory;
  • registers + enables the meta channel in the feed core (installing the connector means you want the feed).

Mapping categories

Open a product category in the CMS → Meta catalog → paste the category id or full path from Meta's own product taxonomy (Commerce Manager shows it). A sub-category inherits its nearest mapped ancestor, so setting a top-level category is usually enough. A product's g:fb_product_category is resolved from its category's value (walking up the tree).

fb_product_category uses Meta's own taxonomy (distinct ids/paths from Google's). It is optional when g:google_product_category is present (Meta accepts and uses the Google category), so this v1 keeps it a simple free-text field rather than bundling the full Meta taxonomy. If the Google connector is also installed, its google_product_category mapping is reused automatically (see the map below).

Generating & serving

The feed core owns generation, scheduling and serving (see its README). With this connector installed:

  • generate: sake tasks:ProductFeed-Generate --channel=meta (or let the recurring GenerateProductFeedJob do it), written to public/feeds/meta.xml;
  • serve: https://your-shop/feed/meta (the core's serving route) — point Meta Commerce Manager at that URL.

The g: field map

Meta attribute (g:-prefixed in RSS) Source (CatalogProductData unless noted)
g:id feedId() (= Google feed id = Meta Pixel/CAPI content_ids)
title / description / link title() / description() / link()
g:image_link / g:additional_image_link imageLink() / additionalImageLinks()
g:availability availability() → in stock / out of stock / preorder / available for order (space form)
g:price / g:sale_price formattedPrice() / formattedSalePrice() ("12.95 EUR")
g:brand / g:gtin / g:mpn brand() / gtin() / mpn() (gtin/mpn via silvershop-suite/product-identity)
g:condition condition() → new / refurbished / used
g:fb_product_category the per-category Meta value via the category parent-walk
g:google_product_category reused from the Google connector's taxonomy mapping when it is installed (emit_google_product_category, default on)
g:product_type productType() with the site root trimmed (product_type_trim_segments, default 1)
g:item_group_id itemGroupId() (parent product) — variants are separate <item>s sharing it
g:color / g:size matched from attributes() (color_attributes / size_attributes)
g:shipping opt-in (shipping_enabled, default off) from configured flat rates

All text is XML-escaped (XSS-safe) and the document is well-formed RSS 2.0.

Meta deltas vs the Google connector

  • g:availability uses the space form (in stock, not in_stock) — Meta's documented tokens. Backorder maps to Meta's nearest value, available for order (Meta has no backorder).
  • g:identifier_exists is dropped — a Google-only attribute Meta does not document.
  • g:fb_product_category is added (Meta's own taxonomy), while g:google_product_category is reused when the Google connector is present.
  • id / title / description / image limits are all looser on Meta than Google, so the shared VO's caps already satisfy Meta with no truncation divergence.

Config

SilverShop\ProductFeed\Meta\MetaChannelFeed:
  emit_google_product_category: true   # reuse the Google connector's category mapping when installed
  product_type_trim_segments: 1        # drop the catalogue root from g:product_type
  shipping_enabled: false
  shipping:
    - { country: 'NL', service: 'Standard', price: '4.95 EUR' }

Core knobs (output_dir, chunk_size, regenerate_interval_mins, cache_max_age, access_token, reading stage) are inherited from the feed core unchanged.

The content_ids tie

g:id is CatalogProductData::feedId() verbatim — the same shared id the Google feed emits and the same value silvershop-suite/conversion-tracking-meta sends as the Meta Pixel / CAPI content_ids. So the Meta catalog ↔ Pixel/CAPI product matching (and Advantage+/dynamic-ads retargeting) lines up by construction, with no extra configuration — provided feed and tracking read the same catalog-data id_source (they share one factory, so they do). Variants are emitted as separate <item>s sharing g:item_group_id, the shape Meta's product_group events resolve to.

Commerce Manager setup

  1. Create/claim a Catalog in Meta Commerce Manager (plus a Business + verified domain for Shops/checkout).
  2. Catalog → Data sources → Data feed → Use a URL (Scheduled) → https://your-shop/feed/meta → set the fetch interval (minimum once per hour) to match GenerateProductFeedJob.regenerate_interval_mins.
  3. For Advantage+/dynamic ads: connect the catalog to the ad account, and ensure the Pixel (from silvershop-suite/conversion-tracking-meta) is linked to the same catalog so content_ids match.
  4. Map categories (fb_product_category and/or google_product_category) and clear the Commerce Manager diagnostics warnings.

The connector produces a spec-correct feed; catalogue / commerce policy compliance is the merchant's (image rules, prohibited categories, price/availability accuracy). Watch the Commerce Manager diagnostics.

Not in v1

No Graph API / Catalog Batch API / access-token push; no bundled Meta taxonomy tree-picker; no CSV/TSV format; no quantity_to_sell_on_facebook (on-Meta checkout stock level); no material / gender / age_group / video / rich-text. These are designed-for follow-ons — the v1 scheduled-URL RSS feed deliberately needs no secrets.

Licence

BSD-3-Clause.

Credits

Built and maintained by Remy Vaartjes (remy@xd.nl) — part of the SilverShop-Suite.