Move discord bot out of packages directory

This commit is contained in:
Jackson Harper
2024-03-19 16:19:44 +08:00
parent e47e169402
commit aa137319b3
8 changed files with 0 additions and 0 deletions

2
pkg/discord/.env.test Normal file
View File

@ -0,0 +1,2 @@
API_ENV=local
DISCORD_BOT_KEY=BlaBlaBla

56
pkg/discord/.eslintrc Normal file
View File

@ -0,0 +1,56 @@
{
"extends": "eslint:recommended",
"env": {
"node": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 2021,
"project": "tsconfig.json"
},
"rules": {
"arrow-spacing": ["warn", { "before": true, "after": true }],
"brace-style": ["error", "stroustrup", { "allowSingleLine": true }],
"comma-dangle": ["warn", {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "never"
}],
"comma-spacing": "error",
"comma-style": "error",
"curly": ["error", "multi-line", "consistent"],
"dot-location": ["error", "property"],
"handle-callback-err": "off",
"indent": ["warn", 2],
"keyword-spacing": "error",
"max-nested-callbacks": ["error", { "max": 4 }],
"max-statements-per-line": ["error", { "max": 2 }],
"no-console": "off",
"no-empty-function": "error",
"no-floating-decimal": "error",
"no-inline-comments": "error",
"no-lonely-if": "error",
"no-multi-spaces": "error",
"no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }],
"no-shadow": ["error", { "allow": ["err", "resolve", "reject"] }],
"no-trailing-spaces": ["error"],
"no-var": "error",
"object-curly-spacing": ["error", "always"],
"prefer-const": "error",
"quotes": ["error", "single"],
"semi": ["warn", "never"],
"space-before-blocks": "error",
"space-before-function-paren": ["error", {
"anonymous": "never",
"named": "never",
"asyncArrow": "always"
}],
"space-in-parens": "error",
"space-infix-ops": "error",
"space-unary-ops": "error",
"spaced-comment": "error",
"yoda": "error"
}
}

33
pkg/discord/Dockerfile Normal file
View File

@ -0,0 +1,33 @@
FROM node:18.16 as builder
WORKDIR /app
RUN apt-get update && apt-get install -y g++ make python3
COPY package.json .
COPY yarn.lock .
COPY tsconfig.json .
COPY .prettierrc .
COPY .eslintrc .
COPY /packages/discord/src ./packages/discord/src
COPY /packages/discord/package.json ./packages/discord/package.json
COPY /packages/discord/tsconfig.json ./packages/discord/tsconfig.json
RUN yarn install --pure-lockfile
RUN yarn workspace @omnivore/discord build
FROM node:18.16 as runner
WORKDIR /app
ENV NODE_ENV production
COPY --from=builder /app/packages/discord/dist /app/packages/discord/dist
COPY --from=builder /app/packages/discord/package.json /app/packages/discord/package.json
COPY --from=builder /app/packages/discord/node_modules /app/packages/discord/node_modules
COPY --from=builder /app/node_modules /app/node_modules
COPY --from=builder /app/package.json /app/package.json
CMD ["yarn", "workspace", "@omnivore/discord", "start"]

22
pkg/discord/package.json Normal file
View File

@ -0,0 +1,22 @@
{
"name": "@omnivore/discord",
"version": "1.0.0",
"description": "A Discord Bot to extract features to add to Community Picks",
"scripts": {
"build": "tsc",
"dev": "ts-node-dev --files src/index.ts",
"start": "node dist/index.js",
"lint": "eslint src --ext ts,js,tsx,jsx",
"lint:fix": "eslint src --fix --ext ts,js,tsx,jsx",
"test:typecheck": "tsc --noEmit"
},
"dependencies": {
"@google-cloud/pubsub": "^4.0.0",
"discord.js": "^14.14.1",
"dotenv": "^16.4.5",
"typescript": "^5.4.2",
"typescript-eslint": "^7.1.1"
},
"author": "",
"license": "ISC"
}

94
pkg/discord/src/index.ts Normal file
View File

