Skip to content
Open
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
34 changes: 17 additions & 17 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,39 @@ jobs:
name: main
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: install node v16
uses: actions/setup-node@v1
- uses: actions/checkout@v4
- name: install node
uses: actions/setup-node@v4
with:
node-version: 16
node-version: 24

- name: yarn install
run: yarn install
- name: build
run: yarn run build
- name: lint
run: yarn run lint

- name: Set up Docker Buildx
if: contains(github.ref, 'master')
uses: docker/setup-buildx-action@v1

- name: Login to Github Container Registry
if: contains(github.ref, 'master')
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GHCR_TOKEN }}
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GHCR_TOKEN }}

- name: Build and push
if: contains(github.ref, 'master')
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
push: true
cache-from: type=registry,ref=ghcr.io/typescript-community/bot:latest
cache-to: type=inline
tags: |
ghcr.io/typescript-community/bot:latest
context: .
file: ./Dockerfile
push: true
cache-from: type=registry,ref=ghcr.io/typescript-community/bot:latest
cache-to: type=inline
tags: |
ghcr.io/typescript-community/bot:latest
3 changes: 0 additions & 3 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx pretty-quick --staged
File renamed without changes.
18 changes: 9 additions & 9 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"cSpell.words": [
"algoliasearch",
"autorole",
"Cooldown",
"leaderboard",
"twoslash",
"twoslasher"
]
"typescript.tsdk": "node_modules/typescript/lib",
"cSpell.words": [
"algoliasearch",
"autorole",
"Cooldown",
"leaderboard",
"twoslash",
"twoslasher"
]
}
20 changes: 12 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# 2026-03-29

- Update Node from 16 to 24, update deps, migrate to ESM.

# 2022-12-16

- Remove `!close`, update `!helper` to include thread tags.
- Remove `!close`, update `!helper` to include thread tags.

# 2022-11-19

- Removed `HELP_CATEGORY`, `GENERAL_HELP_CHANNEL` environment variables.
- Added `HELP_FORUM_CHANNEL`, `HELP_REQUESTS_CHANNEL` environment variables.
- Updated how to get help and how to give help channel content to not use embeds.
- Updated to Discord.js 14, removed Cookiecord to prevent future delays in updating versions.
- The bot will now react on the configured autorole messages to indicate available roles.
- Unhandled rejections will now only be ignored if `NODE_ENV` is set to `production`.
- Removed admin `checkThreads` command as using it would result in the bot checking for closed threads twice as often until restarted.
- Removed `HELP_CATEGORY`, `GENERAL_HELP_CHANNEL` environment variables.
- Added `HELP_FORUM_CHANNEL`, `HELP_REQUESTS_CHANNEL` environment variables.
- Updated how to get help and how to give help channel content to not use embeds.
- Updated to Discord.js 14, removed Cookiecord to prevent future delays in updating versions.
- The bot will now react on the configured autorole messages to indicate available roles.
- Unhandled rejections will now only be ignored if `NODE_ENV` is set to `production`.
- Removed admin `checkThreads` command as using it would result in the bot checking for closed threads twice as often until restarted.
13 changes: 12 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM node:16.18.1-alpine
# Two stage build to avoid installing dev dependencies in deployed image
FROM node:24.14.1-alpine AS build
WORKDIR /usr/src/app

COPY yarn.lock ./
Expand All @@ -10,4 +11,14 @@ COPY . .

RUN yarn build

FROM node:24.14.1-alpine AS prod
WORKDIR /usr/src/app

COPY yarn.lock ./
COPY package.json ./

RUN yarn --production

COPY --from=build /usr/src/app/dist dist

