Social-Media-Beiträge von PHP aus veröffentlichen

Social-Media-Beiträge von PHP aus veröffentlichen

Es gibt kein PHP-SDK, daher geht es hier direkt um die REST-API. Funktionierende cURL- und Guzzle-Beispiele zum Erstellen, Planen und Prüfen von Beiträgen.

Es gibt kein PHP-SDK, daher wird hier direkt die REST-API genutzt. Das ist weniger einschränkend, als es klingt: Die API ist einfaches JSON über HTTPS mit einem Bearer-Token, und PHP hat alles Nötige in der Standardbibliothek.

Wenn du speziell aus WordPress veröffentlichst, gibt es ein Plugin und eine RSS-Route, die weniger Arbeit machen könnten, als das selbst zu schreiben.

Authentifizierung

Jede Anfrage trägt deinen API-Schlüssel als Bearer-Token:

$apiKey = getenv('BULKPUBLISH_API_KEY');
$baseUrl = 'https://app.bulkpublish.com';

Bewahre den Schlüssel in der Umgebung auf, nicht im Quellcode oder einer eingecheckten Konfigurationsdatei.

Einen Entwurf erstellen

$payload = [
    'content'  => 'Check out our latest update!',
    'channels' => [
        ['channelId' => 1, 'platform' => 'x'],
        ['channelId' => 2, 'platform' => 'linkedin'],
    ],
    'status'   => 'draft',
];

$ch = curl_init("$baseUrl/api/posts");
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Content-Type: application/json',
        "Authorization: Bearer $apiKey",
    ],
    CURLOPT_POSTFIELDS     => json_encode($payload),
]);

$response = curl_exec($ch);
$status   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($status >= 400) {
    error_log("BulkPublish error $status: $response");
} else {
    $post = json_decode($response, true);
}

Fang mit draft an. Er erscheint in der App, sodass du sehen kannst, was dein Code erzeugt hat, bevor irgendetwas veröffentlicht wird.

Dasselbe mit Guzzle

Wenn du Guzzle schon hast, ist es aufgeräumter:

use GuzzleHttp\Client;

$client = new Client([
    'base_uri' => 'https://app.bulkpublish.com',
    'headers'  => [
        'Authorization' => 'Bearer ' . getenv('BULKPUBLISH_API_KEY'),
        'Content-Type'  => 'application/json',
    ],
]);

$response = $client->post('/api/posts', [
    'json' => [
        'content'     => 'Check out our new feature!',
        'channels'    => [['channelId' => 1, 'platform' => 'instagram']],
        'status'      => 'scheduled',
        'scheduledAt' => '2026-04-10T14:00:00Z',
        'timezone'    => 'America/New_York',
    ],
]);

$post = json_decode((string) $response->getBody(), true);

Kanal-IDs finden

$response = $client->get('/api/channels');
$channels = json_decode((string) $response->getBody(), true);

Schlag sie nach oder halte sie in der Konfiguration fest. Eine ID aus einem einmaligen Skript in etwas Langlebiges fest einzubauen, ist der Weg, auf dem ein Deploy anfängt, auf das falsche Konto zu posten.

Planungsfelder

scheduledAt ist ein ISO-8601-Zeitstempel und timezone ein IANA-Name. Gib die Zeitzone bei allem Wiederkehrenden explizit an, sonst verschiebt sich deine Veröffentlichungszeit bei der Zeitumstellung um eine Stunde.

Fehler richtig behandeln

Der Fehlermodus, der spezifisch für serverseitige Veröffentlichung ist: Niemand schaut zu. Ein Beitrag, der um 3 Uhr nachts die Validierung nicht besteht, bleibt still, wenn du ihn nicht selbst laut gemacht hast.

  • Statuscodes prüfen, nicht davon ausgehen, dass ein Antwortkörper Erfolg bedeutet
  • Den Antwortkörper bei Fehlern protokollieren, denn er sagt, was falsch war
  • Ratenlimits respektieren und zurückhaltend statt sofort erneut versuchen
FreeProBusiness
API-Anfragen/Tag305.00050.000
API-Schlüssel1510
Die 30 pro Tag bei Free sind zum Ausprobieren gedacht. Alles, was nach Zeitplan läuft, braucht einen bezahlten Tarif.

Die Kurzfassung

Kein SDK nötig. POST JSON an /api/posts mit einem Bearer-Token, content, channels und einem status. Fang mit Entwürfen an, schlag Kanal-IDs nach, gib bei geplanten Beiträgen eine Zeitzone an und protokolliere Fehler ordentlich, denn serverseitige Veröffentlichung scheitert standardmäßig lautlos.