Add functionality to create transactions
- Transactions work against the account balance - Needs helper functions for users - Needs more testing
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
const libCore = require("../libCore.js");
|
const { submitPromptTransaction } = require("../controllers/chatGptController");
|
||||||
const { SlashCommandBuilder } = require('discord.js');
|
const { SlashCommandBuilder } = require('discord.js');
|
||||||
const { DebugBuilder } = require("../utilities/debugBuilder");
|
const { DebugBuilder } = require("../utilities/debugBuilder");
|
||||||
const log = new DebugBuilder("server", "chat");
|
const log = new DebugBuilder("server", "chat");
|
||||||
|
const { EmbedBuilder } = require('discord.js');
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@@ -12,6 +13,10 @@ module.exports = {
|
|||||||
option.setName('prompt')
|
option.setName('prompt')
|
||||||
.setDescription('The prompt to be sent to ChatGPT')
|
.setDescription('The prompt to be sent to ChatGPT')
|
||||||
.setRequired(true))
|
.setRequired(true))
|
||||||
|
.addBooleanOption(option =>
|
||||||
|
option.setName('public')
|
||||||
|
.setDescription("Set this to false if you would like the message to only be visible to you.")
|
||||||
|
.setRequired(false))
|
||||||
.addNumberOption(option =>
|
.addNumberOption(option =>
|
||||||
option.setName('temperature')
|
option.setName('temperature')
|
||||||
.setDescription('Set the temperature, 0 = repetitive, 1 = random; Defaults to 0')
|
.setDescription('Set the temperature, 0 = repetitive, 1 = random; Defaults to 0')
|
||||||
@@ -20,23 +25,17 @@ module.exports = {
|
|||||||
option.setName('tokens')
|
option.setName('tokens')
|
||||||
.setDescription('The max amount of tokens to be spent')
|
.setDescription('The max amount of tokens to be spent')
|
||||||
.setRequired(false)),
|
.setRequired(false)),
|
||||||
example: "chat [tell me a story] [0.07] []", // Need to figure out the tokens
|
example: "chat [tell me a story] [0.07] [400]", // Need to figure out the tokens
|
||||||
isPrivileged: false,
|
isPrivileged: false,
|
||||||
requiresTokens: true,
|
requiresTokens: true,
|
||||||
defaultTokenUsage: 100,
|
defaultTokenUsage: 100,
|
||||||
deferInitialReply: true,
|
deferInitialReply: true,
|
||||||
async execute(interaction) {
|
async execute(interaction) {
|
||||||
try {
|
try {
|
||||||
var params = {};
|
submitPromptTransaction(interaction, async (err, result) => {
|
||||||
var promptText = interaction.options.getString('prompt');
|
if (err) throw err;
|
||||||
var temperature = interaction.options.getNumber('temperature');
|
await interaction.editReply({ content: `${interaction.member.user} ${result.promptResult}`, ephemeral: false });
|
||||||
var maxTokens = interaction.options.getNumber('tokens') ?? this.defaultTokenUsage;
|
});
|
||||||
|
|
||||||
if (temperature) params._temperature = temperature;
|
|
||||||
if (maxTokens) params._max_tokens = maxTokens;
|
|
||||||
|
|
||||||
var gptResponse = await libCore.getChat(promptText, params);
|
|
||||||
await interaction.editReply(`${interaction.member.user} ${gptResponse}`);
|
|
||||||
|
|
||||||
// Needs reply code to reply to the generation
|
// Needs reply code to reply to the generation
|
||||||
}catch(err){
|
}catch(err){
|
||||||
|
|||||||
@@ -36,6 +36,16 @@ exports.createAccount = (_discordAccountId, callback) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.withdrawBalance = async (_withdrawAmount, _accountId, callback) => {
|
||||||
|
userStorage.updateBalance('withdraw', _withdrawAmount, _accountId, async (err, result) => {
|
||||||
|
if (err) return callback(err, undefined);
|
||||||
|
|
||||||
|
if(result) return callback(undefined, result);
|
||||||
|
|
||||||
|
return callback(undefined, undefined);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
exports.verifyBalance = (_tokensToBeUsed, _accountId, callback) => {
|
exports.verifyBalance = (_tokensToBeUsed, _accountId, callback) => {
|
||||||
userStorage.checkBalance(_tokensToBeUsed, _accountId, (err, results) => {
|
userStorage.checkBalance(_tokensToBeUsed, _accountId, (err, results) => {
|
||||||
if (err) return callback(err, undefined);
|
if (err) return callback(err, undefined);
|
||||||
|
|||||||
@@ -1,3 +1,49 @@
|
|||||||
|
const { DebugBuilder } = require("../utilities/debugBuilder");
|
||||||
|
const log = new DebugBuilder("server", "chatGptController");
|
||||||
|
|
||||||
|
const { createTransaction } = require("./transactionController");
|
||||||
|
|
||||||
|
const { Configuration, OpenAIApi } = require('openai');
|
||||||
|
const configuration = new Configuration({
|
||||||
|
organization: process.env.OPENAI_ORG,
|
||||||
|
apiKey: process.env.OPENAI_KEY
|
||||||
|
});
|
||||||
|
|
||||||
|
const openai = new OpenAIApi(configuration);
|
||||||
|
|
||||||
|
|
||||||
|
async function getGeneration(_prompt, callback, { _model = "text-davinci-003", _temperature = 0, _max_tokens = 100}) {
|
||||||
|
log.DEBUG("Getting chat with these properties: ", _prompt, _model, _temperature, _max_tokens)
|
||||||
|
try{
|
||||||
|
/*
|
||||||
|
const response = await openai.createCompletion({
|
||||||
|
model: _model,
|
||||||
|
prompt: _prompt,
|
||||||
|
temperature: _temperature,
|
||||||
|
max_tokens: _max_tokens
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
var response = {
|
||||||
|
"id": "ABD123",
|
||||||
|
"usage": {
|
||||||
|
"total_tokens": _max_tokens
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"text": "ASKLDJHASLDJALSKDJAKLSDJLASKDJALSKD"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return callback(undefined, response);
|
||||||
|
} catch (err){
|
||||||
|
return callback(err, undefined);
|
||||||
|
}
|
||||||
|
//var responseData = response.data.choices[0].text;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use ChatGPT to generate a response
|
* Use ChatGPT to generate a response
|
||||||
*
|
*
|
||||||
@@ -5,18 +51,30 @@
|
|||||||
* @param {*} param1 Default parameters can be modified
|
* @param {*} param1 Default parameters can be modified
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
exports.getChat = async (_prompt, { _model = "text-davinci-003", _temperature = 0, _max_tokens = 100 }) => {
|
exports.submitPromptTransaction = async (interaction, callback) => {
|
||||||
log.DEBUG("Getting chat with these properties: ", _prompt, _model, _temperature, _max_tokens)
|
var params = {};
|
||||||
return
|
var promptText = interaction.options.getString('prompt');
|
||||||
/*
|
var temperature = interaction.options.getNumber('temperature');
|
||||||
const response = await openai.createCompletion({
|
var maxTokens = interaction.options.getNumber('tokens');
|
||||||
model: _model,
|
|
||||||
prompt: _prompt,
|
if (temperature) params._temperature = temperature;
|
||||||
temperature: _temperature,
|
if (maxTokens) params._max_tokens = maxTokens;
|
||||||
max_tokens: _max_tokens
|
|
||||||
});
|
getGeneration(promptText, (err, gptResult) => {
|
||||||
|
if (err) callback(err, undefined);
|
||||||
var responseData = response.data.choices[0].text;
|
|
||||||
return responseData;
|
// TODO - Use the pricing table to calculate discord tokens
|
||||||
*/
|
const discordTokensUsed = gptResult.usage.total_tokens;
|
||||||
|
|
||||||
|
if (gptResult){
|
||||||
|
createTransaction(gptResult.id, interaction.member.user, discordTokensUsed, gptResult.usage.total_tokens, 1, async (err, transactionResult) => {
|
||||||
|
if (err) callback(err, undefined);
|
||||||
|
|
||||||
|
if (transactionResult){
|
||||||
|
log.DEBUG("Transaction Created: ", transactionResult);
|
||||||
|
callback(undefined, ({ promptResult: gptResult.data.choices[0].text, totalTokens: discordTokensUsed}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, { _temperature: temperature, _max_tokens: maxTokens });
|
||||||
}
|
}
|
||||||
35
controllers/transactionController.js
Normal file
35
controllers/transactionController.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// Controller for managing transactions
|
||||||
|
|
||||||
|
const { DebugBuilder } = require("../utilities/debugBuilder");
|
||||||
|
const log = new DebugBuilder("server", "transactionController");
|
||||||
|
|
||||||
|
const { TransactionStorage } = require("../libStorage");
|
||||||
|
const transactionStorage = new TransactionStorage();
|
||||||
|
|
||||||
|
const { BaseTransaction } = require("../utilities/recordHelper");
|
||||||
|
const { withdrawBalance } = require("./accountController");
|
||||||
|
|
||||||
|
exports.createTransaction = async (_provider_transaction_id, _account_id, _discord_tokens_used, _provider_tokens_used, _provider_id, callback) => {
|
||||||
|
if (!_provider_transaction_id && !_account_id && !_discord_tokens_used && !_provider_id) return callback(new Error("Invalid vars when creating transaction", {vars: [_provider_transaction_id, _account_id, _discord_tokens_used, _provider_id, callback]}))
|
||||||
|
|
||||||
|
const newTransaction = new BaseTransaction(_provider_transaction_id, _account_id, _discord_tokens_used, _provider_tokens_used, _provider_id, callback);
|
||||||
|
log.DEBUG("New Transaction Object: ", newTransaction);
|
||||||
|
withdrawBalance(newTransaction.discord_tokens_used, newTransaction.account_id, (err, withdrawResult) => {
|
||||||
|
if (err) return callback(err, undefined);
|
||||||
|
|
||||||
|
if (withdrawResult){
|
||||||
|
log.DEBUG("New withdraw result: ", withdrawResult);
|
||||||
|
transactionStorage.createTransaction(newTransaction, async (err, transactionResult) =>{
|
||||||
|
if (err) return callback(err, undefined);
|
||||||
|
|
||||||
|
if(transactionResult){
|
||||||
|
log.DEBUG("New transaction result: ", transactionResult);
|
||||||
|
return callback(undefined, transactionResult);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return callback(undefined, undefined);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ module.exports = {
|
|||||||
await authorizeCommand(interaction, command, async () => {
|
await authorizeCommand(interaction, command, async () => {
|
||||||
await authorizeTokenUsage(interaction, command, async () => {
|
await authorizeTokenUsage(interaction, command, async () => {
|
||||||
try {
|
try {
|
||||||
if (command.deferInitialReply) await interaction.deferReply({ ephemeral: true });
|
if (command.deferInitialReply || !interaction.options.getBool('public')) await interaction.deferReply({ ephemeral: true });
|
||||||
command.execute(interaction);
|
command.execute(interaction);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.ERROR(error);
|
log.ERROR(error);
|
||||||
|
|||||||
@@ -10,15 +10,6 @@ const { all } = require('axios');
|
|||||||
const { DebugBuilder } = require("./utilities/debugBuilder");
|
const { DebugBuilder } = require("./utilities/debugBuilder");
|
||||||
const log = new DebugBuilder("server", "libCore");
|
const log = new DebugBuilder("server", "libCore");
|
||||||
|
|
||||||
/* OpenAI config
|
|
||||||
const { Configuration, OpenAIApi } = require('openai');
|
|
||||||
const configuration = new Configuration({
|
|
||||||
organization: process.env.OPENAI_ORG,
|
|
||||||
apiKey: process.env.OPENAI_API
|
|
||||||
});
|
|
||||||
|
|
||||||
const openai = new OpenAIApi(configuration);
|
|
||||||
*/
|
|
||||||
// Setup Storage handlers
|
// Setup Storage handlers
|
||||||
var feedStorage = new FeedStorage();
|
var feedStorage = new FeedStorage();
|
||||||
var postStorage = new PostStorage();
|
var postStorage = new PostStorage();
|
||||||
|
|||||||
@@ -187,30 +187,60 @@ exports.UserStorage = class UserStorage extends Storage {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a user's account Balance
|
||||||
|
*
|
||||||
|
* @param {string} _updateType The type of update to make to the account [ withdraw | deposit ]
|
||||||
|
* @param {number} _updateAmount The amount to update the account
|
||||||
|
* @param {number} _account_id The ID of the account to update
|
||||||
|
* @param {function} callback The callback function to call with the results
|
||||||
|
* @returns Result from the SQL query or false
|
||||||
|
*/
|
||||||
|
updateBalance(_updateType, _updateAmount, _account_id, callback){
|
||||||
|
var sqlQuery = "";
|
||||||
|
switch(_updateType){
|
||||||
|
case "withdraw":
|
||||||
|
// Code here to withdraw funds
|
||||||
|
sqlQuery = `UPDATE ${this.dbTable} SET balance=balance-${_updateAmount};`;
|
||||||
|
break;
|
||||||
|
case "deposit":
|
||||||
|
// Code here to withdraw funds
|
||||||
|
sqlQuery = `UPDATE ${this.dbTable} SET balance=balance+${_updateAmount};`;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.ERROR('Update type not valid: ', _updateType);
|
||||||
|
return callback(new Error("Update type not valid"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!sqlQuery) return callback(new Error("SQL Query empty"), undefined);
|
||||||
|
|
||||||
updateBalance(){
|
runSQL(sqlQuery, this.connection, (err, rows) => {
|
||||||
|
if (err) return callback(err, undefined);
|
||||||
|
if (rows?.affectedRows > 0) return callback(undefined, rows);
|
||||||
|
return callback(undefined, undefined);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
exports.TransactionStorage = class TransactionStorage extends Storage {
|
exports.TransactionStorage = class TransactionStorage extends Storage {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(transactionsTable);
|
super(transactionsTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
createTransaction(transaction, callback){
|
createTransaction(transaction, callback){
|
||||||
const sqlQuery = `INSERT INTO ${this.dbTable} () VALUES ('${}');`;
|
var sqlQuery = `INSERT INTO ${this.dbTable} (transaction_id, account_id, discord_tokens_used, provider_tokens_used, provider_id, order_date) VALUES ('${transaction.transaction_id}', '${transaction.account_id}', '${transaction.discord_tokens_used}', '${transaction.provider_tokens_used}', '${transaction.provider_id}', '${returnMysqlTime()}');`;
|
||||||
|
|
||||||
log.DEBUG(`Adding new entry with SQL query: '${sqlQuery}'`)
|
log.DEBUG(`Adding new entry with SQL query: '${sqlQuery}'`)
|
||||||
|
|
||||||
runSQL(sqlQuery, this.connection, (err, rows) => {
|
runSQL(sqlQuery, this.connection, (err, rows) => {
|
||||||
if (err) return callback(err, undefined);
|
if (err) return callback(err, undefined);
|
||||||
if (rows[0]?.id) return callback(undefined, rows);
|
if (rows?.affectedRows > 0) return callback(undefined, rows);
|
||||||
return callback(undefined, undefined);
|
return callback(undefined, undefined);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
exports.FeedStorage = class FeedStorage extends Storage {
|
exports.FeedStorage = class FeedStorage extends Storage {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(rssFeedsTable);
|
super(rssFeedsTable);
|
||||||
|
|||||||
@@ -69,4 +69,31 @@ exports.RSSPostRecord = class RSSPostRecord extends baseRSSRecord{
|
|||||||
super(_id, _title, _link, _category);
|
super(_id, _title, _link, _category);
|
||||||
this.guid = _guid;
|
this.guid = _guid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base transaction
|
||||||
|
*/
|
||||||
|
class BaseTransaction {
|
||||||
|
constructor(_provider_transaction_id, _account_id, _discord_tokens_used, _provider_tokens_used, _provider_id) {
|
||||||
|
this.transaction_id = _provider_transaction_id;
|
||||||
|
this.account_id = _account_id;
|
||||||
|
this.discord_tokens_used = _discord_tokens_used;
|
||||||
|
this.provider_tokens_used = _provider_tokens_used;
|
||||||
|
this.provider_id = _provider_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.BaseTransaction = BaseTransaction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base transaction
|
||||||
|
*/
|
||||||
|
class BaseUserAccount {
|
||||||
|
constructor(_discord_account_id, _account_id) {
|
||||||
|
this.discord_account_id = _discord_account_id;
|
||||||
|
this.account_id = _account_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.BaseUserAccount = BaseUserAccount;
|
||||||
Reference in New Issue
Block a user