Skip to content

Instantly share code, notes, and snippets.

@kazad
Created August 8, 2024 01:41
Show Gist options
  • Save kazad/d2b46d95487a8e98b94b7d47484beb1a to your computer and use it in GitHub Desktop.
Save kazad/d2b46d95487a8e98b94b7d47484beb1a to your computer and use it in GitHub Desktop.
NodeJS to export discourse instance to a bunch of .md files
const axios = require('axios');
const fs = require('fs-extra');
const path = require('path');
const DISCOURSE_URL = 'https://aha.betterexplained.com';
const OUTPUT_DIR = 'discourse_export';
// Configuration for categories to export
const EXPORT_CATEGORIES = [
{ id: 5, name: 'Community Guides' },
{ id: 3, name: 'Meta' },
{ id: 12, name: 'Intuition Help' },
];
if (!fs.existsSync(OUTPUT_DIR)) {
fs.mkdirSync(OUTPUT_DIR);
}
async function fetchJson(url) {
const response = await axios.get(url);
return response.data;
}
async function downloadTopic(categoryName, topicId, topicTitle) {
console.log(`Downloading: ${topicTitle} (${topicId})`);
const rawUrl = `${DISCOURSE_URL}/raw/${topicId}`;
const response = await axios.get(rawUrl);
const markdownContent = response.data;
const categoryDir = path.join(OUTPUT_DIR, categoryName);
fs.ensureDirSync(categoryDir);
const filename = `${topicTitle.replace(/[^a-z0-9]/gi, '_').toLowerCase()}.md`;
const filepath = path.join(categoryDir, filename);
fs.writeFileSync(filepath, markdownContent);
}
async function main() {
for (const category of EXPORT_CATEGORIES) {
const categoryId = category.id;
const categoryName = category.name.replace(/[^a-z0-9]/gi, '_').toLowerCase();
const topicsUrl = `${DISCOURSE_URL}/c/${categoryId}/l/latest.json`;
const topicsData = await fetchJson(topicsUrl);
const topics = topicsData.topic_list.topics;
for (const topic of topics) {
const topicId = topic.id;
const topicTitle = topic.title;
await downloadTopic(categoryName, topicId, topicTitle);
}
}
}
main().catch(err => {
console.error(err);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment