Skip to content

Commit

Permalink
v2.4.0 - Added onProgress Typing Effect
Browse files Browse the repository at this point in the history
Some minor changes
Beautification
  • Loading branch information
itskdhere committed Feb 12, 2023
1 parent 7de1311 commit c3c6f3e
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 59 deletions.
22 changes: 16 additions & 6 deletions env.example → .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,32 @@
# ---------------------------------------:Environment Variables:------------------------------------
# --------------------------------------------------------------------------------------------------
# Discord BOT Credentials from "Discord Developer Portal"
DISCORD_CLIENT_ID=...
DISCORD_BOT_TOKEN=...
DISCORD_CLIENT_ID=
DISCORD_BOT_TOKEN=


# --------------------------------------------------------------------------------------------------
# For 'Google' login type provide the Gmail-ID and the google account password of the Gmail-ID
# For 'OpenAI' login type provide the email and password associated with your OpenAI account
EMAIL=...
PASSWORD=...
EMAIL=
PASSWORD=


# --------------------------------------------------------------------------------------------------
# Login Type ( Value: 'google' or 'openai' )
LOGIN_TYPE=...
LOGIN_TYPE=


# --------------------------------------------------------------------------------------------------
# ChatGPT Account Type ( Value: 'free' or 'pro' )
ACCOUNT_TYPE=...
ACCOUNT_TYPE=

# --------------------------------------------------------------------------------------------------
# Bot Typing Effect i.e Stream ChatGPT response in real-time ( Value: 'true' or 'false' )
# TYPING_EFFECT=true

# --------------------------------------------------------------------------------------------------
# Change these if you know what you're doing
DISCORD_MAX_RESPONSE_LENGTH=2000
UWU=true
CHATGPT_INITIAL_PROMPT=hi
5 changes: 4 additions & 1 deletion .github/note.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## Important !!

To run This **CodeQL** WorkFlow goto `YOUR_REPO_URL/actions`
### To Run These GitHub Actions WorkFlows:

