main
suhas 2 years ago
commit 404412da9e

@ -0,0 +1,9 @@
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

@ -0,0 +1,45 @@
module.exports = {
env: {
commonjs: true,
es6: true,
node: true
},
extends: ['eslint:recommended', 'prettier/@typescript-eslint', 'plugin:prettier/recommended'],
globals: {
NodeJS: true,
BigInt: true
},
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 6,
sourceType: 'module'
},
plugins: ['@typescript-eslint'],
rules: {
'prettier/prettier': 'warn',
'no-cond-assign': [2, 'except-parens'],
'no-unused-vars': 0,
'@typescript-eslint/no-unused-vars': 1,
'no-empty': [
'error',
{
allowEmptyCatch: true
}
],
'prefer-const': [
'warn',
{
destructuring: 'all'
}
],
'spaced-comment': 'warn'
},
overrides: [
{
files: ['slash-up.config.js'],
env: {
node: true
}
}
]
};

15
.gitignore vendored

@ -0,0 +1,15 @@
# Packages
node_modules/
yarn.lock
package_lock.json
# Log files
logs/
*.log
# Miscellaneous
.tmp/
.vscode/**/*
!.vscode/extensions.json
.env
dist/

@ -0,0 +1,8 @@
{
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"useTabs": false,
"trailingComma": "none",
"printWidth": 120
}

@ -0,0 +1,8 @@
{
"recommendations": [
"deepscan.vscode-deepscan",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"editorconfig.editorconfig"
]
}

