Skip to content

Commit d4a488c

Browse files
feat: ask ai discord bot (aaif-goose#6842)
Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>
1 parent cf3023b commit d4a488c

23 files changed

Lines changed: 1262 additions & 0 deletions
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Publish Ask AI Bot Docker Image
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- "services/ask-ai-bot/**"
9+
- "documentation/**"
10+
- ".github/workflows/publish-ask-ai-bot.yml"
11+
workflow_dispatch:
12+
13+
permissions:
14+
contents: read
15+
packages: write
16+
17+
jobs:
18+
docker:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
23+
24+
- name: Set up Docker Buildx
25+
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
26+
27+
- name: Log in to GitHub Container Registry
28+
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
29+
with:
30+
registry: ghcr.io
31+
username: ${{ github.actor }}
32+
password: ${{ secrets.GITHUB_TOKEN }}
33+
34+
- name: Extract metadata
35+
id: meta
36+
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
37+
with:
38+
images: ghcr.io/${{ github.repository_owner }}/ask-ai-bot
39+
tags: |
40+
type=ref,event=branch
41+
type=sha,prefix=sha-
42+
type=raw,value=latest,enable={{is_default_branch}}
43+
44+
- name: Build and push Docker image
45+
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # pin@v6.18.0
46+
with:
47+
context: .
48+
file: services/ask-ai-bot/Dockerfile
49+
push: true
50+
tags: ${{ steps.meta.outputs.tags }}
51+
labels: ${{ steps.meta.outputs.labels }}
52+
cache-from: type=gha
53+
cache-to: type=gha,mode=max
54+
platforms: linux/amd64,linux/arm64

services/ask-ai-bot/.dockerignore

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Include only what's needed from the monorepo root context
2+
# This file is used when building from the repo root
3+
4+
# Exclude everything by default
5+
*
6+
7+
# Include the bot source
8+
!services/ask-ai-bot/
9+
10+
# Include documentation (only docs subfolder needed)
11+
!documentation/docs/
12+
13+
# Exclude unnecessary files from included directories
14+
services/ask-ai-bot/node_modules
15+
services/ask-ai-bot/dist
16+
services/ask-ai-bot/.env
17+
services/ask-ai-bot/.discraft
18+
**/*.tsbuildinfo
19+
20+
# Exclude large assets from docs that aren't needed for search
21+
documentation/docs/assets

services/ask-ai-bot/.env.example

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# From `Bot > Token` | https://discord.com/developers/applications
2+
DISCORD_TOKEN=unset
3+
# From `General Information > App ID` | https://discord.com/developers/applications
4+
DISCORD_APP_ID=unset
5+
6+
# Channel ID where the bot should create threads for questions
7+
QUESTION_CHANNEL_ID=1397240187041349753
8+
9+
# OpenRouter API Key | https://openrouter.ai/settings/keys
10+
OPENROUTER_API_KEY=sk-1234
11+
# AI Model (default: google/gemini-3-flash-preview)
12+
AI_MODEL=google/gemini-3-flash-preview
13+
14+
# Path to documentation directory (default: ./docs in Docker, for local dev use ../../documentation/docs)
15+
DOCS_PATH=../../documentation/docs

services/ask-ai-bot/.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
dist
2+
node_modules
3+
package-lock.json
4+
bun.lockb
5+
yarn.lock
6+
pnpm-lock.yaml
7+
.env
8+
.discraft
9+
10+
*.tsbuildinfo

services/ask-ai-bot/Dockerfile

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
FROM oven/bun:1 AS base
2+
WORKDIR /app
3+
4+
# Install dependencies
5+
FROM base AS deps
6+
COPY services/ask-ai-bot/package.json services/ask-ai-bot/bun.lock ./
7+
RUN bun install --frozen-lockfile
8+
9+
# Build stage
10+
FROM base AS build
11+
COPY --from=deps /app/node_modules ./node_modules
12+
COPY services/ask-ai-bot/ ./
13+
RUN bun run build
14+
15+
# Production stage
16+
FROM base AS production
17+
ENV NODE_ENV=production
18+
ENV DOCS_PATH=/app/docs
19+
20+
COPY --from=build /app/dist ./dist
21+
COPY --from=build /app/node_modules ./node_modules
22+
COPY --from=build /app/package.json ./
23+
24+
# Copy documentation (only docs/ subdirectory with markdown files)
25+
COPY documentation/docs ./docs
26+
27+
# Empty index.ts for discraft start to detect
28+
RUN touch index.ts
29+
30+
CMD ["bun", "run", "start"]

services/ask-ai-bot/bun.lock

Lines changed: 214 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

services/ask-ai-bot/clients/ai.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { openrouter } from "@openrouter/ai-sdk-provider";
2+
3+
const modelName = process.env.AI_MODEL || "google/gemini-3-flash-preview";
4+
5+
export const model = openrouter(modelName);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Client, GatewayIntentBits } from "discord.js";
2+
3+
const client = new Client({
4+
/* Sensible defaults, you can add or remove intents as needed. */
5+
intents: [
6+
GatewayIntentBits.Guilds,
7+
GatewayIntentBits.GuildMessages,
8+
GatewayIntentBits.MessageContent,
9+
],
10+
});
11+
12+
export default client;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
2+
3+
export default {
4+
data: new SlashCommandBuilder().setName("ping").setDescription("Ping!"),
5+
6+
async execute(data: { interaction: ChatInputCommandInteraction }) {
7+
const interaction = data.interaction;
8+
await interaction.reply("Bot is online.");
9+
},
10+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Client, Events } from "discord.js";
2+
import { logger } from "../utils/logger";
3+
4+
export default {
5+
event: Events.Error,
6+
handler: (client: Client, error: Error) => {
7+
logger.error("An error occurred:", error);
8+
},
9+
};

0 commit comments

Comments
 (0)