- Goto the `Actions` tab of your forked repo, i.e. `YOUR_REPO_URL/actions`
- Then click I `understand my workflows, go ahead and enable them`
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ This BOT uses [ChatGPT-API v3](https://github.com/transitive-bullshit/chatgpt-ap
## ✨Features
🔥 Use slash command `/ask` to ask questions in any channel.

💥 This uses **puppeteer** to automate the login process. Auto Solve CAPTCHA ✨
✨ ChatGPT onProgress Typing Effect. Chalk, Figlet & Gradient-String for decoration.

💥 This uses **puppeteer** to automate the login process. Auto Solve CAPTCHA.

🔑 Uses Single ChatGPT Conversation Thread per Session.

Expand All @@ -44,7 +46,7 @@ This BOT uses [ChatGPT-API v3](https://github.com/transitive-bullshit/chatgpt-ap
- [Node.js v18](https://nodejs.org/)
- [Google Chrome](https://www.google.com/chrome/)
- [OpenAI Account](https://chat.openai.com/)
- Atleast 1vCPU , 0.5GB RAM and 0.5GB Storage (For the **BOT Only**)
- Atleast 1vCPU , 0.5GB RAM and 0.5GB Storage for the Bot.

### Steps:
0. Create **New Application** [BOT] from [Discord Developer Portal](https://discord.com/developers/applications) and add this to your Discord Server with proper *Bot Permissions* and *Privileged Gateway Intents*.
Expand All @@ -71,7 +73,12 @@ npm install
```bash
npm run start
```
6. Complete the **CAPTCHA** Manually *or* [Use This Automation](https://github.com/transitive-bullshit/chatgpt-api#captchas). If you're using Google Login then you can skip this step.
- *or,* During development:
```bash
npm run dev
```

6. Complete the **CAPTCHA** Manually *or* [Use This Automation](https://github.com/transitive-bullshit/chatgpt-api/tree/v3#captchas).

7. Use the BOT 🎉

Expand Down
110 changes: 66 additions & 44 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
// Imports
import dotenv from 'dotenv'; dotenv.config();
import { ChatGPTAPIBrowser } from 'chatgpt';
import { Client, GatewayIntentBits, REST, Routes, Partials, ActivityType} from 'discord.js';
import { Client, GatewayIntentBits, REST, Routes, Partials, ActivityType } from 'discord.js';
import axios from 'axios';
import chalk from 'chalk';
import figlet from 'figlet';
import gradient from 'gradient-string';

// Defines
const MAX_RESPONSE_LENGTH = 2000 // Discord Max 2000 Characters
let res; // ChatGPT Thread Identifier

// Discord Slash Commands Defines
Expand All @@ -31,7 +30,7 @@ const commands = [
}
];

// Initialize OpenAI Session & New ChatGPT Thread
// Initialize OpenAI Session
async function initOpenAI() {
const loginType = process.env.LOGIN_TYPE;
const accountType = process.env.ACCOUNT_TYPE;
Expand Down Expand Up @@ -77,7 +76,7 @@ async function initOpenAI() {
}
}

// Initialize Discord Application Commands
// Initialize Discord Application Commands & New ChatGPT Thread
async function initDiscordCommands(api) {
const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_BOT_TOKEN);
try {
Expand All @@ -90,26 +89,28 @@ async function initDiscordCommands(api) {
} catch (error) {
console.log(chalk.red(error));
}
res = await api.sendMessage('Hi'); // Init New Thread

res = await api.sendMessage(process.env.CHATGPT_INITIAL_PROMPT); // Init New Thread
}

// Main Function (Execution Starts Here)
// Main Function (Execution Starts From Here)
async function main() {
console.log(gradient.pastel.multiline(figlet.textSync('ChatGPT', {
font: 'univers',
horizontalLayout: 'default',
verticalLayout: 'default',
width: 100,
whitespaceBreak: true
})));
if (process.env.UWU === 'true') {
console.log(gradient.pastel.multiline(figlet.textSync('ChatGPT', {
font: 'univers',
horizontalLayout: 'default',
verticalLayout: 'default',
width: 100,
whitespaceBreak: true
})));
}

const chatGTP = await initOpenAI().catch(error => {
console.error(error)
process.exit()
})
const api = await initOpenAI().catch(error => {
console.error(error);
process.exit();
});

await initDiscordCommands(chatGTP).catch(e => { console.log(e) });
await initDiscordCommands(api).catch(e => { console.log(e) });

const client = new Client({
intents: [
Expand Down Expand Up @@ -139,12 +140,14 @@ async function main() {

client.user.setActivity(interaction.user.tag, { type: ActivityType.Watching });

interaction.channel.sendTyping();

switch (interaction.commandName) {
case "ask":
ask_Interaction_Handler(interaction)
ask_Interaction_Handler(interaction);
break;
case "ping":
ping_Interaction_Handler(interaction)
ping_Interaction_Handler(interaction);
break;
default:
await interaction.reply({ content: 'Command Not Found' });
Expand All @@ -165,17 +168,17 @@ async function main() {
console.log("UserId : " + interaction.user.id);
console.log("User : " + interaction.user.tag);
console.log("Question : " + question);
// TODO: send to DB

try {
await interaction.reply({ content: "ChatGPT Is Processing Your Question..." });
askQuestion(question, async (content) => {
await interaction.reply({ content: `${client.user.username} Is Processing Your Question...` });
askQuestion(question, interaction, async (content) => {
console.log("Response : " + content.response);
console.log("---------------End---------------");
if (content.length >= MAX_RESPONSE_LENGTH) {
await interaction.editReply({ content: "The answer to this question is very long, so I will answer by dm." });
if (content.length >= process.env.DISCORD_MAX_RESPONSE_LENGTH) {
await interaction.editReply({ content: "The answer to this question is very long, so I'll answer by DM." });
splitAndSendResponse(content.response, interaction.user);
} else {
await interaction.editReply(`${interaction.user.tag}: ${question}\n\nChatGPT: ${content.response}`);
await interaction.editReply(`**${interaction.user.tag}:** ${question}\n**${client.user.username}:** ${content.response}\n</>`);

This comment has been minimized.

Copy link
@davidecke

davidecke Feb 19, 2023

Contributor

@itskdhere, is there any specific reason that you added </> at the end of responses? Thanks

also, thanks for an excellent bot

This comment has been minimized.

Copy link
@itskdhere

itskdhere Feb 19, 2023

Author Owner

@itskdhere, is there any specific reason that you added </> at the end of responses? Thanks

If the Typing Effect is enabled and the bot fails to send the full response to the discord channel due to Discord's rate-limits, in this case the </> is useful to indicate if that's the end of the actual response or not.

also, thanks for an excellent bot

Welcome 😀

@davidecke

}
client.user.setActivity('/ask');
// TODO: send to DB
Expand All @@ -185,36 +188,51 @@ async function main() {
}
}

function askQuestion(question, cb) {
function askQuestion(question, interaction, cb) {
let tmr = setTimeout((e) => {
cb("Oppss, something went wrong! (Timeout)")
console.error(chalk.red(e))
}, 100000)

chatGTP.sendMessage(question, {
conversationId: res.conversationId,
parentMessageId: res.messageId
}).then((response) => {
clearTimeout(tmr)
res = response;
cb(response)
}).catch((err) => {
cb("Oppss, something went wrong! (Error)")
console.error(chalk.red("AskQuestion Error:" + err))
})
}, 100000);

if (process.env.TYPING_EFFECT === 'true') {
api.sendMessage(question, {
conversationId: res.conversationId,
parentMessageId: res.messageId,
onProgress: (partialResponse) => {
interaction.editReply(`**${interaction.user.tag}:** ${question}\n**${client.user.username}:** ${partialResponse?.response}`);
}
}).then((response) => {
clearTimeout(tmr);
res = response;
cb(response);
}).catch((err) => {
cb("Oppss, something went wrong! (Error)");
console.error(chalk.red("AskQuestion Error:" + err));
})
} else {
api.sendMessage(question, {
conversationId: res.conversationId,
parentMessageId: res.messageId
}).then((response) => {
clearTimeout(tmr);
res = response;
cb(response);
}).catch((err) => {
cb("Oppss, something went wrong! (Error)")
console.error(chalk.red("AskQuestion Error:" + err))
})
}
}

async function splitAndSendResponse(resp, user) {
while (resp.length > 0) {
let end = Math.min(MAX_RESPONSE_LENGTH, resp.length)
let end = Math.min(process.env.DISCORD_MAX_RESPONSE_LENGTH, resp.length)
await user.send(resp.slice(0, end))
resp = resp.slice(end, resp.length)
}
}
}

main() // Call Main function

// Discord Rate Limit Check
setInterval(() => {
axios
Expand All @@ -229,3 +247,7 @@ setInterval(() => {
});

}, 30000); // Check Every 30 Second

main() // Call Main function

// ---EoC---
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "chatgpt-discord-bot",
"version": "2.3.0",
"version": "2.4.0",
"description": "ChatGPT Discord BOT",
"author": "KD",
"license": "MIT",
Expand All @@ -9,7 +9,8 @@
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
"start": "node index.js",
"dev": "node --watch index.js"
},
"dependencies": {
"@types/node": "^18.0.6",
Expand All @@ -23,4 +24,4 @@
"node-fetch": "^3.2.6",
"puppeteer": "^19.5.2"
}
}
}

0 comments on commit c3c6f3e

Please sign in to comment.