@ -0,0 +1,29 @@
# slash-create-template in TypeScript
This templates helps you in creating slash commands in TypeScript from a webserver.
| [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/Snazzah/slash-create-template/tree/typescript) | [![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template/GL2qbv?referralCode=snazzah) |
|:-:|:-:|
## Installation
```sh
npx slash-up init typescript slash-commands
cd slash-commands
# edit variables in the ".env" file!
# Create and edit commands in the `commands` folder
npx slash-up sync
yarn build
yarn start
```
### From Railway/Heroku
For Railway and Heroku users, you must sync commands locally to push any command changes to Discord. You can do this by using `slash-up sync` within your Git repository.
Heroku users will have their commands synced when they initially deploy to Heroku.
### Using PM2
```sh
npm i -g pm2
# Follow the installation process above
pm2 start pm2.json
pm2 dump # recommended
```

@ -0,0 +1,21 @@
{
"name": "/create (TypeScript)",
"description": "Deploy a slash-create server for Discord interactions.",
"repository": "https://github.com/Snazzah/slash-create-template/tree/typescript",
"logo": "https://slash-create.js.org/static/logo-nomargin.png",
"scripts": {
"postdeploy": "npx slash-up sync"
},
"env": {
"DISCORD_APP_ID": {
"description": "The application ID of the Discord app"
},
"DISCORD_PUBLIC_KEY": {
"description": "The public key of the Discord app"
},
"DISCORD_BOT_TOKEN": {
"description": "The bot token of the Discord app"
}
},
"keywords": ["node", "fastify", "discord", "interactions"]
}

1739
err.txt

File diff suppressed because it is too large Load Diff

@ -0,0 +1,8 @@
> slash-create-template@1.0.0 start
> cd dist && node index.js
03/12 12:47:34 info Registered command hello
ready!
03/12 12:47:35 info Commands synced!
03/12 12:47:47 info ZeroMomentum#6560 (435206857276260353) ran command hello

@ -0,0 +1,40 @@
{
"name": "slash-create-template",
"version": "1.0.0",
"description": "A template for slash-create",
"main": "dist/index.js",
"scripts": {
"sync": "slash-up sync",
"sync:dev": "slash-up sync -e development",
"start": "cd dist && node index.js",
"build": "npx tsc",
"lint": "npx eslint --ext .ts ./src",
"lint:fix": "npx eslint --ext .ts ./src --fix"
},
"dependencies": {
"@prisma/client": "^4.11.0",
"cat-loggr": "^1.1.0",
"discord.js": "^14.7.1",
"dotenv": "^8.2.0",
"fastify": "^3.9.2",
"node-fetch": "^3.3.1",
"robert": "^2.6.5",
"slash-create": "^5.2.0",
"stream": "^0.0.2",
"undici": "^5.20.0"
},
"devDependencies": {
"@types/express": "^4.17.11",
"@types/node": "^14.14.37",
"@typescript-eslint/eslint-plugin": "^4.19.0",
"@typescript-eslint/parser": "^4.19.0",
"eslint": "^7.15.0",
"eslint-config-prettier": "^7.0.0",
"eslint-plugin-prettier": "^3.3.0",
"prettier": "^2.2.1",
"prisma": "^4.11.0",
"slash-up": "^1.0.11",
"ts-node": "^9.1.1",
"typescript": "^4.2.3"
}
}

@ -0,0 +1,9 @@
{
"apps": [
{
"name": "slash-commands",
"script": "node",
"args": "dist/index.js"
}
]
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,30 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model GuildConfig {
id String @id
welcome_message String @default("Hello %USER%!")
welcome_channel String?
daily_message_text String @default("daily message")
daily_message_channel String?
daily_message_time DateTime @default(now()) @db.Timetz
users User[]
}
model User {
id String
guild GuildConfig @relation(fields: [guild_id], references: [id])
guild_id String
messages Int @default(0)
@@id([id, guild_id])
}

@ -0,0 +1,19 @@
// This is the slash-up config file.
// Make sure to fill in "token" and "applicationId" before using.
// You can also use environment variables from the ".env" file if any.
module.exports = {
// The Token of the Discord bot
token: process.env.TOKEN,
// The Application ID of the Discord bot
applicationId: process.env.APPLICATION_ID,
// This is where the path to command files are, .ts files are supported!
commandPath: './src/commands',
// You can use different environments with --env (-e)
env: {
development: {
// The "globalToGuild" option makes global commands sync to the specified guild instead.
globalToGuild: process.env.DEVELOPMENT_GUILD_ID
}
}
};

@ -0,0 +1,27 @@
import { PrismaClient } from '@prisma/client'
import { SlashCommand, SlashCreator, CommandContext, MessageEmbed } from 'slash-create'
export default class LeaderboardCommand extends SlashCommand {
constructor(creator: SlashCreator) {
super(creator, {
name: 'leaderboard',
description: 'see top 10 messages'
})
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async run(ctx: CommandContext) {
const prisma = new PrismaClient()
const users = await prisma.user.findMany({
where: { guild_id: ctx.guildID },
take: 10,
orderBy: { messages: 'desc' }
})
let st = ''
for (const u of users) {
let uu = await this.client.users.fetch(u.id)
st += `${uu.username}#${uu.discriminator} - ${u.messages} message(s)\n`
}
return st
}
}

@ -0,0 +1,34 @@
import { CommandContext, CommandOptionType, SlashCommand, SlashCreator } from 'slash-create'
import { PrismaClient } from '@prisma/client'
export default class MessagesCommand extends SlashCommand {
constructor(creator: SlashCreator) {
super(creator, {
name: 'messages',
description: 'show message count, either for yourself, or someone else',
options: [
{
name: 'user',
description: 'person to show messages for (blank shows your own)',
required: false,
type: CommandOptionType.USER
}
]
})
}
async run(ctx: CommandContext) {
const prisma = new PrismaClient()
if (ctx.options.user == null) {
const u = await prisma.user.findFirst({ where: { id: ctx.member?.id, guild: { id: ctx.guildID } } })
if (!u) return `you have no messages!`
return `you have ${u.messages} message(s)`
} else {
const uid = ctx.options.user
const u = await prisma.user.findFirst({ where: { id: uid, guild: { id: ctx.guildID } } })
if (!u) return `this user has no messages!`
const uu = await this.client.users.fetch(u.id)
return `${uu.username}#${uu.discriminator} has ${u.messages} message(s)`
}
}
}

@ -0,0 +1,15 @@
import { SlashCommand, SlashCreator, CommandContext } from 'slash-create';
export default class PingCommand extends SlashCommand {
constructor(creator: SlashCreator) {
super(creator, {
name: 'ping',
description: 'pongs'
});
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async run(_ctx: CommandContext) {
return `pong from ${this.client.user.tag}!`;
}
}

@ -0,0 +1,23 @@
/* eslint-disable prettier/prettier */
import { SlashCommand, SlashCreator, CommandOptionType, CommandContext } from 'slash-create';
export default class StockCommand extends SlashCommand {
constructor(creator: SlashCreator) {
super(creator, {
name: 'stock',
description: 'checks stock price',
options: [{ type: CommandOptionType.STRING, name: 'ticker', description: 'the ticker to check', required: true }]
});
}
async run(ctx: CommandContext) {
const tkr = ctx.options.ticker
const req = await fetch(`https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${tkr}&apikey=8O1INVBY11E0GRGC`)
const info = await req.json()
if (Object.keys(info['Global Quote']).length == 0) {
return `stock not found!`
}
const i = info['Global Quote']
return `stock info for ${i['01. symbol']} - OPEN: ${i['02. open']} - PRICE: ${i['05. price']} - % CHANGE: ${i['10. change percent']}`
}
}

@ -0,0 +1,79 @@
import dotenv from 'dotenv'
import { SlashCreator, GatewayServer } from 'slash-create'
import path from 'path'
import CatLoggr from 'cat-loggr/ts'
import { Client, GatewayDispatchEvents, Events, Guild, Message } from 'discord.js'
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
const client = new Client({ intents: [131071] })
let dotenvPath = path.join(process.cwd(), '.env')
if (path.parse(process.cwd()).name === 'dist') dotenvPath = path.join(process.cwd(), '..', '.env')
dotenv.config({ path: dotenvPath })
const logger = new CatLoggr().setLevel(process.env.COMMANDS_DEBUG === 'true' ? 'debug' : 'info')
const creator = new SlashCreator({
client,
applicationID: process.env.APPLICATION_ID ?? 'AASDF',
publicKey: process.env.PUBLIC_KEY,
token: process.env.TOKEN
})
creator.on('debug', (message) => logger.log(message))
creator.on('warn', (message) => logger.warn(message))
creator.on('error', (error) => logger.error(error))
creator.on('synced', () => logger.info('Commands synced!'))
creator.on('commandRun', (command, _, ctx) =>
logger.info(`${ctx.user.username}#${ctx.user.discriminator} (${ctx.user.id}) ran command ${command.commandName}`)
)
creator.on('commandRegister', (command) => logger.info(`Registered command ${command.commandName}`))
creator.on('commandError', (command, error) => logger.error(`Command ${command.commandName}:`, error))
creator
.withServer(new GatewayServer((handler) => client.ws.on(GatewayDispatchEvents.InteractionCreate, handler)))
.registerCommandsIn(path.join(__dirname, 'commands'))
.syncCommands()
client.once('ready', async () => console.log('ready!'))
client.on(Events.GuildCreate, async (g: Guild) => {
await prisma.guildConfig.create({
data: {
id: g.id
}
})
})
client.on(Events.MessageCreate, async (msg: Message) => {
if (!msg.guild || msg.author == client.user) return
const u = await prisma.user.findFirst({
where: {
guild_id: msg.guild.id,
id: msg.author.id
}
})
if (!u) {
await prisma.user.create({
data: {
guild_id: msg.guild.id,
id: msg.author.id,
messages: 1
}
})
return
}
const newMessagesCount = (u.messages ?? 0) + 1
await prisma.user.update({
where: {
id_guild_id: { id: msg.author.id, guild_id: msg.guild.id }
},
data: {
messages: newMessagesCount
}
})
})
client.login(process.env.TOKEN)

@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "dist",
"strict": false,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"typeRoots": ["./node_modules/@types", "types"]
},
"include": [
"./src/**/*"
],
"exclude": [
"node_modules",
"dist",
"testing",
]
}
Loading…
Cancel
Save