Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Vedinsoh committed Dec 23, 2022
2 parents ed5427f + 126d64d commit d6d4fe9
Show file tree
Hide file tree
Showing 70 changed files with 1,262 additions and 1,178 deletions.
2 changes: 1 addition & 1 deletion .docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM node:18-alpine

WORKDIR /usr/src/app
WORKDIR /app

COPY package.json .
COPY yarn.lock .
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Continuous integration

on:
push:
branches:
- main
- develop
pull_request:

jobs:
lint-and-build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: 18
cache: yarn

- name: Install dependencies
run: yarn install --immutable

- name: Lint
run: yarn run lint

- name: Build
run: yarn run build
554 changes: 280 additions & 274 deletions .yarn/releases/yarn-3.2.4.cjs → .yarn/releases/yarn-3.3.0.cjs

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ nodeLinker: node-modules

plugins:
- path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs
spec: '@yarnpkg/plugin-typescript'
spec: "@yarnpkg/plugin-typescript"
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: '@yarnpkg/plugin-interactive-tools'
spec: "@yarnpkg/plugin-interactive-tools"

yarnPath: .yarn/releases/yarn-3.2.4.cjs
yarnPath: .yarn/releases/yarn-3.3.0.cjs
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@ You're free to host this bot on your own machine, but please keep in mind I will

Requirements:

- Node ^16.9.0
- Node ^18.12.0
- Yarn ^3.0.0
- Redis server ^7.0.0
4 changes: 2 additions & 2 deletions config.development.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"botAdmin": "150701861626839041",
"loggingLevel": "debug",
"stringLocale": "de-DE",
"presenceInterval": 15,
"urlDetection": {
"enabled": true,
"deferTimeout": 5
},
"spam": {
"antiSpam": {
"enabled": true,
"autoLeave": false,
"rateLimitsThreshold": 3,
"messagesThreshold": 40
}
}
4 changes: 2 additions & 2 deletions config.production.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"botAdmin": "150701861626839041",
"loggingLevel": "info",
"stringLocale": "de-DE",
"presenceInterval": 15,
"urlDetection": {
"enabled": true,
"deferTimeout": 5
},
"spam": {
"antiSpam": {
"enabled": true,
"autoLeave": true,
"rateLimitsThreshold": 3,
"messagesThreshold": 40
}
}
50 changes: 26 additions & 24 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"name": "discord-auto-publisher",
"version": "3.0.0",
"version": "4.0.0",
"description": "Automatically publish messages or news in your announcement channels!",
"author": "Forcellrus",
"author": "Vedinsoh",
"license": "GPL-3.0-or-later",
"homepage": "https://github.com/Forcellrus/Discord-Auto-Publisher#readme",
"homepage": "https://github.com/Vedinsoh/Discord-Auto-Publisher#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/Forcellrus/Discord-Auto-Publisher.git"
"url": "git+https://github.com/Vedinsoh/Discord-Auto-Publisher.git"
},
"bugs": {
"url": "https://github.com/Forcellrus/Discord-Auto-Publisher/issues"
"url": "https://github.com/Vedinsoh/Discord-Auto-Publisher/issues"
},
"keywords": [
"discord",
Expand All @@ -32,48 +32,50 @@
"dependencies": {
"bufferutil": "^4.0.7",
"cross-env": "^7.0.3",
"discord-hybrid-sharding": "^1.7.4",
"discord.js-light": "^4.10.0",
"discord-hybrid-sharding": "^1.7.5",
"discord.js": "^14.7.1",
"dotenv": "^16.0.3",
"glob": "^8.0.3",
"pino": "^8.7.0",
"p-queue": "^7.3.0",
"pino": "^8.8.0",
"pino-pretty": "^9.1.1",
"re2": "^1.17.7",
"redis": "^4.4.0",
"tsconfig-paths": "^4.1.0",
"re2": "^1.18.0",
"redis": "^4.5.1",
"tsconfig-paths": "^4.1.1",
"url-regex-safe": "^3.0.0",
"utf-8-validate": "^5.0.10",
"zod": "^3.19.1"
"zod": "^3.20.2"
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^3.4.0",
"@sapphire/ts-config": "^3.3.4",
"@trivago/prettier-plugin-sort-imports": "^4.0.0",
"@types/glob": "^8.0.0",
"@types/node": "^18.11.9",
"@types/node": "^18.11.17",
"@types/url-regex-safe": "^1.0.0",
"@typescript-eslint/eslint-plugin": "^5.42.0",
"@typescript-eslint/parser": "^5.42.0",
"eslint": "^8.27.0",
"@typescript-eslint/eslint-plugin": "^5.47.0",
"@typescript-eslint/parser": "^5.47.0",
"eslint": "^8.30.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"prettier": "^2.7.1",
"tsc-watch": "^5.0.3",
"typescript": "^4.8.4"
"prettier": "^2.8.1",
"tsc-watch": "^6.0.0",
"typescript": "^4.9.4"
},
"imports": {
"#config": "./dist/config.js",
"#client": "./dist/AutoPublisher.js",
"#constants/*": "./dist/constants/*.js",
"#functions/*": "./dist/functions/*.js",
"#handlers": "./dist/handlers/*.js",
"#crosspost/*": "./dist/crosspost/*.js",
"#managers/*": "./dist/managers/*.js",
"#schemas/*": "./dist/schemas/*.js",
"#structures/*": "./dist/structures/*.js",
"#types/*": "./dist/types/*.js",
"#util/*": "./dist/util/*.js"
},
"engines": {
"node": "^16.9.0",
"node": "^18.12.0",
"npm": "please-use-yarn"
},
"packageManager": "[email protected]"
"type": "module",
"packageManager": "[email protected]"
}
32 changes: 20 additions & 12 deletions src/AutoPublisher.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
import Cluster from 'discord-hybrid-sharding';
import { Intents, Options } from 'discord.js-light';
import { AutoPublisherClient } from '#structures/Client';
import crosspostQueueFilter from '#util/crosspostQueueFilter';
import { CacheWithLimitsOptions, GatewayIntentBits as IntentBits, Options, Partials } from 'discord.js';
import gatewayQueueFilter from '#crosspost/gatewayQueueFilter';
import AutoPublisherClient from '#structures/Client';

