# Discord Channel Message Scraper (`punkrecordsdata/discord-scraper`) Actor

Export Discord channel messages: content, author, attachments, embeds, reactions, timestamps. Export CSV, Excel, JSON.

- **URL**: https://apify.com/punkrecordsdata/discord-scraper.md
- **Developed by:** [PunkRecordsData](https://apify.com/punkrecordsdata) (community)
- **Categories:**
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.51 / 1,000 message results

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?

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

<p align="center">
  <img src="https://api.apify.com/v2/key-value-stores/AAm3a1h3Z9nYfrvh9/records/banner" alt="PunkRecordsData" width="100%" />
</p>

## 💬 Discord Message Scraper: Export Channel History

> 🚀 **Discord Message Scraper** exports a channel's message history in seconds: content, author, attachments, embeds, reactions, mentions, and timestamps, in the order they were posted. Point it at a channel URL and a token, get a structured dataset back.

> 🕒 **Last updated:** 2026-08-29 · **📊 21 fields** per message · pagination up to full channel history · CSV, Excel, JSON export

Discord doesn't expose channel history through a public search index, so pulling a full conversation thread out for analysis, moderation review, or archiving normally means scrolling and copy-pasting by hand. This Actor calls Discord's own message API directly and turns a channel into a clean, exportable dataset: one row per message, ready for a spreadsheet or a downstream pipeline.

| 🎯 Target audience | 💡 Primary use cases |
|---|---|
| Community managers, researchers, moderators, data teams | Archiving a channel before it's deleted, sentiment/trend analysis on a community, exporting evidence for moderation, building a searchable message log |

### 📋 What the Discord Message Scraper does

Given a channel URL, it walks the channel's message history page by page (newest-first by default, or oldest-first for a full archive) and returns each message as a structured record: text content, author profile, attachments, embeds, reaction counts, mentions, pin status, and both posted and edited timestamps. Runs on the Apify platform, so every run is schedulable, monitorable from the Console, and reachable through the Apify API or any of Apify's integrations (Zapier, Make, n8n).

### ⚙️ Input

| Field | Type | Required | Description |
|---|---|---|---|
| `token` | string | ✅ | Your personal Discord token. See "How to use" below. |
| `channelUrl` | string | ✅ | `https://discord.com/channels/{serverId}/{channelId}`, from a channel's right-click "Copy Link" menu. |
| `maxItems` | integer | Optional | Stop after this many messages. Leave empty for the full channel history. |
| `oldestFirst` | boolean | Optional | Off starts from the newest message. On starts from the first message ever posted. |
| `minDelaySecs` / `maxDelaySecs` | integer | Optional | Random wait between pages, in seconds. Defaults: 1 and 3. |
| `proxyConfiguration` | object | Optional | Route requests through an Apify Proxy IP. |

Minimal input:

```json
{
  "token": "your-discord-token",
  "channelUrl": "https://discord.com/channels/123456789012345678/123456789012345679",
  "maxItems": 100
}
```

Full channel archive, oldest message first:

```json
{
  "token": "your-discord-token",
  "channelUrl": "https://discord.com/channels/123456789012345678/123456789012345679",
  "oldestFirst": true,
  "minDelaySecs": 2,
  "maxDelaySecs": 5
}
```

> ⚠️ **Good to know:** this Actor authenticates as your personal Discord account, not an official bot. Automating a personal account this way is against Discord's Terms of Service and carries a real risk of that account being banned. Use a secondary or otherwise expendable account, never your main one, and never a token for an account you can't afford to lose. You are responsible for how you use it.

### 📊 Output

| Field | Description |
|---|---|
| 🖼 `authorAvatarUrl` | Author's avatar image URL |
| 💬 `content` | Message text |
| 👤 `authorUsername` / `authorGlobalName` / `authorId` | Author identity |
| 🤖 `authorIsBot` | Whether the author is a bot account |
| # `channelId` / `messageId` | Discord IDs |
| 📎 `attachmentCount` / `attachments` | File attachment count and details |
| 🔗 `embedCount` / `embeds` | Link preview/embed count and details |
| 😀 `reactionCount` | Total reactions on the message |
| @ `mentionCount` / `mentions` | Users mentioned |
| 📌 `pinned` | Pin status |
| 🕒 `postedAt` / `editedAt` | Timestamps |
| 🔗 `messageUrl` | Direct link back to the message |

Real sample record (from a live run against a public server):

```json
{
  "authorAvatarUrl": "https://cdn.discordapp.com/avatars/712447082652237904/0bbc2086679de3b310846db9e7021b0c.png",
  "content": "anyone free to review the PR I opened this morning?",
  "authorUsername": "riverjay",
  "authorGlobalName": "River",
  "authorId": "712447082652237904",
  "authorIsBot": false,
  "channelId": "1480052419512635462",
  "messageId": "1518669370136723536",
  "attachmentCount": 0,
  "attachments": [],
  "embedCount": 0,
  "embeds": [],
  "reactionCount": 2,
  "mentionCount": 0,
  "mentions": [],
  "pinned": false,
  "postedAt": "2026-06-22T17:29:53.353Z",
  "editedAt": null,
  "messageUrl": "https://discord.com/channels/1371199180072292513/1480052419512635462/1518669370136723536",
  "scrapedAt": "2026-08-29T23:28:13.093Z",
  "error": null
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel from the Storage tab.

### ✨ Why choose this Actor

- ✅ Direct calls to Discord's own message API, no browser automation, so runs finish fast
- 🔓 Works on any channel your account can already see, no server admin approval or bot invite needed
- 📄 Full pagination: pull the last 20 messages or the entire channel history in one run
- ⚠️ Honest about the trade-off: the input schema and this README both disclose the ToS risk up front, most tools like this don't

### 📈 How it compares to alternatives

An official Discord bot (OAuth2 + Bot API) is the ToS-safe way to read a server's messages, but it only works on servers where someone with Manage Server permission has invited the bot first, so it can't reach a channel you don't already administrate. This Actor trades that safety for reach: it works on any channel you're already a member of, with no invite step, at the cost of using a personal account token instead of a bot identity.

### 🚀 How to use

1. Open [console.apify.com](https://console.apify.com) and find Discord Message Scraper in your Actors.
2. Get your Discord token: open discord.com in a browser you're logged into, open DevTools (F12) → Console, and run a token-extraction snippet (search "get discord token console" for a current one, Discord's internal structure changes periodically so snippets do too).
3. Right-click the target channel in Discord → Copy Link, paste it into `channelUrl`.
4. Set `maxItems` (or leave empty for the full history) and click Start.
5. Download results as JSON, CSV, or Excel from the Storage tab once the run finishes.

### 💼 Business use cases

**Community management.** Archive a channel's full history before pruning it or before a server migration.

**Research.** Pull message-level data from a public community for sentiment or trend analysis.

**Moderation.** Export a conversation thread as evidence for a report or an appeal.

**Compliance.** Keep a searchable record of a workspace's Discord communications where policy requires it.

### ❓ Frequently Asked Questions

**Is this against Discord's Terms of Service?**
Yes. Automating a personal Discord account outside the official Bot API violates Discord's ToS and can get that account banned. This Actor discloses that plainly instead of hiding it. Use an account you're prepared to lose.

**Do I need to be an admin of the server?**
No. You only need to already be a member with access to view the target channel.

**How do I get a Discord token?**
Log into discord.com in a browser, open DevTools (F12) → Console, and run a token-extraction snippet. Search "get discord token console" for a current one.

**Will my token be stored or shared?**
No. It's used only for the run you provide it in and isn't logged or persisted by this Actor.

**Can I scrape a channel I'm not a member of?**
No. Your account needs to already have view access to that channel, same as opening it in the Discord app.

**Does this scrape server member lists?**
Not in this version. Discord serves member lists over a real-time connection rather than a simple API call, which is a meaningfully bigger automation footprint; it's intentionally out of scope for now.

**How much does it cost to run?**
Apify's free tier covers small runs. Cost scales with message count, roughly proportional to how many pages of history you pull. Check current Apify plan pricing at [apify.com/pricing](https://apify.com/pricing).

**Can I resume a large export if it stops partway?**
Set `oldestFirst: true` and re-run with `maxItems` adjusted; the Actor works from the message ID range so a re-run naturally continues from where you left off if you track the last `messageId` seen.

**Can I schedule this to run automatically?**
Yes, Apify Actors support scheduling directly from the Console, so you can pull new messages daily or hourly.

**What happens if my token expires mid-run?**
Discord returns a 401, the run logs the error and stops rather than silently failing.

### 🔌 Integrate with any app

Every Apify Actor exposes a REST API, webhooks, and native integrations with Zapier, Make, and n8n. Trigger a run, get notified when it finishes, and pull results straight into your own tools.

> **⚠️ Disclaimer:** independent tool, not affiliated with or endorsed by Discord Inc. Only data visible to the account whose token you provide is collected. Contact: contact.punkrecordsdata@gmail.com

# Actor input Schema

## `token` (type: `string`):

Your personal Discord token, from a browser you're already logged into (F12 → Console → paste the token-grab snippet linked in the Actor's README). ⚠️ This authenticates as YOUR account, not an official bot. Automating a personal Discord account this way is against Discord's Terms of Service and can get that account banned. Use an account you're comfortable putting at risk, never your only/primary account.

## `channelUrl` (type: `string`):

Right-click a channel in Discord → Copy Link. Looks like https://discord.com/channels/{serverId}/{channelId}. You must already be a member of that server for your token to see it.

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

Stop after this many messages. Leave empty to pull the entire channel history.

## `oldestFirst` (type: `boolean`):

Off (default) starts from the newest message and works backward. On starts from the very first message in the channel and works forward — slower, but useful for a full archive.

## `minDelaySecs` (type: `integer`):

Wait at least this long before fetching the next page of messages. Higher values look less automated and lower ban risk, at the cost of speed.

## `maxDelaySecs` (type: `integer`):

Upper bound of the random wait between pages.

## `proxyConfiguration` (type: `object`):

Optional. Routes requests through an Apify Proxy IP instead of the platform's own, for extra traffic-pattern variety.

## Actor input object example

```json
{
  "channelUrl": "https://discord.com/channels/613425648685547541/613425648685547546",
  "maxItems": 100,
  "oldestFirst": false,
  "minDelaySecs": 1,
  "maxDelaySecs": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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 = {
    "channelUrl": "https://discord.com/channels/613425648685547541/613425648685547546",
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("punkrecordsdata/discord-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 = {
    "channelUrl": "https://discord.com/channels/613425648685547541/613425648685547546",
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("punkrecordsdata/discord-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 '{
  "channelUrl": "https://discord.com/channels/613425648685547541/613425648685547546",
  "maxItems": 100
}' |
apify call punkrecordsdata/discord-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,punkrecordsdata/discord-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/iQQpJrZK7YZRGxMHP/builds/s86xFL3gI3EQF9uqp/openapi.json
