Skip to content

Commit

Permalink
Fix/threads fixes (#46)
Browse files Browse the repository at this point in the history
* fix: errors in threads plugin, encrypts data for chat-gpt api/org
* feat: sends errors to monitoring channel
  • Loading branch information
en3sis authored May 10, 2023
1 parent 46a78c3 commit b3f428a
Show file tree
Hide file tree
Showing 29 changed files with 340 additions and 145 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Hans is built with a modular architecture that makes it easy to add and remove f

Built with [Discord.JS](https://discord.js.org/#/), [TypeScript](https://www.typescriptlang.org/), and lots of ❤️

## Invite hans to your server
## Invite to server

Bring Hans to your Discord server and start using his available features right away by inviting it to your server [here 🔗](https://discord.com/api/oauth2/authorize?client_id=403523619222847488&permissions=0&scope=bot%20applications.commands). It's using the latest `hans:nightly` image with the latest features.

Expand Down
Empty file added config.json
Empty file.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
"prepare": "npx husky install",
"slash": "yarn build && node build/utils/deploy-commands.js",
"slashDev": "export ISDEV=true && yarn build_dev && node build/utils/deploy-commands.js",
"test": "ts-mocha -p ./tsconfig.json ./tests/**/*.spec.ts",
"test:dev": "ts-mocha ./tests/**/*.spec.ts -w --watch-files '**/*.ts'"
"test": "ts-mocha -p ./tsconfig.json ./tests/**/*.spec.ts -r dotenv/config",
"test:dev": "ts-mocha ./tests/**/*.spec.ts -w --watch-files '**/*.ts' -r dotenv/config"
},
"author": "en3sis",
"repository": {
Expand Down
3 changes: 2 additions & 1 deletion src/commands/about.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ module.exports = {
const createsEmbed = getUserInformation(member)
return await interaction.reply({ embeds: [createsEmbed] })
} catch (error) {
console.error('❌ ERROR: Command -> activities ', error)
console.error('❌ Command: about: ', error)
throw new Error(error)
}
},
}
16 changes: 10 additions & 6 deletions src/commands/ask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { SlashCommandBuilder } from '@discordjs/builders'
import { CommandInteraction } from 'discord.js'
import { resolveGuildPlugins } from '../controllers/bot/plugins.controller'
import { gpt3Controller } from '../controllers/plugins/chat-gpt3.controller'
import { DEFAULT_COLOR } from '../utils/colors'
import { decrypt } from '../utils/crypto'

// https://discord.js.org/#/docs/main/stable/class/CommandInteraction?scrollTo=replied
module.exports = {
Expand All @@ -22,16 +24,17 @@ module.exports = {
if (!enabled)
return await interaction.editReply('This feature is not enabled for this server.')

if (!data.premium && metadata?.apiKey === null)
if (!data.premium && metadata?.api_key === null)
return await interaction.editReply(
'Your API-Key & Organization is not set. Please set it using `/plugins chatGtp` command.',
)

if (data.premium) {
if (data.premium || metadata?.api_key) {
const prompt = interaction.options.get('prompt')!.value as string

const API_KEY = data.premium ? process.env.OPENAI_API_KEY : metadata.apiKey
const ORGANIZATION = data.premium ? process.env.OPENAI_ORGANIZATION : metadata.organization
const API_KEY = data.premium ? process.env.OPENAI_API_KEY : decrypt(metadata.api_key)

const ORGANIZATION = data.premium ? process.env.OPENAI_ORGANIZATION : decrypt(metadata.org)

const answer = await gpt3Controller(prompt, API_KEY, ORGANIZATION)
await interaction.editReply({
Expand All @@ -55,15 +58,16 @@ module.exports = {
6,
)}`,
},
color: 0x73ec8e,
color: DEFAULT_COLOR,
},
],
})
} else {
return await interaction.editReply('This feature is only available for premium servers.')
}
} catch (error) {
console.log('❌ Command: ask(): ', error)
console.error('❌ Command: ask: ', error)
throw new Error(error)
}
},
}
3 changes: 2 additions & 1 deletion src/commands/invite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ module.exports = {
const inviteEmbed = inviteBot(interaction.client)
await interaction.reply({ ...inviteEmbed, fetchReply: true })
} catch (error) {
console.log('❌ invite(): ', error)
console.error('❌ Command: invite: ', error)
throw new Error(error)
}
},
}
23 changes: 14 additions & 9 deletions src/commands/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,21 @@ module.exports = {
string.setName('text').setDescription('Your sentence to be mocked').setRequired(true),
),
async execute(interaction: CommandInteraction) {
const text = interaction.options.get('text')!.value as string
try {
const text = interaction.options.get('text')!.value as string

await interaction.channel.send(
text
.split('')
.map((letter, i) => (i % 2 == 0 ? letter.toUpperCase() : letter.toLowerCase()))
.join(''),
)
await interaction.channel.send('<:mock:1016362569088376924>')
await interaction.channel.send(
text
.split('')
.map((letter, i) => (i % 2 == 0 ? letter.toUpperCase() : letter.toLowerCase()))
.join(''),
)
await interaction.channel.send('<:mock:1016362569088376924>')

await interaction.reply({ content: 'Done :P', ephemeral: true })
await interaction.reply({ content: 'Done :P', ephemeral: true })
} catch (error) {
console.error('❌ Command: mock: ', error)
throw new Error(error)
}
},
}
3 changes: 2 additions & 1 deletion src/commands/moderation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ https: module.exports = {
await purgeMessages(interaction)
}
} catch (error) {
console.log('❌ ERROR: recipe(): ', error)
console.error('❌ Command: moderation: ', error)
throw new Error(error)
}
},
}
18 changes: 11 additions & 7 deletions src/commands/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,19 @@ module.exports = {
.setName('chatgpt')
.setDescription('Sets your own ChatGPT API-KEY & Organization')
.addStringOption((option) =>
option.setName('api_key').setDescription('Your ChatGPT API-KEY').setRequired(true),
option
.setName('api_key')
.setDescription(
'Your ChatGPT API-KEY. It will be encrypted with a aes-256-cbc algorithm',
)
.setRequired(true),
)
.addStringOption((option) =>
option
.setName('organization_id')
.setDescription('Your ChatGPT Organization ID')
.setDescription(
'Your ChatGPT Organization ID. It will be encrypted with a aes-256-cbc algorithm',
)
.setRequired(true),
),
)
Expand Down Expand Up @@ -126,11 +133,8 @@ module.exports = {
})
}
} catch (error) {
console.log(error)
return interaction.reply({
content: 'There was an error while executing this command!',
ephemeral: true,
})
console.error('❌ Command: plugins: ', error)
throw new Error(error)
}
},
}
49 changes: 27 additions & 22 deletions src/commands/support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,32 @@ module.exports = {
.setName('support')
.setDescription('Display Bot support information'),
async execute(interaction: CommandInteraction) {
await interaction.reply({
embeds: [
{
title: '📨 Hans support',
description: `Please feel free to join Hans Discord server for support. \n[🔗 Discord Server](${Hans.settings.perma_invite})`,
fields: [
{
name: '💢 Any issues?',
value:
'[Open an Issue](https://github.com/en3sis/hans/issues/new?assignees=&labels=bug&template=bug_report.md&title=%5BBUG%5D)',
inline: true,
},
{
name: '💡 Any ideas?',
value:
'[Send a suggestion](https://github.com/en3sis/hans/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=%5BFEATURE%5D)',
inline: true,
},
],
},
],
})
try {
await interaction.reply({
embeds: [
{
title: '📨 Hans support',
description: `Please feel free to join Hans Discord server for support. \n[🔗 Discord Server](${Hans.settings.perma_invite})`,
fields: [
{
name: '💢 Any issues?',
value:
'[Open an Issue](https://github.com/en3sis/hans/issues/new?assignees=&labels=bug&template=bug_report.md&title=%5BBUG%5D)',
inline: true,
},
{
name: '💡 Any ideas?',
value:
'[Send a suggestion](https://github.com/en3sis/hans/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=%5BFEATURE%5D)',
inline: true,
},
],
},
],
})
} catch (error) {
console.log('❌ Command: support: ', error)
throw new Error(error)
}
},
}
99 changes: 52 additions & 47 deletions src/commands/weather.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,56 +11,61 @@ module.exports = {
string.setName('city').setDescription('City name').setRequired(true),
),
async execute(interaction: CommandInteraction) {
const { location, current } = await WeatherController(
interaction.options.get('city')!.value as string,
)
try {
const { location, current } = await WeatherController(
interaction.options.get('city')!.value as string,
)

await interaction.reply({
embeds: [
{
title: `Weather in ${location.name}, ${location.country} `,
description: `${current.condition.text} with **${current.humidity}%** humidity and **${current.wind_kph} km/h** winds and UV index of **${current.uv}** `,
fields: [
{
name: ' 🌡 Temp:',
value: `**${Math.floor(current.temp_c)} °C**`,
inline: true,
await interaction.reply({
embeds: [
{
title: `Weather in ${location.name}, ${location.country} `,
description: `${current.condition.text} with **${current.humidity}%** humidity and **${current.wind_kph} km/h** winds and UV index of **${current.uv}** `,
fields: [
{
name: ' 🌡 Temp:',
value: `**${Math.floor(current.temp_c)} °C**`,
inline: true,
},
{
name: '🤷🏻‍♂️ Feels:',
value: `**${Math.floor(current.feelslike_c)} °C**`,
inline: true,
},
{
name: '🌧 Precip:',
value: `**${Math.floor(current.precip_mm)} mm**`,
inline: true,
},
{
name: '☁️ Cloudcover:',
value: `${current.cloud} %`,
inline: true,
},
{
name: '👀 Visibility:',
value: `${current.vis_km} KM`,
inline: true,
},
{
name: '🕐 Local time:',
value: `${location.localtime}`,
inline: true,
},
],
footer: {
text: `For NA: Temp: ${current.temp_f} F | Feels: ${current.feelslike_f} F | 🕑 Last update at ${current.last_updated}`,
},
{
name: '🤷🏻‍♂️ Feels:',
value: `**${Math.floor(current.feelslike_c)} °C**`,
inline: true,
thumbnail: {
url: `https:${current.condition.icon}`,
},
{
name: '🌧 Precip:',
value: `**${Math.floor(current.precip_mm)} mm**`,
inline: true,
},
{
name: '☁️ Cloudcover:',
value: `${current.cloud} %`,
inline: true,
},
{
name: '👀 Visibility:',
value: `${current.vis_km} KM`,
inline: true,
},
{
name: '🕐 Local time:',
value: `${location.localtime}`,
inline: true,
},
],
footer: {
text: `For NA: Temp: ${current.temp_f} F | Feels: ${current.feelslike_f} F | 🕑 Last update at ${current.last_updated}`,
},
thumbnail: {
url: `https:${current.condition.icon}`,
color: 0x3f51b5,
},
color: 0x3f51b5,
},
],
})
],
})
} catch (error) {
console.error('❌ Command: weather: ', error)
throw new Error(error)
}
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ export const insertConfiguration = async () => {
bot_guild_id: `${process.env.BOT_GUILD_ID}`,
bot_id: `${process.env.DISCORD_CLIENT_ID}`,
created_at: new Date().toISOString(),
disable_commands: [],
discord_client_id: `${process.env.DISCORD_CLIENT_ID}`,
id: 1,
name: 'Hans',
notify_channel_id: '905157473671975002',
monitoring_channel_id: '1105791856207462438', // Sends errors to the monitoring channel, useful to debug in production
perma_invite: 'https://discord.com/invite/sMmbbSefwH',
website: '',
website: 'https://github.com/en3sis/hans',
},
{ onConflict: 'id' },
)
Expand Down
3 changes: 2 additions & 1 deletion src/controllers/bot/plugins.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CommandInteraction } from 'discord.js'
import supabase from '../../libs/supabase'
import { pluginsList } from '../../models/plugins.model'
import { encrypt } from '../../utils/crypto'
import { GuildPlugin } from './guilds.controller'

export const insertGuildPlugin = async (guild_id: string) => {
Expand Down Expand Up @@ -137,7 +138,7 @@ export const pluginChatGPTSettings = async (
try {
const { error } = await supabase
.from('guilds-plugins')
.update({ metadata: { api_key, org } })
.update({ metadata: { api_key: encrypt(api_key), org: encrypt(org) } })
.eq('name', 'chatGtp')
.eq('owner', interaction.guildId)

Expand Down
1 change: 0 additions & 1 deletion src/controllers/plugins/chat-gpt3.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ interface IOpenAIRequestSettings {
organization: string
}

// TODO: Keep history for 1 round per user per conversation
const history = [] as ChatCompletionRequestMessage[]
/**
* OpenAI API request
Expand Down
Loading

0 comments on commit b3f428a

Please sign in to comment.