Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions DISCORD_MIRROR_DEPLOYMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Discord Mirror Deployment Guide for PowerShell.org

This repository contains a PowerShell-based Discord mirror that publishes selected Discord channel content into the Hugo site under `/discord/`.

## What this does

- Pulls messages from **specific allowlisted channels** in the PowerShell.org Discord server.
- Applies **moderation controls** before any content is published.
- Generates Hugo content pages in `content/discord/`.
- Generates search assets in `static/discord/`.
- Leaves all attachments and images hosted by Discord and links back to them.

## Required GitHub secret

Add this repository secret:

- `DISCORD_BOT_TOKEN`

## Required config updates

Edit `config/discord-mirror.json`:

- Replace `discord.guildId`
- Replace each placeholder channel ID
- Tune moderation mode per channel
- Tune `minMessageAgeMinutes` per channel
- Optionally adjust regex filters

## Recommended moderation modes

### `all`
Publish everything in that channel after the minimum age filter.

Use for:
- announcements
- release channels
- moderator-curated channels only

### `reaction`
Only publish messages that have the approval reaction, such as ✅.

Use for:
- help channels
- showcase channels
- Q&A highlights

### `prefix`
Only publish messages whose content starts with a configured prefix, such as `[publish]`.

Use for:
- moderator repost channels
- copy-edited summaries

### `author-role`
Only publish messages authored by users with one of the configured role names.

Use for:
- staff summaries
- trusted publisher channels

### `any`
Publish a message if any of the enabled approval mechanisms match.

Use for:
- flexible moderation workflows

## Workflow behavior

- On `main` branch pushes, the workflow runs the Discord exporter if `DISCORD_BOT_TOKEN` is present.
- On pull requests or when the secret is missing, the Hugo build still runs but the Discord export step is skipped.

## Validation checklist

1. Confirm the bot can read the selected channels.
2. Confirm the bot can read message history.
3. Confirm `https://powershell.org/discord/` renders.
4. Confirm `https://powershell.org/discord/search/` loads search results.
5. Confirm no private or unapproved messages appear.
6. Confirm attachment links point to Discord URLs.

## Operational advice

Do not point this at high-noise general chat and hope for the best. That is how you build a searchable landfill.
63 changes: 63 additions & 0 deletions DISCORD_MIRROR_MODERATION_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Discord Mirror Moderation Guide (v5)

This version adds practical publication controls so PowerShell.org can expose selected Discord content on the public web without blindly dumping channel history.

## Controls available

### 1. Channel allowlist
Only channels listed in `config/discord-mirror.json` are processed.

### 2. Per-channel moderation mode
Each channel can choose one of these modes:

- `all`
- `reaction`
- `prefix`
- `author-role`
- `any`

### 3. Minimum message age
`minMessageAgeMinutes` delays publication so moderators have time to correct or remove content.

Examples:
- `60` for announcements
- `1440` for support highlights
- `10080` for weekly editorial review

### 4. Regex filters
Use `excludeRegex` to suppress command spam, bot command invocations, or unwanted patterns.
Use `includeRegex` to only publish messages that match a known format.

### 5. Optional thread capture
`includeThreads` can be enabled per channel, but it is off by default because the current target is mostly normal text channels.

## Suggested policies for PowerShell.org

### Announcements
- moderation: `all`
- age: `60`
- threads: `false`

### Help highlights
- moderation: `reaction`
- reaction: `✅`
- age: `1440`
- threads: `false`

### Moderator summaries
- moderation: `prefix`
- prefix: `[publish]`
- age: `60`
- threads: `false`

### Staff-only publisher channel
- moderation: `author-role`
- roles: `Moderator`, `Admin`, `Discord Team`
- age: `60`
- threads: `false`

## Recommended rollout

Start with one low-risk channel such as announcements, verify output, then add one curated help channel using `reaction` mode.

