# Mattermost Message Scraper (`jungle_synthesizer/mattermost-message-scraper`) Actor

Export messages from any Mattermost workspace — self-hosted or cloud. Provide your instance URL and a personal access token to scrape channels and posts. Supports team/channel filtering, date ranges, and direct message channels.

- **URL**: https://apify.com/jungle\_synthesizer/mattermost-message-scraper.md
- **Developed by:** [BowTiedRaccoon](https://apify.com/jungle_synthesizer) (community)
- **Categories:** Social media, Business
- **Stats:** 1 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Mattermost Message Scraper - Export Chat History from Self-Hosted or Cloud

Export messages from any Mattermost workspace — both self-hosted instances and Mattermost Cloud. Connect with your instance URL and a personal access token to scrape teams, channels, and posts. Supports filtering by team name, channel name, date range, and direct messages. Returns 23 fields per message including team and channel context, author, message body (plain Markdown), reactions, and file attachment IDs.

`post_message` is stored as plain Markdown text, which makes it directly usable for Confluence or Notion imports, RAG pipeline ingestion, or knowledge base extraction without additional parsing.

### What does the Mattermost scraper do?

It authenticates to the Mattermost REST API v4 using your personal access token, enumerates teams and channels accessible to that user, and paginates through posts in each channel. Usernames are resolved from a local cache to minimize API calls. The default API rate limit on self-hosted Mattermost is generous for authenticated users — typically 200+ requests per second.

### What data does it extract?

Each record represents one Mattermost post:

| Field | Type | Description |
|-------|------|-------------|
| `instance_url` | string | Base URL of the Mattermost instance |
| `team_id` | string | Team UUID |
| `team_name` | string | Team URL slug |
| `team_display_name` | string | Team display name |
| `channel_id` | string | Channel UUID |
| `channel_name` | string | Channel URL slug |
| `channel_display_name` | string | Channel display name |
| `channel_type` | string | `O`=public, `P`=private, `D`=direct, `G`=group |
| `channel_header` | string | Channel header text |
| `channel_purpose` | string | Channel purpose text |
| `post_id` | string | Post UUID |
| `post_root_id` | string | Parent post UUID (empty for root posts, set for thread replies) |
| `post_create_at` | integer | Creation timestamp in milliseconds since Unix epoch |
| `post_update_at` | integer | Last update timestamp in ms |
| `post_edit_at` | integer | Last edit timestamp in ms (0 if never edited) |
| `post_user_id` | string | Author's user UUID |
| `post_user_username` | string | Author's username |
| `post_message` | string | Post body text (Markdown) |
| `post_type` | string | Empty for regular posts; `system_*` for system messages |
| `post_hashtags` | string | Space-separated hashtags |
| `post_reactions` | string | JSON array of emoji reactions `[{emoji_name, user_id, create_at}]` |
| `post_file_ids` | string | JSON array of file attachment IDs |
| `post_props` | string | JSON object with post metadata (attachments, overrides, etc.) |

#### Sample output record

```json
{
  "instance_url": "https://community.mattermost.com/",
  "team_display_name": "Contributors",
  "channel_display_name": "Town Square",
  "channel_type": "O",
  "post_id": "3yd1q7gcrinbdmdq5qmnggd4xy",
  "post_root_id": "",
  "post_create_at": 1748063442000,
  "post_user_username": "john.doe",
  "post_message": "Has anyone seen the new API docs? The pagination endpoint changed.",
  "post_type": "",
  "post_reactions": "[{\"emoji_name\":\"thumbsup\",\"user_id\":\"abc123\",\"create_at\":1748063500000}]",
  "post_file_ids": "[]"
}
```

### How to use it

| Input | Required | Description |
|-------|----------|-------------|
| `instanceUrl` | Yes | Base URL of your Mattermost instance (e.g. `https://mattermost.yourcompany.com`). Works with self-hosted and Mattermost Cloud. |
| `accessToken` | Yes | Personal access token (see setup below) |
| `teamNames` | No | List of team URL slugs to scrape. Leave empty for all accessible teams. |
| `channelNames` | No | List of channel names to scrape within selected teams. Leave empty for all. |
| `sinceDate` | No | Only fetch posts on or after this date (ISO 8601) |
| `untilDate` | No | Only fetch posts on or before this date (ISO 8601) |
| `includeDirectMessages` | No | Set `true` to include DM and group message channels |
| `maxItems` | No | Maximum number of posts to return |

#### Generating a personal access token

1. Log in to your Mattermost instance
2. Go to **Account Settings** → **Security** → **Personal Access Tokens**
3. Click **Create Token**, give it a description, and copy the token

The path may vary slightly between Mattermost versions and UI themes. Administrators can also generate tokens from the **Admin Panel** → **Users** panel for any user account.

#### Example input

```json
{
  "instanceUrl": "https://mattermost.yourcompany.com/",
  "accessToken": "your-personal-access-token",
  "teamNames": ["engineering"],
  "channelNames": ["general", "incidents"],
  "sinceDate": "2024-01-01",
  "maxItems": 5000
}
```

### Use cases

- **Compliance archival** — export message history for legal hold or regulatory retention requirements in enterprise and government Mattermost deployments
- **Platform migration** — export messages to move to Slack, Microsoft Teams, or a custom data warehouse
- **Knowledge base export** — `post_message` is plain Markdown, so channel history exports directly to Confluence, Notion, or any RAG pipeline without additional parsing
- **Incident retrospectives** — extract incident channel history for post-mortems, filtered by date range
- **Communication analytics** — analyze team communication patterns, channel activity, and response times across channels

### FAQ

**Does this work with Mattermost Cloud?**
Yes. Set `instanceUrl` to your cloud workspace URL (e.g. `https://yourteam.cloud.mattermost.com`). The REST API v4 is identical between self-hosted and cloud.

**What permissions does the token need?**
A standard personal access token with the authenticated user's default permissions is sufficient. The actor only reads data the token's user can access — private channels and DMs are included only if the user is a member.

**How do I handle very large workspaces?**
Set `maxItems` to limit the run, then resume by setting `sinceDate` to the date of the last run. The actor pages through channels in batches of 200 posts per API request.

Output is available in JSON, CSV, and Excel via the Apify dataset export panel.

# Actor input Schema

## `sp_intended_usage` (type: `string`):

Please describe how you plan to use the data extracted by this crawler.

## `sp_improvement_suggestions` (type: `string`):

Provide any feedback or suggestions for improvements.

## `sp_contact` (type: `string`):

Provide your email address so we can get in touch with you.

## `instanceUrl` (type: `string`):

Base URL of your Mattermost instance (e.g. https://mattermost.example.com). Use https://community.mattermost.com for the public Mattermost community server.

## `accessToken` (type: `string`):

Mattermost personal access token. Generate one in Account Settings → Security → Personal Access Tokens.

## `teamNames` (type: `array`):

List of team names (URL-slug form) to scrape. Leave empty to scrape all accessible teams.

## `channelNames` (type: `array`):

List of channel names to scrape within the selected teams. Leave empty to scrape all accessible channels.

## `includeDirectMessages` (type: `boolean`):

Include direct message (D) and group message (G) channels.

## `sinceDate` (type: `string`):

Fetch posts created on or after this date (ISO 8601, e.g. 2024-01-01).

## `untilDate` (type: `string`):

Fetch posts created on or before this date (ISO 8601, e.g. 2024-12-31).

## `maxItems` (type: `integer`):

Maximum number of post records to return across all channels.

## Actor input object example

```json
{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "instanceUrl": "https://community.mattermost.com/",
  "includeDirectMessages": false,
  "maxItems": 10
}
```

# 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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "instanceUrl": "https://community.mattermost.com/",
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("jungle_synthesizer/mattermost-message-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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "instanceUrl": "https://community.mattermost.com/",
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("jungle_synthesizer/mattermost-message-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 '{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "instanceUrl": "https://community.mattermost.com/",
  "maxItems": 10
}' |
apify call jungle_synthesizer/mattermost-message-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jungle_synthesizer/mattermost-message-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/h35YOqCdTJ8rzewrH/builds/vaRJZqEvfZ6TcXRow/openapi.json
