Facebook Page Post ExecModule
Overview
FacebookPagePostModule creates one text/link feed post or one remote-photo post through the Meta Graph API. It supports immediate publication, unpublished drafts, and conservatively bounded schedules.
Version 2.0 replaces empty catalog I/O metadata and the former query-string credential path. The Page token is sent only as a Bearer authorization header. Requests have bounded connection and read timeouts, provider response IDs are validated, and error events exclude the token and provider body.
Creating a Page post is an outbound, non-idempotent write. The module never fabricates success and never retries an HTTP 429, 5xx, timeout, or ambiguous network failure automatically.
Usage
- Create or select a Meta app authorized for the target Facebook Page.
- Obtain a Page access token with
pages_manage_postsand any additional permissions required by the Page and content type. - Create a ValkyrAI
IntegrationAccount, store the token in encryptedapiKey, store the numeric Page ID in encryptedpassword, and set the account status toREADY. - Bind that account through
ExecModuleConfig.authConfig.integrationAccount. - Add
FacebookPagePostModuleto a workflow and provide a non-emptymessage. - Optionally supply either
linkorphoto_url. They are mutually exclusive. - For a draft, set
published=false. For a schedule, also provide an RFC3339scheduled_publish_time20 minutes to 29 days ahead. - Require outbound approval where workflow policy demands it, then inspect the verified post ID before continuing.
Inputs
| Name | Type | Required | Description | Constraints |
|---|---|---|---|---|
message | string | Yes | Page post text. | Non-blank; at most 63,206 Unicode code points locally. Meta applies final content and Page policy checks. |
link | string | No | Link attached to a feed post. | Absolute HTTPS URL, at most 2,048 characters, no embedded credentials; cannot be combined with photo_url. |
photo_url | string | No | Public remote image URL submitted to the Page photos edge. | Absolute HTTPS URL, at most 2,048 characters, no embedded credentials; cannot be combined with link. |
published | boolean | No | Publish immediately or create unpublished content. | Defaults to true; must be false when scheduling. |
scheduled_publish_time | string | No | Future publication time. | RFC3339 timestamp 20 minutes to 29 days after execution; requires published=false. |
page_id | string | No | Legacy provider-identity assertion. | If present, must be numeric and exactly match the bound IntegrationAccount Page ID. It does not override the account. |
The legacy media_url key is accepted as an alias for photo_url. Video upload, multi-photo creation, Stories, Reels, and local file upload are separate provider workflows and are not inferred from a URL extension.
Outputs
| Name | Type | When present | Description |
|---|---|---|---|
fb.post.id | string | Success | Numeric post or photo identifier returned by Meta. |
fb.post.permalink | string | Success | Stable https://www.facebook.com/<id> browser URL derived from the verified ID. |
fb.post.status | string | Always | PUBLISHED, SCHEDULED, DRAFT, or ERROR. |
fb.post.scheduled_time | string | Scheduled success | Normalized scheduled instant recorded after Meta accepts the create request. |
The runtime ExecModule is also marked GOOD or ERROR. EventLogs contain bounded validation, submission, success, or sanitized failure details; access tokens and provider response bodies are excluded.
IntegrationAccount Requirements
| Setting | Requirement |
|---|---|
| Provider | Meta Graph API / Facebook Pages API |
| Status | Exactly READY |
accountName | Human-readable Page identity |
apiKey | Encrypted Facebook Page access token |
password | Encrypted numeric Facebook Page ID |
| Relationship | Bind through ExecModuleConfig.authConfig.integrationAccount |
The Page access token must represent the target Page and carry pages_manage_posts. Depending on the app, Page, review state, content, and desired read-back behavior, Meta can require other scopes such as pages_read_engagement or pages_show_list.
Do not put tokens in module parameters, URLs, messages, links, media URLs, logs, or examples. The module ignores plaintext credential-like payload fields and uses only the bound IntegrationAccount.
Configuration
Illustrative normalized configuration:
{
"version": "2.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:facebook-page-publishing"
},
"payloadConfig": {
"parameters": "{\"message\":\"Release notes are live.\",\"photo_url\":\"https://cdn.example.com/releases/launch.png\",\"published\":false,\"scheduled_publish_time\":\"2026-08-08T18:00:00Z\"}"
}
}
The account value is a symbolic secure reference. Persisted workflows use the generated IntegrationAccount relationship, not plaintext token or Page ID fields.
The default transport uses a 10-second connection timeout and a 30-second read timeout. The module submits one form-encoded POST with Bearer authorization and performs no automatic retry.
Operations
FacebookPagePostModule has one create operation with these supported shapes:
| Shape | Provider edge | Parameters | Side effect |
|---|---|---|---|
| Text feed post | /{page-id}/feed | message, published | Creates an immediate post or draft. |
| Link feed post | /{page-id}/feed | message, link, published | Creates an immediate link post or draft. |
| Photo post | /{page-id}/photos | message, url, published | Creates a post from one public remote photo URL. |
| Scheduled feed/photo | Matching edge | Above fields plus published=false and epoch scheduled_publish_time | Creates unpublished content for provider scheduling. |
The module does not update, delete, reschedule, upload local bytes, poll processing, attach multiple photos, publish video, create Reels or Stories, or manage comments. Use separately authorized modules for those behaviors.
Errors and Failure Modes
| Failure | Cause | Retry guidance |
|---|---|---|
| Validation failure | Blank or oversized message, unsafe URL, link/photo conflict, malformed boolean/time, or schedule outside the local window. | Correct the input; no Meta request was sent. |
| IntegrationAccount failure | Missing account, account not READY, blank token, malformed Page ID, or page_id mismatch. | Bind or repair the correct Page account; no Meta request was sent. |
| HTTP 400 | Invalid Page/content/schedule shape or another provider validation rule. | Correct the request after reviewing Meta diagnostics outside workflow logs. |
| HTTP 401/403 | Expired token, wrong token identity, missing scope, app-review restriction, or insufficient Page task access. | Reauthorize the Page account with least-required scope. |
| HTTP 404 | Page, edge, object, or API-version mismatch. | Verify the Page ID, Page access, and currently supported Meta API version. |
| HTTP 429 | Meta rate limit. | Reconcile whether the post exists, honor provider retry guidance, then schedule a deliberate new attempt. |
| HTTP 5xx or network failure | Provider or transport failure with an ambiguous commit boundary. | Do not retry blindly; inspect Page content or Meta Business Suite first. |
| Invalid success response | A 2xx response lacks a numeric post_id or id, or is not valid JSON. | Treat as failure and inspect provider compatibility; success is not recorded. |
Provider response bodies can contain user content, app details, or credential-like values, so failures expose only a sanitized HTTP status or bounded local validation message.
Example
Schedule one Page photo:
{
"message": "Release notes are live.",
"photo_url": "https://cdn.example.com/releases/launch.png",
"published": false,
"scheduled_publish_time": "2026-08-08T18:00:00Z"
}
Expected normalized result after Meta accepts the create request and returns a valid identifier:
{
"fb.post.id": "123456789_987654321",
"fb.post.permalink": "https://www.facebook.com/123456789_987654321",
"fb.post.status": "SCHEDULED",
"fb.post.scheduled_time": "2026-08-08T18:00:00Z"
}
Acceptance does not prove that Meta later published scheduled content. Use an authorized read or Meta Business Suite to confirm the final provider state.
Notes
- Pagination: not applicable; one execution attempts one Page post creation.
- Limits: message and URL sizes are bounded locally. Meta enforces additional Page, app, content, media-fetch, scheduling, and platform limits.
- Scheduling: the 20-minute to 29-day local window is intentionally conservative. Provider capabilities can vary by product surface, API version, Page, and account policy.
- Rate limits: HTTP 429 is surfaced without retry. Provider quotas vary by app, token, Page, and usage.
- Idempotency: Page post creation has no durable provider idempotency key here. A workflow retry can create a duplicate post, so reconcile ambiguous attempts before re-execution.
- API constraints: remote photos must be publicly retrievable by Meta. Meta performs final content, scope, Page-role, URL, media, schedule, and policy validation.
- Destructive behavior: creation is an external outbound write. This module cannot delete or compensate a post; removal requires a separately authorized operation.
- Observability: EventLogs record bounded progress and sanitized failures. Tokens, request authorization, and provider bodies are never stored in workflow state.
- Unverified boundary: deterministic tests cover request edge and form construction, header-only credentials, bounds, IntegrationAccount state and identity, response validation, non-retry behavior, metadata serialization, and secret redaction. Live Facebook execution requires separately authorized credentials and is not exercised in repository tests.
See Meta's official Pages API posts guide, Page feed reference, and Page photos reference for current provider behavior.