Extension · moselwal/semantic-delivery · MIT

semantic-delivery — one piece of content, eleven distributors.

Schema.org enrichment and multichannel distribution for TYPO3 14. Six native platform adapters (LinkedIn, X/Twitter, Instagram, Facebook, Bluesky, Dev.to) plus five proxy adapters (Ayrshare, Buffer, n8n, Late.dev, Webhook). Per-page platform selection, backend module, CLI commands. MIT licence.

Die Realität

Multichannel distribution usually ends in a copy-paste loop.

With semantic-delivery

  • Auto-generation of Schema.org JSON-LD from content models
  • Channel transformer per channel (Web/AI/Voice/Social) with character-limit awareness
  • Direct distribution on 6 platforms, proxy distribution on 5 more
  • OAuth tokens AES-256-CBC encrypted in the backend, with refresh flow
  • Dev.to cross-posting with canonical URL attribution
  • Podcast episode detection with automatic job creation
  • Per-page platform selection in the backend — only configured platforms visible

Until now

  • Manual adjustment per channel, each with its own character limits
  • JSON-LD writing in the template
  • No channel detection in the frontend (Web vs AI Agent vs Voice)
  • OAuth token management as a side project with plain-text storage
  • Cross-posting in blog platforms without canonical attribution
  • Podcast episode detection as a cron-job hack

Four core building blocks

Channel detection middleware

Detects from headers / user-agent / Accept whether the request is coming from an AI agent, voice assistant, social crawler, or browser — and serves the appropriate format.

Distributor architecture

Auto-discovery via Symfony DI. Custom distributors implement DistributorInterface and appear automatically in the page editor as soon as the related site credentials are configured.

Channel transformer

One transformer per channel: Web/AI Agent/Voice/Social Media. Trim to platform limits (e.g. 280 characters X, 300 graphemes Bluesky), tonality adjustment, asset selection.

Schema.org enrichment

JSON-LD is generated automatically from the content model: Article, BlogPosting, NewsArticle, FAQPage, Product, HowTo, Organization, LocalBusiness. Auto-detect with manual override per page.

Installation: composer require moselwal/semantic-delivery · MIT licence

TYPO3: 14.0 · PHP: 8.2+ · Licence: MIT · Suggested:moselwal/content-intelligence (AI-driven social transformation), moselwal/secret-resolver (%secret()% syntax for platform tokens)

Add the Composer repository at gitlab.moselwal.io, then run composer require moselwal/semantic-delivery. Afterwards vendor/bin/typo3 database:updateschema.

02 — Plattformen

Eleven distributors in three categories

Six platforms are served directly through their native APIs (direct distribution); one of these is a long-form blog platform with canonical attribution. Five more run via established proxy services — useful if, for example, you already use Buffer or Ayrshare.

Proxy services

  • Ayrshare — API Key
  • Buffer — Access Token
  • n8n — Webhook URL
  • Late.dev — API Key
  • Generic Webhook — Custom URL
Proxy

Long-form blog

  • Dev.to — API Key · Markdown format

Automatically sets a canonical URL back to the original TYPO3 page — no SEO penalty for cross-posting.

Direct

Social Media (short-form)

  • Bluesky — App Password · 300 graphemes
  • LinkedIn — OAuth 2.0 · 3,000 characters
  • X / Twitter — Bearer Token · 280 characters
  • Instagram — Page Access Token · 2,200 characters
  • Facebook — Page Access Token · 63,000 characters
Direct
03 — Backend & Operations

Backend, CLI and operations

semantic-delivery does not ship with backend extensions that nobody uses — the backend module is editor-ready from the start, the CLI commands are cron-friendly, and the OAuth service stores tokens AES-256-CBC encrypted.

DDD + tests

4-layer DDD (Domain / Application / Infrastructure / Presentation), strictly enforced via deptrac. PHPStan Level 8, PER-CS3x0, PHPUnit unit + functional tests. Four database tables (channel_content, distribution_job, schema_cache, oauth_token).

OAuth token service

For platforms with OAuth 2.0 + refresh: tokens are stored AES-256-CBC encrypted in the backend (TYPO3 encryption key). API for storage, lookup, refresh, and expiry check is in the service container.

CLI commands

semantic-delivery:detect-episodes detects new podcast episodes and creates distribution jobs (with --dry-run and --auto-publish). semantic-delivery:process-jobs works the queue.

Backend module

Under Content → Semantic Delivery (admin access): per-platform preview before publish, job queue management, log with external URLs of successful distributions. Per-page "Semantic Delivery" tab with platform checkbox list.

Database and page fields

Tables