CMD [ "node", "dist/index.js" ]
9 changes: 1 addition & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ _A utility bot built for the [TypeScript Community Discord Server](https://disco

# Contributing

See the [documentation](https://cookiecord.js.org/) for the framework we use.
See the [documentation](https://discordjs.guide/) for the framework we use.

We also have a docker-compose.yml for development, along with a .env.example.

**A quick note about the help channel system:** Please only use it if you have a large server (10k+ members) as it will likely inconvenience your members rather than benefit them. We used a static channel system (#help-1 and #help-2) up until around 9,000 members, when we started to see issues arising (many questions being asked on top of each other without answers).

## Thanks!

- [ckie](https://github.com/ckiee) for writing the base for the bot!
- [Python Discord](https://github.com/python-discord) for heavily influencing our help channel system.
4 changes: 1 addition & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# Development compose file
version: '3'

services:
bot:
image: node:16
image: node:24.14.1-alpine
command: yarn start
depends_on:
- postgres
Expand Down
50 changes: 24 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,38 @@
"version": "0.0.1",
"description": "Typescript Community Bot",
"main": "dist/index.js",
"type": "module",
"dependencies": {
"@typescript/twoslash": "^3.2.12",
"algoliasearch": "^4.14.2",
"discord.js": "^14.6.0",
"dotenv-safe": "^8.2.0",
"html-entities": "^2.3.3",
"lz-string": "^1.4.4",
"npm-registry-fetch": "^14.0.2",
"parse-duration": "^1.0.2",
"pg": "^8.8.0",
"prettier": "^2.7.1",
"pretty-ms": "^8.0.0",
"tar": "^6.1.12",
"typeorm": "^0.3.10",
"undici": "^5.12.0"
"algoliasearch": "^5.50.0",
"discord.js": "^14.25.1",
"dotenv": "^8.6.0",
"dotenv-safe": "^9.1.0",
"html-entities": "^2.6.0",
"lz-string": "^1.5.0",
"npm-registry-fetch": "^19.1.1",
"parse-duration": "^2.1.5",
"pg": "^8.20.0",
"prettier": "^3.8.1",
"pretty-ms": "^9.3.0",
"tar": "^7.5.13",
"typeorm": "^0.3.28"
},
"devDependencies": {
"@types/dotenv-safe": "8.1.2",
"@types/lz-string": "1.3.34",
"@types/node": "16.18.3",
"@types/npm-registry-fetch": "8.0.4",
"@types/prettier": "2.7.1",
"@types/tar": "6.1.3",
"@types/ws": "8.5.3",
"husky": "^8.0.2",
"pretty-quick": "^3.1.3",
"ts-node-dev": "^2.0.0",
"typescript": "^4.9.3"
"@types/dotenv-safe": "9.1.0",
"@types/node": "25.5.0",
"@types/npm-registry-fetch": "8.0.9",
"@types/ws": "8.18.1",
"husky": "^9.1.7",
"pretty-quick": "^4.2.2",
"tsx": "^4.21.0",
"typescript": "^6.0.2"
},
"scripts": {
"start": "ts-node-dev --respawn src",
"start": "tsx watch src/index.ts",
"build": "tsc",
"lint": "prettier --check \"src/**/*.ts\"",
"lint:fix": "prettier \"src/**/*.ts\" --write ",
"prepare": "husky install"
"prepare": "husky"
}
}
2 changes: 1 addition & 1 deletion src/bot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Message, Client, User, GuildMember } from 'discord.js';
import { botAdmins, prefixes, trustedRoleId } from './env';
import { botAdmins, prefixes, trustedRoleId } from './env.js';

export interface CommandRegistration {
aliases: string[];
Expand Down
10 changes: 5 additions & 5 deletions src/db.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { DataSource } from 'typeorm';
import { dbUrl } from './env';
import { Rep } from './entities/Rep';
import { HelpThread } from './entities/HelpThread';
import { Snippet } from './entities/Snippet';
import { dbUrl } from './env.js';
import { Rep } from './entities/Rep.js';
import { HelpThread } from './entities/HelpThread.js';
import { Snippet } from './entities/Snippet.js';

let db: DataSource | undefined;
export async function getDB() {
Expand All @@ -18,7 +18,7 @@ export async function getDB() {
rejectUnauthorized: false,
},
},
}
}
: {};

db = new DataSource({
Expand Down
10 changes: 5 additions & 5 deletions src/entities/HelpThread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@ import { BaseEntity, Column, Entity, PrimaryColumn } from 'typeorm';

@Entity()
export class HelpThread extends BaseEntity {
@PrimaryColumn()
@PrimaryColumn({ type: String })
threadId!: string;

@Column()
@Column({ type: String })
ownerId!: string;

// When @helper was last pinged
@Column({ nullable: true })
@Column({ nullable: true, type: String })
helperTimestamp?: string;

/**
* When the title was last set, exists only for backwards compat
* @deprecated
*/
@Column({ nullable: true })
@Column({ nullable: true, type: String })
titleSetTimestamp?: string;

/**
* The id of the original message, exists only for backwards compat
* @deprecated
*/
@Column({ nullable: true })
@Column({ nullable: true, type: String })
origMessageId?: string;
}
12 changes: 6 additions & 6 deletions src/entities/Rep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@ import { Entity, BaseEntity, PrimaryColumn, Column } from 'typeorm';

@Entity()
export class Rep extends BaseEntity {
@PrimaryColumn()
@PrimaryColumn({ type: String })
messageId!: string;

@Column()
@Column({ type: String })
date!: string;

@Column()
@Column({ type: String })
channel!: string;

@Column()
@Column({ type: Number })
amount!: number;

@Column()
@Column({ type: String })
recipient!: string;

@Column()
@Column({ type: String })
initialGiver!: string;
}
18 changes: 9 additions & 9 deletions src/entities/Snippet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,30 @@ import { BaseEntity, Column, Entity, PrimaryColumn } from 'typeorm';

@Entity()
export class Snippet extends BaseEntity {
@PrimaryColumn()
@PrimaryColumn({ type: String })
id!: string;

@Column()
@Column({ type: String })
owner!: string;

@Column()
@Column({ type: Number })
uses!: number;

@Column({ nullable: true })
@Column({ nullable: true, type: String })
content?: string;

@Column({ nullable: true })
@Column({ nullable: true, type: String })
title?: string;

@Column({ nullable: true })
@Column({ nullable: true, type: String })
description?: string;

@Column({ nullable: true })
@Column({ nullable: true, type: Number })
color?: number;

@Column({ nullable: true })
@Column({ nullable: true, type: String })
image?: string;

@Column({ nullable: true })
@Column({ nullable: true, type: String })
url?: string;
}
30 changes: 15 additions & 15 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { Client, GatewayIntentBits, Partials } from 'discord.js';
import { Bot } from './bot';
import { getDB } from './db';
import { token } from './env';
import { hookLog } from './log';
import { Bot } from './bot.js';
import { getDB } from './db.js';
import { token } from './env.js';
import { hookLog } from './log.js';

import { autoroleModule } from './modules/autorole';
import { etcModule } from './modules/etc';
import { handbookModule } from './modules/handbook';
import { helpModule } from './modules/help';
import { modModule } from './modules/mod';
import { playgroundModule } from './modules/playground';
import { repModule } from './modules/rep';
import { twoslashModule } from './modules/twoslash';
import { snippetModule } from './modules/snippet';
import { helpForumModule } from './modules/helpForum';
import { autoroleModule } from './modules/autorole.js';
import { etcModule } from './modules/etc.js';
import { handbookModule } from './modules/handbook.js';
import { helpModule } from './modules/help.js';
import { modModule } from './modules/mod.js';
import { playgroundModule } from './modules/playground.js';
import { repModule } from './modules/rep.js';
import { twoslashModule } from './modules/twoslash.js';
import { snippetModule } from './modules/snippet.js';
import { helpForumModule } from './modules/helpForum.js';

const client = new Client({
partials: [
Expand All @@ -37,7 +37,7 @@ const client = new Client({

getDB().then(() => client.login(token));

client.on('ready', async () => {
client.on('clientReady', async client => {
const bot = new Bot(client);
console.log(`Logged in as ${client.user?.tag}`);
await hookLog(client);
Expand Down
Loading
Loading