Engagement

Like Facebook Page posts and manage comments as the Page.

Facebook engagement is likes. The connection likes a published post as the Page, and likes are idempotent. Liking an already liked post succeeds without error. Pass post as described in Analytics. Use the internal id for Onepostly posts. Use the native post id plus accountId for outside posts.

Likes

import { Configuration, EngagementApi } from "@onepostly/sdk";

const engagementApi = new EngagementApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await engagementApi.like({
  engagementTargetBody: {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8"
  },
});
console.log(response);
{
  "postId": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
  "destinationId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
  "platform": "facebook",
  "kind": "like",
  "active": true
}
import { Configuration, EngagementApi } from "@onepostly/sdk";

const engagementApi = new EngagementApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await engagementApi.unlike({
  post: "1699f415-7fb6-43f4-9d2a-c447491f32a8",
});
console.log(response);
{
  "postId": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
  "destinationId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
  "platform": "facebook",
  "kind": "like",
  "active": false
}

Unliking returns the same shape with active: false.

Successful calls emit the engagement.liked and engagement.unliked webhooks.

Bookmarks, retweets and quotes do not exist on Facebook.

Comments

Manage comments on a published Facebook Page post. Works on text posts, photos, videos and multi-photo posts. Stories have no comments. Comments are posted as the Page.

List

Returns the post comments. Top level comments include their replies.

import { Configuration, CommentsApi } from "@onepostly/sdk";

const commentsApi = new CommentsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await commentsApi.listComments({
  post: "1699f415-7fb6-43f4-9d2a-c447491f32a8",
  limit: 25,
});
console.log(response);
{
  "comments": {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "subjects": [
      {
        "scope": "destination",
        "subjectId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
        "accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
        "platform": "facebook",
        "externalPostId": "17895695668004550",
        "status": "ready",
        "comments": [
          {
            "id": "c1",
            "text": "Love this!",
            "username": "jane_doe",
            "likeCount": 12,
            "timestamp": "2026-08-25T10:05:00.000Z",
            "parentId": null
          }
        ],
        "nextCursor": null,
        "error": null,
        "externalUrl": "https://www.facebook.com/page/posts/17895695668004550"
      }
    ]
  }
}
QueryRequiredNotes
postYesInternal post id or native post id. Native ids require accountId
accountIdFor native idsDisambiguates the target account. Also narrows internal posts with several destinations
destinationIdNoGlobally unique. Resolves on its own or narrows one destination inside an internal post
limitNo1-50, default 25
cursorNoPagination cursor from the previous response nextCursor. Requires a single resolved target

Create

Creates a top level comment, or a reply when parentCommentId is set.

import { Configuration, CommentsApi } from "@onepostly/sdk";

const commentsApi = new CommentsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await commentsApi.createComment({
  createCommentBody: {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "text": "Love this!",
    "parentCommentId": "c0"
  },
});
console.log(response);
{
  "comment": {
    "id": "c1",
    "text": "Love this!",
    "username": "jane_doe",
    "likeCount": 12,
    "timestamp": "2026-08-25T10:05:00.000Z"
  }
}
BodyRequiredNotes
postYesInternal post id or native post id. Native ids require accountId
textYesComment text
accountIdFor native idsTarget account for native ids. Also disambiguates internal posts
destinationIdNoGlobally unique. Resolves on its own or targets one destination inside an internal post
parentCommentIdNoReply to a comment. Omit to comment on the post itself

Delete

Deletes a comment made by the Page. commentId is the comment id on Facebook. Get it from List above (comments[].id). The same id works for hide, like, and private reply below.

import { Configuration, CommentsApi } from "@onepostly/sdk";

const commentsApi = new CommentsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await commentsApi.deleteComment({
  post: "1699f415-7fb6-43f4-9d2a-c447491f32a8",
  commentId: "c0",
});
console.log(response);
{
  "deleted": {
    "postId": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "destinationId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
    "platform": "facebook",
    "commentId": "c0",
    "deleted": true
  }
}

If you get a permission error on any of these, reconnect the Facebook connection once.

Hide or unhide

Hides a comment so only its author still sees it, or reveals it again with hidden: false.

import { Configuration, CommentsApi } from "@onepostly/sdk";

const commentsApi = new CommentsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await commentsApi.hideComment({
  body: {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "commentId": "c0",
    "hidden": true
  },
});
console.log(response);
{
  "hidden": {
    "postId": "string",
    "destinationId": "string",
    "platform": "facebook",
    "commentId": "string",
    "hidden": false
  }
}

Like or unlike a comment

Likes a comment as the Page, or removes the like. Unliking a comment that was never liked succeeds with liked: false.

import { Configuration, CommentsApi } from "@onepostly/sdk";

const commentsApi = new CommentsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await commentsApi.likeComment({
  commentTargetBody: {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "commentId": "c0"
  },
});
console.log(response);
{
  "liked": {
    "postId": "string",
    "destinationId": "string",
    "platform": "facebook",
    "commentId": "string",
    "liked": false
  }
}
import { Configuration, CommentsApi } from "@onepostly/sdk";

const commentsApi = new CommentsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await commentsApi.unlikeComment({
  post: "1699f415-7fb6-43f4-9d2a-c447491f32a8",
  commentId: "c0",
});
console.log(response);
{
  "liked": {
    "postId": "string",
    "destinationId": "string",
    "platform": "facebook",
    "commentId": "string",
    "liked": false
  }
}

