Skip to content

Commit

Permalink
feature: dashboard developed
Browse files Browse the repository at this point in the history
  • Loading branch information
onury5506 committed Mar 29, 2023
1 parent 900471f commit e524b83
Show file tree
Hide file tree
Showing 20 changed files with 1,763 additions and 14 deletions.
8 changes: 2 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
DISCORD_BOT_TOKEN=.....
DISCORD_CLIENT_ID=.....
OPENAI_API_KEY=....
OPENAI_MODEL=gpt-3.5-turbo
MAX_TOKEN=1000
ENABLE_DIRECT_MESSAGES=false
CONVERSATION_MEMORY_SECONDS=300
CONVERSATION_START_PROMPT=false
USE_EMBED=true
DASHBOARD_USERNAME=admin
DASHBOARD_PASSWORD=admin
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ The bot now uses the official ChatGpt API. :tada: This means you can expect more
However, if you prefer to use the unofficial API version, you can always find it on the "non_official_api" branch.
Thank you for using our bot and contributing to the project!

We now have a convenient dashboard for configuring the bot, eliminating the need to restart it to modify settings. The bot runs on port 8080. Additionally, there are plans to integrate usage statistics into the dashboard.

commands :

* You can ask anything with ```/ask 'question'```
Expand All @@ -15,6 +17,8 @@ commands :

Screenshots :

