diff --git a/package-lock.json b/package-lock.json
index a12a9ce..e6593e1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,6 +20,7 @@
"@uiw/react-md-editor": "^3.11.0",
"axios": "^1.7.2",
"bech32": "^2.0.0",
+ "discord.js": "^14.15.3",
"light-bolt11-decoder": "^3.1.1",
"next": "14.2.5",
"next-auth": "^4.24.7",
@@ -470,6 +471,133 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@discordjs/builders": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.8.2.tgz",
+ "integrity": "sha512-6wvG3QaCjtMu0xnle4SoOIeFB4y6fKMN6WZfy3BMKJdQQtPLik8KGzDwBVL/+wTtcE/ZlFjgEk74GublyEVZ7g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@discordjs/formatters": "^0.4.0",
+ "@discordjs/util": "^1.1.0",
+ "@sapphire/shapeshift": "^3.9.7",
+ "discord-api-types": "0.37.83",
+ "fast-deep-equal": "^3.1.3",
+ "ts-mixer": "^6.0.4",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.11.0"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/@discordjs/collection": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz",
+ "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16.11.0"
+ }
+ },
+ "node_modules/@discordjs/formatters": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.4.0.tgz",
+ "integrity": "sha512-fJ06TLC1NiruF35470q3Nr1bi95BdvKFAF+T5bNfZJ4bNdqZ3VZ+Ttg6SThqTxm6qumSG3choxLBHMC69WXNXQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "discord-api-types": "0.37.83"
+ },
+ "engines": {
+ "node": ">=16.11.0"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/@discordjs/rest": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.3.0.tgz",
+ "integrity": "sha512-C1kAJK8aSYRv3ZwMG8cvrrW4GN0g5eMdP8AuN8ODH5DyOCbHgJspze1my3xHOAgwLJdKUbWNVyAeJ9cEdduqIg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@discordjs/collection": "^2.1.0",
+ "@discordjs/util": "^1.1.0",
+ "@sapphire/async-queue": "^1.5.2",
+ "@sapphire/snowflake": "^3.5.3",
+ "@vladfrangu/async_event_emitter": "^2.2.4",
+ "discord-api-types": "0.37.83",
+ "magic-bytes.js": "^1.10.0",
+ "tslib": "^2.6.2",
+ "undici": "6.13.0"
+ },
+ "engines": {
+ "node": ">=16.11.0"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/@discordjs/rest/node_modules/@discordjs/collection": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.0.tgz",
+ "integrity": "sha512-mLcTACtXUuVgutoznkh6hS3UFqYirDYAg5Dc1m8xn6OvPjetnUlf/xjtqnnc47OwWdaoCQnHmHh9KofhD6uRqw==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/@discordjs/util": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.1.0.tgz",
+ "integrity": "sha512-IndcI5hzlNZ7GS96RV3Xw1R2kaDuXEp7tRIy/KlhidpN/BQ1qh1NZt3377dMLTa44xDUNKT7hnXkA/oUAzD/lg==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16.11.0"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/@discordjs/ws": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.1.1.tgz",
+ "integrity": "sha512-PZ+vLpxGCRtmr2RMkqh8Zp+BenUaJqlS6xhgWKEZcgC/vfHLEzpHtKkB0sl3nZWpwtcKk6YWy+pU3okL2I97FA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@discordjs/collection": "^2.1.0",
+ "@discordjs/rest": "^2.3.0",
+ "@discordjs/util": "^1.1.0",
+ "@sapphire/async-queue": "^1.5.2",
+ "@types/ws": "^8.5.10",
+ "@vladfrangu/async_event_emitter": "^2.2.4",
+ "discord-api-types": "0.37.83",
+ "tslib": "^2.6.2",
+ "ws": "^8.16.0"
+ },
+ "engines": {
+ "node": ">=16.11.0"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/@discordjs/ws/node_modules/@discordjs/collection": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.0.tgz",
+ "integrity": "sha512-mLcTACtXUuVgutoznkh6hS3UFqYirDYAg5Dc1m8xn6OvPjetnUlf/xjtqnnc47OwWdaoCQnHmHh9KofhD6uRqw==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -1145,6 +1273,39 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@sapphire/async-queue": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.3.tgz",
+ "integrity": "sha512-x7zadcfJGxFka1Q3f8gCts1F0xMwCKbZweM85xECGI0hBTeIZJGGCrHgLggihBoprlQ/hBmDR5LKfIPqnmHM3w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=v14.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/@sapphire/shapeshift": {
+ "version": "3.9.7",
+ "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.7.tgz",
+ "integrity": "sha512-4It2mxPSr4OGn4HSQWGmhFMsNFGfFVhWeRPCRwbH972Ek2pzfGRZtb0pJ4Ze6oIzcyh2jw7nUDa6qGlWofgd9g==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "lodash": "^4.17.21"
+ },
+ "engines": {
+ "node": ">=v16"
+ }
+ },
+ "node_modules/@sapphire/snowflake": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.3.tgz",
+ "integrity": "sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=v14.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
"node_modules/@scure/base": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz",
@@ -1415,7 +1576,6 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz",
"integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==",
"license": "MIT",
- "peer": true,
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -1463,6 +1623,15 @@
"integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==",
"license": "MIT"
},
+ "node_modules/@types/ws": {
+ "version": "8.5.12",
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz",
+ "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@typescript-eslint/parser": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz",
@@ -2959,6 +3128,16 @@
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
"license": "ISC"
},
+ "node_modules/@vladfrangu/async_event_emitter": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.4.6.tgz",
+ "integrity": "sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=v14.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
"node_modules/@webassemblyjs/ast": {
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
@@ -4286,6 +4465,44 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/discord-api-types": {
+ "version": "0.37.83",
+ "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.83.tgz",
+ "integrity": "sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==",
+ "license": "MIT"
+ },
+ "node_modules/discord.js": {
+ "version": "14.15.3",
+ "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.15.3.tgz",
+ "integrity": "sha512-/UJDQO10VuU6wQPglA4kz2bw2ngeeSbogiIPx/TsnctfzV/tNf+q+i1HlgtX1OGpeOBpJH9erZQNO5oRM2uAtQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@discordjs/builders": "^1.8.2",
+ "@discordjs/collection": "1.5.3",
+ "@discordjs/formatters": "^0.4.0",
+ "@discordjs/rest": "^2.3.0",
+ "@discordjs/util": "^1.1.0",
+ "@discordjs/ws": "^1.1.1",
+ "@sapphire/snowflake": "3.5.3",
+ "discord-api-types": "0.37.83",
+ "fast-deep-equal": "3.1.3",
+ "lodash.snakecase": "4.1.1",
+ "tslib": "2.6.2",
+ "undici": "6.13.0"
+ },
+ "engines": {
+ "node": ">=16.11.0"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/discord.js/node_modules/tslib": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
+ "license": "0BSD"
+ },
"node_modules/dlv": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
@@ -7281,6 +7498,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "license": "MIT"
+ },
"node_modules/lodash.castarray": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
@@ -7302,6 +7525,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/lodash.snakecase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
+ "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==",
+ "license": "MIT"
+ },
"node_modules/longest-streak": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
@@ -7333,6 +7562,12 @@
"yallist": "^3.0.2"
}
},
+ "node_modules/magic-bytes.js": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz",
+ "integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==",
+ "license": "MIT"
+ },
"node_modules/markdown-table": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz",
@@ -11174,6 +11409,12 @@
"dev": true,
"license": "Apache-2.0"
},
+ "node_modules/ts-mixer": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz",
+ "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==",
+ "license": "MIT"
+ },
"node_modules/tsconfig-paths": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
@@ -11373,12 +11614,20 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/undici": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.13.0.tgz",
+ "integrity": "sha512-Q2rtqmZWrbP8nePMq7mOJIN98M0fYvSgV89vwl/BQRT4mDOeY2GXZngfGpcBBhtky3woM7G24wZV3Q304Bv6cw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0"
+ }
+ },
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/unified": {
"version": "11.0.5",
@@ -12093,6 +12342,27 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/ws": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
+ "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
"node_modules/yaeti": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
diff --git a/package.json b/package.json
index 08fca98..92462fd 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"@uiw/react-md-editor": "^3.11.0",
"axios": "^1.7.2",
"bech32": "^2.0.0",
+ "discord.js": "^14.15.3",
"light-bolt11-decoder": "^3.1.1",
"next": "14.2.5",
"next-auth": "^4.24.7",
diff --git a/src/pages/_app.js b/src/pages/_app.js
index a7a4081..ee76374 100644
--- a/src/pages/_app.js
+++ b/src/pages/_app.js
@@ -5,8 +5,9 @@ import { ToastProvider } from '@/hooks/useToast';
import { SessionProvider } from "next-auth/react"
import Layout from '@/components/Layout';
import '@/styles/globals.css'
-// import 'primereact/resources/themes/lara-dark-indigo/theme.css';
import 'primereact/resources/themes/lara-dark-blue/theme.css'
+import 'primereact/resources/primereact.min.css';
+import 'primeicons/primeicons.css';
import "@uiw/react-md-editor/markdown-editor.css";
import "@uiw/react-markdown-preview/markdown.css";
import Sidebar from '@/components/sidebar/Sidebar';
diff --git a/src/pages/api/discord-messages.js b/src/pages/api/discord-messages.js
new file mode 100644
index 0000000..a0a670a
--- /dev/null
+++ b/src/pages/api/discord-messages.js
@@ -0,0 +1,53 @@
+import { Client, GatewayIntentBits } from 'discord.js';
+
+const BOT_TOKEN = process.env.DISCORD_BOT_TOKEN;
+
+let client = null;
+
+async function initializeClient() {
+ if (!client) {
+ client = new Client({
+ intents: [
+ GatewayIntentBits.Guilds,
+ GatewayIntentBits.GuildMessages,
+ GatewayIntentBits.MessageContent
+ ]
+ });
+ await client.login(BOT_TOKEN);
+ }
+ return client;
+}
+
+export default async function handler(req, res) {
+ try {
+ const client = await initializeClient();
+
+ const channels = ['🤝general', '🌀random', '❓help', '🛠project-ideas', '🙌show-it-off', '🤡memes', '🧠learning'];
+ const messages = [];
+
+ for (const channelName of channels) {
+ const channel = client.channels.cache.find(ch => ch.name === channelName);
+ if (channel) {
+ const channelMessages = await channel.messages.fetch({ limit: 5 });
+ messages.push(...channelMessages.map(msg => ({
+ id: msg.id,
+ content: msg.content,
+ author: msg.author.username,
+ avatar: msg.author.avatarURL(),
+ channel: msg.channel.name,
+ channelId: msg.channel.id,
+ timestamp: msg.createdAt
+ })));
+ }
+ }
+
+ const filteredMessages = messages.filter(msg => msg.content.length > 0);
+ filteredMessages.sort((a, b) => b.timestamp - a.timestamp);
+
+ res.setHeader('Cache-Control', 's-maxage=60, stale-while-revalidate');
+ res.status(200).json(filteredMessages.slice(0, 50));
+ } catch (error) {
+ console.error(error);
+ res.status(500).json({ error: 'An error occurred while fetching messages' });
+ }
+}
diff --git a/src/pages/feed.js b/src/pages/feed.js
new file mode 100644
index 0000000..8a9fe62
--- /dev/null
+++ b/src/pages/feed.js
@@ -0,0 +1,83 @@
+import React from 'react';
+import { Card } from 'primereact/card';
+import { Avatar } from 'primereact/avatar';
+import { Tag } from 'primereact/tag';
+import { Button } from 'primereact/button';
+import { ProgressSpinner } from 'primereact/progressspinner';
+import { useQuery } from '@tanstack/react-query';
+
+const fetchDiscordMessages = async () => {
+ const response = await fetch('/api/discord-messages');
+ if (!response.ok) {
+ throw new Error('Failed to fetch messages');
+ }
+ return response.json();
+};
+
+const Feed = () => {
+ const { data, error, isLoading } = useQuery({
+ queryKey: ['discordMessages'],
+ queryFn: fetchDiscordMessages,
+ staleTime: 60000, // 1 minute
+ refetchInterval: 60000, // Refetch every minute
+ });
+
+ if (isLoading) {
+ return
{message.author}
+{message.content}
+