type CacheOptions = CacheWithLimitsOptions & {
PermissionOverwriteManager: 0;
RoleManager: 0;
};

const { FLAGS } = Intents;
const shardData = Cluster.Client.getInfo();
const client = new AutoPublisherClient({
makeCache: Options.cacheWithLimits({
ApplicationCommandManager: 0,
AutoModerationRuleManager: 0,
BaseGuildEmojiManager: 0,
GuildChannelManager: Infinity,
GuildBanManager: 0,
GuildEmojiManager: 0,
GuildForumThreadManager: 0,
GuildInviteManager: 0,
GuildManager: Infinity,
GuildMemberManager: 0,
GuildStickerManager: 0,
GuildScheduledEventManager: 0,
GuildStickerManager: 0,
GuildTextThreadManager: 0,
MessageManager: 0,
PermissionOverwriteManager: 0,
PresenceManager: 0,
Expand All @@ -27,13 +33,15 @@ const client = new AutoPublisherClient({
ThreadMemberManager: 0,
UserManager: 0,
VoiceStateManager: 0,
}),
intents: [FLAGS.GUILDS, FLAGS.GUILD_MESSAGES, FLAGS.DIRECT_MESSAGES],
partials: ['CHANNEL'],
} as CacheOptions),
intents: [IntentBits.Guilds, IntentBits.GuildMessages, IntentBits.DirectMessages, IntentBits.MessageContent],
partials: [Partials.Channel],
shards: shardData.SHARD_LIST,
shardCount: shardData.TOTAL_SHARDS,
restGlobalRateLimit: 50,
rejectOnRateLimit: crosspostQueueFilter,
rest: {
globalRequestsPerSecond: 50,
rejectOnRateLimit: gatewayQueueFilter,
},
});