TablePurpose
tx_semanticdelivery_channel_contentChannel-specific content variants
tx_semanticdelivery_distribution_jobDistribution job queue
tx_semanticdelivery_schema_cacheCached Schema.org data
tx_semanticdelivery_oauth_tokenEncrypted platform OAuth tokens

Page fields

FieldTypeDescription
tx_semanticdelivery_schema_typeSelectSchema.org type override (auto-detect by default)
tx_semanticdelivery_channelsCheckBoxDelivery channels (Website, AI Agent, Voice, Social Media)
tx_semanticdelivery_distribution_enabledCheckEnable distribution for this page
tx_semanticdelivery_distribution_platformsCheckBoxTarget platforms (dynamically populated)

The platform selector only shows platforms with credentials configured for the current site. This stops editors from picking targets that would fail.

Supported platforms

Social media (short-form)

PlatformDistributorAuthLimit
BlueskyBlueskyDistributorApp Password300 graphemes
LinkedInLinkedInDistributorOAuth 2.0 Access Token3,000 chars
X/TwitterTwitterXDistributorBearer Token280 chars
InstagramInstagramDistributorPage Access Token2,200 chars
FacebookFacebookDistributorPage Access Token63,000 chars

Blog platforms (long-form)

PlatformDistributorAuthFormat
Dev.toDevToDistributorAPI KeyMarkdown

Blog distributors automatically set a canonical URL back to the original TYPO3 page. Note: Medium has discontinued issuing new API tokens; the MediumDistributor has been removed.

Proxy services

PlatformDistributorAuth
AyrshareAyrshareDistributorAPI Key
BufferBufferDistributorAccess Token
n8nN8nDistributorWebhook URL
Late.devLateDevDistributorAPI Key
Generic WebhookWebhookDistributorCustom URL

Setup

1. Enable distribution in site settings

 

semanticDelivery:
  channels:
    socialMedia:
      enabled: true
  distribution:
    enabled: true
    defaultDistributor: 'bluesky'

 

2. Configure platform credentials

Credentials sit per site in config/sites/<name>/config.yaml. Sensitive tokens use the %secret()% syntax (see moselwal/secret-resolver); public identifiers go directly into the YAML.

Only platforms with a non-empty primary credential appear in the backend editor. Platforms without credentials are hidden, so editors cannot select targets that would fail.

3. Run the database schema update

 

vendor/bin/typo3 database:updateschema

 

4. Per-page platform selection

In the TYPO3 backend, every page has a Semantic Delivery tab:

  1. Enable Distribution
  2. Pick the target platforms (only configured ones appear)
  3. Save and publish

The distribution system honours this choice — pages are only sent to the platforms you ticked.

CLI, backend module and extension

CLI commands

 

# Detect new podcast episodes
vendor/bin/typo3 semantic-delivery:detect-episodes --dry-run
vendor/bin/typo3 semantic-delivery:detect-episodes
vendor/bin/typo3 semantic-delivery:detect-episodes --auto-publish

# Process pending jobs
vendor/bin/typo3 semantic-delivery:process-jobs

 

Recommended cron

 

*/15 * * * * cd /app && vendor/bin/typo3 semantic-delivery:detect-episodes
*/5  * * * * cd /app && vendor/bin/typo3 semantic-delivery:process-jobs

 

Backend module

Available under Content → Semantic Delivery (admin access):

Adding a distributor

  1. Create a class implementing DistributorInterface in Classes/Infrastructure/Distribution/
  2. Optionally add a TransformerInterface in Classes/Infrastructure/Transformer/
  3. Register the credential mapping in DistributionPlatformItemsProcFunc::CREDENTIAL_KEYS
  4. Add the corresponding site setting in settings.definitions.yaml and settings.yaml

Once credentials are configured, the platform automatically appears in the page editor. OAuth tokens flow through the OAuthTokenService and are encrypted at rest with AES-256-CBC using the TYPO3 encryption key.

Source code & docs

TYPO3 Extension Repository

Not in the official TER — install via Composer only. Extension key: semantic_delivery.

Composer package

moselwal/semantic-delivery via the Moselwal Composer repo. MIT licence, freely usable.

Open the Composer repo

GitLab (source of truth)

Primary repository including CI/CD, tests, and Composer package registry.

gitlab.moselwal.io/development/moselwal/semantic-delivery

GitHub

GitHub mirror (placeholder — verify before publish).

github.com/moselwal/semantic-delivery
Nächster Schritt

Your platform missing?

Auto-discovery turns adding a new distributor into a question of two classes — implement DistributorInterface, optionally a transformer, add credential mapping in DistributionPlatformItemsProcFunc::CREDENTIAL_KEYS, done. If you want to do it yourself: docs in the repo. If you want us to build it: get in touch.

Custom-Distributor besprechen

Oder direkt schreiben: kontakt@moselwal.de