@ -0,0 +1,94 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import {
Client,
Partials,
GatewayIntentBits,
Events,
MessageReaction,
User,
Embed,
PartialMessageReaction,
PartialUser,
} from 'discord.js'
import { PubSub } from '@google-cloud/pubsub'
import { OmnivoreArticle } from './types/OmnivoreArticle'
import { slugify } from 'voca'
import * as dotenv from 'dotenv'
dotenv.config()
const client = new Client({
partials: [Partials.Message, Partials.Reaction],
intents: [
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.Guilds,
],
})
const pubSubClient = new PubSub()
// Will have missed people here
const VALID_USERS = new Set([
'danielprindii',
'riiku',
'hongbowu',
'mollydot',
'jackson.harper',
'podginator',
])
const TOPIC_NAME = 'discordCommunityArticles'
client.once(Events.ClientReady, () => {
console.log('Ready!')
})
const createMessageFromEmbed = (embed: Embed): OmnivoreArticle | undefined => {
if (!embed.url || !embed.title || !embed.description) {
return undefined
}
return {
slug: slugify(embed.url),
title: embed.title,
description: embed.description,
image: embed.thumbnail?.url,
url: embed.url,
authors: embed.author?.name ?? new URL(embed.url).host,
publishedAt: new Date(),
site: embed.url,
type: 'community',
}
}
client.on(
Events.MessageReactionAdd,
async (
props: MessageReaction | PartialMessageReaction,
user: User | PartialUser
): Promise<void> => {
const emoji = props.emoji.name
const message = props.message.partial
? await props.message.fetch(true)
: props.message
const embed = message.embeds[0]
const userName = user.username
if (emoji === '🦥' && userName && VALID_USERS.has(userName) && embed) {
const jsonMessage = createMessageFromEmbed(embed)
if (message) {
await pubSubClient
.topic(TOPIC_NAME)
.publishMessage({ json: jsonMessage })
}
}
}
)
client.login(process.env.DISCORD_BOT_KEY).catch((error) => {
console.log('error logging in:', error)
})

View File

@ -0,0 +1,11 @@
export type OmnivoreArticle = {
slug: string
title: string
description: string
image?: string
authors: string
site: string
url: string
publishedAt: Date
type: 'community'
}

14
pkg/discord/tsconfig.json Normal file
View File

@ -0,0 +1,14 @@
{
"extends": "./../../tsconfig.json",
"compileOnSave": false,
"include": ["src/**/*"],
"ts-node": {
"files": true
},
"exclude": ["**/node_modules"],
"compilerOptions": {
"baseUrl": "./",
"outDir": "dist",
}
}

51
pkg/discord/tslint.json Normal file
View File

@ -0,0 +1,51 @@
{
"extends": "tslint:recommended",
"rulesDirectory": ["codelyzer"],
"rules": {
"array-type": false,
"arrow-parens": false,
"deprecation": {
"severity": "warn"
},
"import-blacklist": [true, "rxjs/Rx"],
"interface-name": false,
"max-classes-per-file": false,
"max-line-length": [true, 140],
"member-access": false,
"member-ordering": [
true,
{
"order": [
"static-field",
"instance-field",
"static-method",
"instance-method"
]
}
],
"no-consecutive-blank-lines": false,
"no-console": [true, "debug", "info", "time", "timeEnd", "trace"],
"no-empty": false,
"no-inferrable-types": [true, "ignore-params"],
"no-non-null-assertion": true,
"no-redundant-jsdoc": true,
"no-switch-case-fall-through": true,
"no-use-before-declare": true,
"no-var-requires": false,
"object-literal-key-quotes": [true, "as-needed"],
"object-literal-sort-keys": false,
"ordered-imports": false,
"quotemark": [true, "single"],
"trailing-comma": false,
"no-output-on-prefix": true,
"no-inputs-metadata-property": true,
"no-outputs-metadata-property": true,
"no-host-metadata-property": true,
"no-input-rename": true,
"no-output-rename": true,
"use-life-cycle-interface": true,
"use-pipe-transform-interface": true,
"component-class-suffix": true,
"directive-class-suffix": true
}
}