![Screenshot_6](https://raw.githubusercontent.com/onury5506/Discord-ChatGPT-Bot/master/screen_shot/Screenshot_5.jpg)

![Screenshot_1](https://raw.githubusercontent.com/onury5506/Discord-ChatGPT-Bot/master/screen_shot/Screenshot_1.jpg)


Expand Down Expand Up @@ -50,6 +54,6 @@ npm start
docker build -t discordchatgpt .
docker run discordchatgpt
docker run -p 8080:8080 -v discordchatgptconfig:/discordChatGpt/configFile discordchatgpt
```
3 changes: 3 additions & 0 deletions chatgpt/chatgpt.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ chatGPT.sendMessage = async function (prompt) {
body: JSON.stringify(data)
})
res = await res.json()
if(res.error){
console.error(res)
}

return {
text: res.choices[0].message.content.trim(),
Expand Down
12 changes: 10 additions & 2 deletions config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ function get(key){
}

function set(key,value){
if(config[key] == undefined){
console.log("Invalid config key : ",key)
return;
}
config[key] = value
}

Expand All @@ -27,7 +31,6 @@ function save(){
}

function load(){

fs.readFile(PATH).then((data)=>{
try{
data = data.toString()
Expand All @@ -41,9 +44,14 @@ function load(){
})
}

function getFullConfig(){
return {...config}
}

export default {
save,
load,
set,
get
get,
getFullConfig
}
40 changes: 40 additions & 0 deletions dashboard/dasboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import express from "express";
import cookieParser from "cookie-parser";
import bodyParser from "body-parser";

import API_ROUTER from "./routes/api.js";

const app = express()

app.use(express.static("./dashboard/public"))
app.use(cookieParser())
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

let init = false
export const JWT_SECRET = generateSecret()
function generateSecret(){
let chars = "qwertyuopasdfghjklizxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"
let secret = ""
for(let i=0;i<32;i++){
secret += chars[Math.floor(Math.random()*chars.length)]
}
return "secret" //secret
}

app.use("/api",API_ROUTER)

app.get("/logout",(req,res)=>{
res.cookie("auth","")
res.redirect("/")
})

export function initDashboard(){
if(init){
return;
}

app.listen(8080,()=>{
console.log(new Date() + " Dashboard listening on port 8080")
})
}
16 changes: 16 additions & 0 deletions dashboard/middleware/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import jwt from "jsonwebtoken";
import { JWT_SECRET } from "../dasboard.js";

export default function auth(req,res,next){
let cookie = req.cookies.auth
if (!cookie) {
return res.sendStatus(403)
}

try {
jwt.verify(cookie, JWT_SECRET);
next()
} catch (e) {
res.sendStatus(403)
}
}
72 changes: 72 additions & 0 deletions dashboard/public/css/dashboard.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
body{
margin: 0;
padding: 0;
background: black;
color: white;
}

#navbar{
display: flex;
justify-content: space-around;
align-items: center;
padding: 10px;
background-color: rgba(0, 0, 0, 0.1);
position: sticky;
top: 0;
backdrop-filter: blur(3px);
}

#navbar img{
height: 80px;
cursor: pointer;
}

#configlist{
max-width: 1000px;
margin: auto;
}

.config{
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid white;
}

.config label{
font-size: 26px;
font-weight: bold;
}

.config span{
font-size: 20px;
color: #dddddd;
}

.config input[type=checkbox]{
width: 30px;
height: 30px;
margin: auto;
}
a{
text-decoration: none;
}
button{
font-size: 20px;
cursor: pointer;
padding: 5px 20px;
}

#save_button{
display: block;
margin: auto;
}

#oauth_discord{
display: block;
color: white;
font-size: 20px;
margin: 20px 0;
}
47 changes: 47 additions & 0 deletions dashboard/public/css/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
body{
margin: 0;
padding: 0;
display: block;
background-color: black;
color: white;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}

#loginform{
border: 1px solid white;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 450px;
height: 450px;
gap: 30px;
font-size: 24px;
}

#loginform input{
font-size: 24px;
width: 60%;
}

#loginform label{
display: inline-block;
font-size: 24px;
width: 30%;
}

.field{
text-align: center;
}

#loginform img{
height: 100px;
}

#loginform button{
font-size: 20px;
padding: 3px 20px;
}
66 changes: 66 additions & 0 deletions dashboard/public/dashboard.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ChatGPT Discord Bot</title>

<script src="/js/auth.js"></script>
<script src="/js/dashboard.js" defer></script>
<link rel="stylesheet" href="/css/dashboard.css">
</head>

<body>
<div id="navbar">
<img src="/images/logo.png" />
<h1>Discord ChatGPT Bot</h1>
<a href="/logout">
<button>Logout</button>
</a>
<a href="https://github.com/onury5506/Discord-ChatGPT-Bot" target="_blank">
<img src="/images/github.png" />
</a>
</div>
<div id="configlist">
<a target="_blank" id="oauth_discord"></a>
<div class="config">
<label for="OPENAI_MODEL">OPENAI_MODEL</label>
<span>Which OPENAI model does the bot use?</span>
<input name="OPENAI_MODEL" list="OPENAI_MODELS" id="OPENAI_MODEL" />
<datalist id="OPENAI_MODELS">
<option value="gpt-3.5-turbo">
<option value="gpt-3.5-turbo-0301">
<option value="gpt-4">
<option value="gpt-4-0314">
<option value="gpt-4-32k">
<option value="gpt-4-32k-0314">
</datalist>
</div>
<div class="config">
<label for="MAX_TOKEN">MAX_TOKEN</label>
<span>What is the maximum number of tokens allowed for a prompt?</span>
<input name="MAX_TOKEN" id="MAX_TOKEN" type="number" />
</div>
<div class="config">
<label for="ENABLE_DIRECT_MESSAGES">ENABLE_DIRECT_MESSAGES</label>
<span>Is it possible for users to send direct messages to the bot?</span>
<input name="ENABLE_DIRECT_MESSAGES" id="ENABLE_DIRECT_MESSAGES" type="checkbox" />
</div>
<div class="config">
<label for="CONVERSATION_START_PROMPT">CONVERSATION_START_PROMPT</label>
<span>What is the maximum number of tokens allowed for a prompt?</span>
<input name="CONVERSATION_START_PROMPT" id="CONVERSATION_START_PROMPT"
placeholder="You are helpful assistant" />
</div>
<div class="config">
<label for="USE_EMBED">USE_EMBED</label>
<span>Generate embed for "/ask" answers.</span>
<input name="USE_EMBED" id="USE_EMBED" type="checkbox" />
</div>
<button id="save_button">SAVE</button>
</div>
</body>

</html>
Binary file added dashboard/public/images/github.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added dashboard/public/images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions dashboard/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ChatGPT Discord Bot</title>

<script src="/js/auth.js"></script>
<script src="/js/index.js" defer></script>
<link rel="stylesheet" href="/css/index.css">
</head>

<body>
<form method="post" action="/api/login" id="loginform">
<img src="images/logo.png"/>
<div class="field">
<label for="username">Username</label>
<input id="username" name="username" />
</div>
<div class="field">
<label for="password">Password</label>
<input id="password" type="password" name="password" />
</div>
<button type="submit">LOGIN</button>
</form>
</body>

</html>
20 changes: 20 additions & 0 deletions dashboard/public/js/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
function checkAuth() {
return new Promise(async (resolve) => {
let res = await fetch("/api/checkauth", {
credentials: "include"
})
if (res.status == 200) {
resolve(true)
} else {
resolve(false)
}
})
}

checkAuth().then(res => {
if (res && window.location.pathname == "/") {
window.location = "/dashboard.html"
} else if (!res && window.location.pathname != "/") {
window.location = "/"
}
})
Loading

0 comments on commit e524b83

Please sign in to comment.