Private reply

Sends a text Messenger DM in response to a comment. One private reply per comment, 7-day window. Requires messaging access on the connection.

import { Configuration, CommentsApi } from "@onepostly/sdk";

const commentsApi = new CommentsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await commentsApi.createPrivateReply({
  body: {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "commentId": "c0",
    "text": "Thanks! Check your DMs."
  },
});
console.log(response);
{
  "reply": {
    "postId": "string",
    "destinationId": "string",
    "platform": "facebook",
    "commentId": "string",
    "reply": {
      "id": "string",
      "text": "string",
      "timestamp": "string"
    }
  }
}

Automations

Keyword auto-replies per connection, evaluated best-effort on inbound webhooks (max 20 rules). comment_to_dm answers matching comments with a private reply; story_reply and welcome_dm answer matching DMs. keywords are case-insensitive substring matches (at least one is required), and use excludeKeywords to skip messages that contain any of them:

import { Configuration, EngagementApi } from "@onepostly/sdk";

const engagementApi = new EngagementApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await engagementApi.createAutomation({
  createAutomationBody: {
    "accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
    "kind": "welcome_dm",
    "name": "Welcome message",
    "keywords": [
      "string"
    ],
    "dmMessage": "Thanks for reaching out! We reply within a day."
  },
});
console.log(response);
{
  "accountId": "string",
  "rule": {
    "id": "string",
    "name": "Free guide giveaway",
    "kind": "comment_to_dm",
    "keywords": [
      "guide",
      "free"
    ],
    "excludeKeywords": [
      "guidelines"
    ],
    "dmMessage": "Thanks for your interest! Here is your guide.",
    "enabled": false
  }
}
import { Configuration, EngagementApi } from "@onepostly/sdk";

const engagementApi = new EngagementApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await engagementApi.listAutomations({
  accountId: "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
  name: "guide",
});
console.log(response);
{
  "rules": [
    {
      "id": "string",
      "name": "Free guide giveaway",
      "kind": "comment_to_dm",
      "keywords": [
        "guide",
        "free"
      ],
      "excludeKeywords": [
        "guidelines"
      ],
      "dmMessage": "Thanks for your interest! Here is your guide.",
      "enabled": false,
      "accountId": "string"
    }
  ]
}

Outside Posts

Posts published outside Onepostly work the same way once they are synced. Sync by URL then use the native id plus accountId in every comments call. Omit url and postId to refresh the recent posts of the account in bulk.

import { Configuration, PostsApi } from "@onepostly/sdk";

const postsApi = new PostsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await postsApi.syncExternal({
  syncExternalBody: {
    "accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
    "url": "https://www.facebook.com/page/posts/987654321"
  },
});
console.log(response);
{
  "synced": {
    "postsFound": 1,
    "postsSynced": 1,
    "skipped": false
  },
  "found": true,
  "post": {
    "id": "e8f9a0b1-c2d3-4e5f-8a6b-c7d8e9f0a1b2",
    "accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
    "platform": "facebook",
    "externalPostId": "987654321",
    "externalUrl": "https://www.facebook.com/page/posts/987654321",
    "mediaKind": "text",
    "publishedAt": "2026-08-25T10:00:00.000Z",
    "syncedAt": "2026-08-25T10:00:00.000Z",
    "analyticsStatus": "ready"
  }
}
import { Configuration, CommentsApi } from "@onepostly/sdk";

const commentsApi = new CommentsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await commentsApi.listComments({
  post: "1699f415-7fb6-43f4-9d2a-c447491f32a8",
  limit: 25,
});
console.log(response);
{
  "comments": {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "subjects": [
      {
        "scope": "destination",
        "subjectId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
        "accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
        "platform": "facebook",
        "externalPostId": "17895695668004550",
        "status": "ready",
        "comments": [
          {
            "id": "c1",
            "text": "Love this!",
            "username": "jane_doe",
            "likeCount": 12,
            "timestamp": "2026-08-25T10:05:00.000Z",
            "parentId": null
          }
        ],
        "nextCursor": null,
        "error": null,
        "externalUrl": "https://www.facebook.com/page/posts/17895695668004550"
      }
    ]
  }
}

Errors

CodeCauseFix
MISSING_EXTERNAL_IDDestination not published yetWait for publish
ENGAGEMENT_PERMISSIONConnection lacks pages_manage_engagementReconnect the Page
LIKE_FAILED or UNLIKE_FAILEDFacebook rejected the actionCheck the error message for the Facebook reason
COMMENTS_PERMISSIONConnection lacks pages_manage_engagementReconnect the Page
TEXT_REQUIREDEmpty comment textAdd message text
COMMENT_CREATE_FAILEDFacebook rejected the commentCheck the error message for the Facebook reason
COMMENT_HIDE_FAILEDFacebook rejected the hide toggleCheck the error message for the Facebook reason
COMMENT_LIKE_FAILED / COMMENT_UNLIKE_FAILEDFacebook rejected the like toggleCheck the error message for the Facebook reason
PRIVATE_REPLY_FAILEDFacebook rejected the private replyReconnect with messaging access; respect the 7-day window

See Also

  • Posts
  • Analytics
  • Webhooks for comment.created, comment.deleted, engagement.liked and engagement.unliked events