client.start();
Expand Down
2 changes: 1 addition & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dotenv/config';
import fs from 'node:fs';
import type z from 'zod';
import type { ConfigSchema } from '#schemas/ConfigSchema';
import type ConfigSchema from '#schemas/ConfigSchema';
import getConfigFilename from '#util/getConfigFilename';
import validateConfig from '#util/validateConfig';

Expand Down
3 changes: 0 additions & 3 deletions src/constants/pathPatterns.ts

This file was deleted.

4 changes: 3 additions & 1 deletion src/constants/redisDatabaseIds.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export default {
const redisDatabaseIds = {
BLACKLIST: 0,
RATE_LIMITS: 1,
SPAM_CHANNELS: 2,
};

export default redisDatabaseIds;
10 changes: 7 additions & 3 deletions src/constants/redisExpirations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export default {
RATE_LIMITS: 5 * 60,
SPAM_CHANNELS: 60 * 60,
import { minToSec } from '#util/timeConverters';

const redisExpirations: { [key: string]: number } = {
RATE_LIMITS: minToSec(5),
SPAM_CHANNELS: minToSec(60),
};

export default redisExpirations;
5 changes: 5 additions & 0 deletions src/constants/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const routes = {
crosspost: '/channels/:id/messages/:id/crosspost',
};

export default routes;
11 changes: 7 additions & 4 deletions src/constants/safeErrorCodes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
export default [
10003, // Unknown channel
50001, // Missing access
50013, // Missing permissions
const safeErrorCodes: number[] = [
10003, // * Unknown channel
40033, // * Already crossposted
50001, // * Missing access
50013, // * Missing permissions
];

export default safeErrorCodes;
28 changes: 28 additions & 0 deletions src/crosspost/crosspost.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { NewsChannel } from 'discord.js';
import client from '#client';
import safeErrorCodes from '#constants/safeErrorCodes';
import type { ReceivedMessage } from '#types/MessageTypes';
import logger from '#util/logger';
import { channelToString, guildToString } from '#util/stringFormatters';

const crosspost = async (message: ReceivedMessage) => {
const channel = message.channel as NewsChannel;

if (await client.rateLimits.isLimited(message)) return;

return message
.crosspost()
.then(() => {
logger.debug(
`Published ${message.id} in ${channelToString(channel)} - ${guildToString(message.guild, channel.guildId)}`
);
})
.catch((error) => {
if (Object.prototype.hasOwnProperty.call(error, 'code')) {
if (safeErrorCodes.includes(error.code)) return;
}
client.rateLimits.add(message);
});
};

export default crosspost;
8 changes: 8 additions & 0 deletions src/crosspost/gatewayQueueFilter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { RateLimitData } from 'discord.js';
import routes from '#constants/routes';

const gatewayQueueFilter = (data: RateLimitData): boolean => {
return data.method.toUpperCase() === 'POST' && routes.crosspost === data.route && !data.global;
};

export default gatewayQueueFilter;
21 changes: 21 additions & 0 deletions src/crosspost/handleCrosspost.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import urlRegex from 'url-regex-safe';
import client from '#client';
import config from '#config';
import type { ReceivedMessage } from '#types/MessageTypes';

const { urlDetection } = config;

const handleCrosspost = (message: ReceivedMessage) => {
if (urlDetection.enabled && message.content) {
const hasUrl = urlRegex({ strict: true, localhost: false }).test(message.content);
const hasEmbeds = !!message.embeds.length;

if (hasUrl && !hasEmbeds) {
return client.crosspostQueue.add(message, true);
}
}

return client.crosspostQueue.add(message);
};

export default handleCrosspost;
Loading

0 comments on commit d6d4fe9

Please sign in to comment.