# Facebook Groups Scraper (`calm_builder/facebook-groups-scraper`) Actor

Scrape posts from public Facebook groups without login: text, author, photos, videos, reactions, comment and share counts, plus optional comments and replies. Filter by date, sort by newest or top posts, and export clean JSON, CSV or Excel. Pay only for results.

- **URL**: https://apify.com/calm\_builder/facebook-groups-scraper.md
- **Developed by:** [Coder](https://apify.com/calm_builder) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 group posts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Facebook Groups Scraper

Extract posts from **public** Facebook groups into clean, structured JSON — text, author, media, reaction breakdowns, engagement counts, and optional comments with replies.

Use it for **community monitoring**, **social listening**, **market research**, **content archiving**, and **AI-ready datasets** — without manually scrolling group feeds.

For Facebook Pages or profiles, use the [Facebook Posts Scraper](https://apify.com/calm_builder/facebook-posts-scraper). For comments on known post URLs only, use the [Facebook Comments Scraper](https://apify.com/calm_builder/facebook-comments-scraper). For Marketplace listings, use the [Facebook Marketplace Scraper](https://apify.com/calm_builder/facebook-marketplace-scraper).

***

### What you get

Each dataset row is **one group post**:

| Section        | What it contains                                                                                |
| -------------- | ----------------------------------------------------------------------------------------------- |
| **Identity**   | Post URL, post ID, group ID / title, and the input link that produced the row                   |
| **Content**    | Post text, publish time, and author (name, profile URL, profile picture when available)         |
| **Engagement** | Likes, comments count, shares, and reaction breakdown (Like, Love, Care, Haha, Wow, Sad, Angry) |
| **Media**      | Photo / video attachments, photo counts, and shared links when present                          |
| **Comments $** | Optional nested `comments` with replies when comment collection is enabled                      |

Results **stream** to the dataset as posts are collected, so you can preview progress before the run finishes.

***

### Quick start on Apify

1. Open the Actor in the Apify Console.
2. Add one or more **public Facebook group** links (full URLs, vanity names, or numeric IDs).
3. Set **Maximum posts per group** (default `20`).
4. Optionally choose **Feed sorting** and a **Only posts newer than** cutoff.
5. Leave **Add comments and replies $** off for the fastest, cheapest runs — or enable it when you need discussion threads.
6. Click **Start** and open the **Dataset** tab.

**Example input (posts only):**

```json
{
  "startUrls": [
    "https://www.facebook.com/groups/dogspotting/",
    "https://www.facebook.com/groups/3277056332339849/"
  ],
  "maxPosts": 25,
  "viewOption": "CHRONOLOGICAL",
  "includeComments": false
}
```

**Example input (posts + comments and replies):**

```json
{
  "startUrls": ["https://www.facebook.com/groups/dogspotting/"],
  "maxPosts": 10,
  "viewOption": "RECENT_ACTIVITY",
  "includeComments": true,
  "maxComments": 15,
  "includeReplies": true,
  "maxRepliesPerComment": 5,
  "commentsSortBy": "newest"
}
```

***

### Input parameters

#### Facebook group links

|              |                 |
| ------------ | --------------- |
| **Field**    | `startUrls`     |
| **Type**     | List of strings |
| **Required** | Yes             |

Add one public group per row. Supported formats in the same run:

- Full URLs: `https://www.facebook.com/groups/dogspotting/`
- Mobile / web hosts: `m.facebook.com`, `web.facebook.com`
- Numeric IDs: `3277056332339849`
- Vanity names: `dogspotting`
- Post, permalink, or tab links (About, Media, …) — resolved to the parent group feed

Duplicate links that resolve to the same group are scraped once. Limits below apply **per group**.

#### Maximum posts per group

|             |            |
| ----------- | ---------- |
| **Field**   | `maxPosts` |
| **Default** | `20`       |

Maximum number of posts to collect from each group.

#### Feed sorting

|             |                 |
| ----------- | --------------- |
| **Field**   | `viewOption`    |
| **Default** | `CHRONOLOGICAL` |

| Value             | Meaning                   |
| ----------------- | ------------------------- |
| `CHRONOLOGICAL`   | New posts (chronological) |
| `RECENT_ACTIVITY` | Newest activity           |
| `TOP_POSTS`       | Most relevant (top posts) |

#### Only posts newer than

|              |                      |
| ------------ | -------------------- |
| **Field**    | `onlyPostsNewerThan` |
| **Optional** | Yes                  |

Stop paginating a group once older posts are reached. Accepts:

- Absolute date: `2026-09-01`
- Relative: `7 days`, `2 weeks`, `1 month`

Leave empty to collect without a date cutoff.

***

### Comments and replies $

Fields marked with **$** are billed separately from posts: each delivered comment or reply counts as one comment event.

| Field                    | Description                                                | Default  |
| ------------------------ | ---------------------------------------------------------- | -------- |
| `includeComments` $      | Collect comments (and replies, when enabled) for each post | `false`  |
| `maxComments` $          | Maximum top-level comments per post                        | `10`     |
| `includeReplies` $       | Also collect replies under each top-level comment          | `true`   |
| `maxRepliesPerComment` $ | Maximum replies under each top-level comment               | `5`      |
| `commentsSortBy`         | `newest`, `most_relevant`, or `all_comments`               | `newest` |

**Tips**

- Keep comments **off** for feed-only monitoring.
- Use a lower `maxComments` / `maxRepliesPerComment` on busy groups to control cost and runtime.
- Replies add conversation context but increase runtime on active threads.

***

### Output

Each dataset item is one Facebook group post.

#### Example output shape

```json
{
  "facebookUrl": "https://www.facebook.com/groups/dogspotting/",
  "inputUrl": "https://www.facebook.com/groups/dogspotting/",
  "groupId": "10487409466",
  "groupTitle": "Dogspotting",
  "url": "https://www.facebook.com/groups/dogspotting/posts/10166216103904467/",
  "legacyId": "10166216103904467",
  "time": "2026-09-23T12:59:53Z",
  "timestamp": 1790168393,
  "text": "This dog is helping mum operate the cash desk…",
  "user": {
    "id": "…",
    "name": "Example Author",
    "profileUrl": "https://www.facebook.com/…",
    "profilePic": "https://…"
  },
  "likesCount": 122,
  "commentsCount": 2,
  "sharesCount": 0,
  "reactionLikeCount": 94,
  "reactionLoveCount": 28,
  "photoCount": 2,
  "attachments": [],
  "comments": [
    {
      "legacyId": "10166216852844467",
      "text": "Working hard",
      "createdAt": "2026-09-23T16:56:38Z",
      "author": {
        "name": "Example Commenter"
      },
      "replyCount": 1,
      "replies": [
        {
          "legacyId": "…",
          "text": "So cute!",
          "createdAt": "2026-09-23T17:01:00Z",
          "author": {
            "name": "Example Reply"
          }
        }
      ]
    }
  ]
}
```

When comments are disabled, the `comments` array is omitted or empty.

***

### Best for

- Community and brand monitoring in public Facebook groups
- Tracking engagement and reaction mix over time
- Research on topics, products, or local communities
- Archiving public group discussions
- Feeding structured social data into BI, NLP, or AI pipelines

***

### How to use

1. Start with a small `maxPosts` (for example `5`) on one known-public group to validate output.
2. Add more groups once the shape looks right.
3. Enable comments only when you need conversation text — it increases runtime and cost.
4. Use `onlyPostsNewerThan` for scheduled runs that should focus on recent activity.
5. Export the dataset as JSON, CSV, or Excel, or pull it through the Apify API.

***

### FAQ

#### Does this work on private groups?

No. Only **public** groups that are visible without logging in are supported.

#### Can I mix vanity names and full URLs?

Yes. Put them in the same `startUrls` list; each is normalized to the group feed.

#### Why are some `commentsCount` values higher than the comments array?

`commentsCount` is Facebook’s total for the post (often including replies). The `comments` array only contains what was collected under your `maxComments` / `maxRepliesPerComment` settings.

#### A group was skipped with "not available" — why?

Facebook returns its generic "content isn't available" page for groups that were
deleted, renamed, or switched to private. The Actor reports that group and continues
with the rest of your list instead of returning an empty dataset without explanation.

#### How long does a run take?

Runtime depends mainly on the number of groups, `maxPosts`, and whether comments/replies are enabled.

#### Are results streamed?

Yes. Posts are pushed to the dataset as they are collected, so you can inspect early rows while the run continues.

***

### Pricing notes

- **Posts** are billed per successful post written to the dataset.
- **Comments and replies $** are billed per delivered comment or reply when that section is enabled.
- Empty attempts, failed fetches, and filtered-out rows are not billed as results.

Exact prices are shown on the Actor’s **Pricing** tab in the Apify Store.

***

### Responsible use

Use this Actor only for publicly available content and ensure your use complies with applicable laws, regulations, and platform terms for your jurisdiction and use case.

### Troubleshooting

- Confirm the group opens in a private/incognito browser window without logging in.
- Test with a small `maxPosts` value first.
- If a group returns nothing, try another known-public group to confirm the run environment.
- For comment-heavy runs, lower `maxComments` and `maxRepliesPerComment` if the run is slow or costly.

# Actor input Schema

## `startUrls` (type: `array`):

One public Facebook group per row. You can mix formats in the same run:

- Full URLs: `https://www.facebook.com/groups/dogspotting/`
- Mobile / web hosts: `https://m.facebook.com/groups/…`, `https://web.facebook.com/groups/…`
- Numeric IDs: `3277056332339849` or `https://www.facebook.com/groups/3277056332339849/`
- Vanity names: `dogspotting`
- Post, permalink, or tab links (About, Media, etc.) — scraped as the parent group feed

Duplicate links that resolve to the same group are scraped once.

## `maxPosts` (type: `integer`):

Maximum number of posts to collect from each group link. Use a smaller value for quick checks; raise it for deeper harvests.

## `viewOption` (type: `string`):

How posts are ordered in the group feed before scraping.

## `onlyPostsNewerThan` (type: `string`):

Optional cutoff for post age. Accepts an absolute date (`YYYY-MM-DD`) or a relative value such as `7 days`, `2 weeks`, or `1 month`. Scraping stops for a group once older posts are reached. Leave empty to collect posts without a date limit.

## `includeComments` (type: `boolean`):

Collect comments (and replies, when enabled below) for each scraped post. $ billed per delivered comment/reply.

## `maxComments` (type: `integer`):

Maximum number of top-level comments to collect for each post. Each delivered comment is billed ($). Lower values reduce runtime and cost.

## `includeReplies` (type: `boolean`):

Also collect replies under each top-level comment. Each delivered reply is billed ($). Turn off to keep top-level comments only.

## `maxRepliesPerComment` (type: `integer`):

Maximum number of replies to collect under each top-level comment. Each delivered reply is billed ($). Controls output size and cost on busy threads.

## `commentsSortBy` (type: `string`):

Ordering used when collecting comments for each post.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.facebook.com/groups/dogspotting/",
    "https://www.facebook.com/groups/3277056332339849/"
  ],
  "maxPosts": 20,
  "viewOption": "CHRONOLOGICAL",
  "onlyPostsNewerThan": "",
  "includeComments": false,
  "maxComments": 10,
  "includeReplies": true,
  "maxRepliesPerComment": 5,
  "commentsSortBy": "newest"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        "https://www.facebook.com/groups/dogspotting/",
        "https://www.facebook.com/groups/3277056332339849/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("calm_builder/facebook-groups-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "startUrls": [
        "https://www.facebook.com/groups/dogspotting/",
        "https://www.facebook.com/groups/3277056332339849/",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("calm_builder/facebook-groups-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    "https://www.facebook.com/groups/dogspotting/",
    "https://www.facebook.com/groups/3277056332339849/"
  ]
}' |
apify call calm_builder/facebook-groups-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,calm_builder/facebook-groups-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/UkwI6RWYQ1TrzIk9j/builds/5ONdU3y8RqJO34oZ0/openapi.json