That gives you a public knowledge layer instead of a public transcript of everyone's stream of consciousness.
9 changes: 9 additions & 0 deletions DISCORD_MIRROR_SITE_OWNER_QUICKSTART.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Discord Mirror Quick Start

1. Add the `DISCORD_BOT_TOKEN` secret to the GitHub repository.
2. Update `config/discord-mirror.json` with the real guild ID and channel IDs.
3. Give the Discord bot **View Channel** and **Read Message History** in the selected channels.
4. Push the changes to `main`.
5. Verify the GitHub Actions workflow succeeds.
6. Open `/discord/` and `/discord/search/` on the site.
7. Verify moderation controls are working before announcing the feature publicly.
79 changes: 79 additions & 0 deletions config/discord-mirror.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
"site": {
"title": "PowerShell.org Discord Archive",
"baseUrl": "https://powershell.org/discord",
"sectionPath": "discord",
"footerText": "Selected Discord content is published to the public web for search and discovery. Attachments and images remain hosted by Discord.",
"searchDescription": "Search approved Discord archive content mirrored from selected PowerShell.org Discord channels."
},
"discord": {
"guildId": "1488875093873397832",
"apiBaseUrl": "https://discord.com/api/v10",
"userAgent": "PowerShellOrgDiscordMirror/5.0"
},
"export": {
"outputContentDir": "content/discord",
"outputStaticDir": "static/discord",
"searchIndexFileName": "search-index.json",
"includeBotMessages": false,
"sanitizeMentions": true,
"maxMessagesPerChannel": 1500,
"defaultMinMessageAgeMinutes": 1440,
"defaultModerationMode": "reaction",
"defaultApprovalReaction": "\u2705",
"defaultApprovalPrefix": "[publish]",
"defaultAuthorRoleNames": [
"Moderator",
"Admin",
"Discord Team"
],
"defaultExcludeRegex": [
"^/",
"^!",
"^\\\\?help"
],
"generatedBy": "tools/discord-mirror/Export-DiscordMirror.ps1"
},
"channels": [
{
"id": "1488875094938746884",
"slug": "announcements",
"title": "Announcements",
"description": "Approved announcement messages mirrored from Discord.",
"enabled": true,
"includeThreads": false,
"maxMessages": 500,
"minMessageAgeMinutes": 60,
"moderationMode": "all",
"approvalReaction": "\u2705",
"approvalPrefix": "[publish]",
"authorRoleNames": [
"Moderator",
"Admin"
],
"excludeRegex": []
},
{
"id": "1489393262191185981",
"slug": "TechTalk-PowerShell",
"title": "TechTalk-PowerShell",
"description": "Curated PowerShell message highlights approved for public publishing.",
"enabled": true,
"includeThreads": false,
"maxMessages": 2000,
"minMessageAgeMinutes": 1440,
"moderationMode": "all",
"approvalReaction": "\u2705",
"approvalPrefix": "[publish]",
"authorRoleNames": [
"Moderator",
"Admin"
],
"excludeRegex": [
"^/",
"^!"
],
"includeRegex": []
}
]
}
3 changes: 3 additions & 0 deletions hugo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ menu:
- name: "Forums"
url: "https://forums.powershell.org"
weight: 60
- name: "Discord Archive"
url: "/discord/"
weight: 62
Comment on lines +60 to +62
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the Discord Archive menu entry points users to /discord/, but this section is generated by the exporter and won’t exist when the export step is skipped (e.g., missing DISCORD_BOT_TOKEN). Consider adding a committed stub content/discord/_index.md (or making the menu entry conditional) so the site doesn’t ship with a dead link when the exporter hasn’t run.

Suggested change
- name: "Discord Archive"
url: "/discord/"
weight: 62

Copilot uses AI. Check for mistakes.

# Site parameters
params:
Expand Down
1 change: 1 addition & 0 deletions static/discord/search-index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
1 change: 1 addition & 0 deletions static/discord/search.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions static/discord/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* Generated by tools/discord-mirror/Export-DiscordMirror.ps1 */
Loading
Loading