This commit is contained in:
tessmania90
2023-04-06 06:11:27 +02:00
parent 2e1d9dadb8
commit 3d1660deab
4 changed files with 151 additions and 1 deletions
-1
View File
@@ -21,6 +21,5 @@ USER node
COPY --from=npm_builder [ "/app/node_modules/", "./node_modules/" ]
COPY --from=npm_builder [ "/app/src/", "./src/" ]
COPY [ "./license.md", "./" ]
ENTRYPOINT [ "node", "src/botservice.js" ]
+96
View File
@@ -0,0 +1,96 @@
const continueThread = require('./openai-thread-completion').continueThread
const { Log } = require('debug-level')
require('babel-polyfill');
require('isomorphic-fetch');
const { mmClient, wsClient } = require('./mm-client')
// the mattermost library uses FormData - so here is a polyfill
if (!global.FormData) {
global.FormData = require('form-data');
}
Log.options({ json: true, colors: true })
Log.wrapConsole('bot-ws', { level4log: 'INFO' })
const log = new Log('bot')
let meId = null;
mmClient.getMe().then(me => meId = me.id)
const name = process.env['MATTERMOST_BOTNAME'] || '@dall-e'
wsClient.addMessageListener(async function (event) {
if (['posted'].includes(event.event) && meId) {
const post = JSON.parse(event.data.post);
if (post.root_id === "" && (!event.data.mentions || (!JSON.parse(event.data.mentions).includes(meId)))) {
// we're not in a thread and we are not mentioned - ignore the message
} else {
if (post.user_id !== meId) {
const chatmessages = [
{
"role": "system",
"content": `You are a helpful assistant named ${name} who provides succinct answers in Markdown format.`
},
]
const thread = await mmClient.getPostThread(post.id, true, false, true)
const posts = [...new Set(thread.order)].map(id => thread.posts[id])
.filter(a => a.create_at > Date.now() - 1000 * 60 * 60 * 24 * 1)
.sort((a, b) => a.create_at - b.create_at)
let assistantCount = 0;
posts.forEach(threadPost => {
log.trace({msg: threadPost})
if (threadPost.user_id === meId) {
chatmessages.push({role: "assistant", content: threadPost.props.originalMessage ?? threadPost.message})
assistantCount++
} else {
if (threadPost.message.includes(name)){
assistantCount++;
}
chatmessages.push({role: "user", content: threadPost.message})
}
})
// see if we are actually part of the conversation -
// ignore conversations where we were never mentioned or participated.
if (assistantCount > 0){
wsClient.userTyping(post.channel_id, post.id ?? "")
log.trace({chatmessages})
const answer = await continueThread(chatmessages)
const fileData = new FormData();
fileData.append('files', answer, 'dall-e-image.png');
const uploadResponse = await mmClient.uploadFile(fileData, post.channel_id);
const fileId = JSON.parse(uploadResponse).file_infos[0].id;
log.trace({answer})
wsClient.userTyping(post.channel_id, post.id ?? "")
const message = `![alt text](${mmClient.getFileUrl(fileId)})`;
const props = {
attachments: [
{
text: '',
title: '',
image_url: mmClient.getFileUrl(fileId),
fallback: message
}
]
};
const newPost = await mmClient.createPost({
message: message,
channel_id: post.channel_id,
props,
root_id: post.root_id || post.id,
file_ids: fileId ? [fileId] : undefined
});
log.trace({msg: newPost})
}
}
}
} else {
log.debug({msg: event})
}
});
+31
View File
@@ -0,0 +1,31 @@
const Client4 = require('@mattermost/client').Client4
const WebSocketClient = require('@mattermost/client').WebSocketClient
const { Log } = require('debug-level')
const log = new Log('bot')
if (!global.WebSocket) {
global.WebSocket = require('ws');
}
const mattermostToken = process.env['MATTERMOST_TOKEN']
const matterMostURLString = process.env['MATTERMOST_URL']
const client = new Client4()
client.setUrl(matterMostURLString)
client.setToken(mattermostToken)
const wsClient = new WebSocketClient();
let matterMostURL = new URL(matterMostURLString);
const wsUrl = `${matterMostURL.protocol === 'https:' ? 'wss' : 'ws'}://${matterMostURL.host}/api/v4/websocket`
new Promise((resolve, reject) => {
wsClient.addCloseListener(connectFailCount => reject())
wsClient.addErrorListener(event => { reject(event) })
}).then(() => process.exit(0)).catch(reason => { log.error(reason); process.exit(-1)})
wsClient.initialize(wsUrl, mattermostToken)
module.exports = {
mmClient: client,
wsClient
}
+24
View File
@@ -0,0 +1,24 @@
const { Configuration, OpenAIApi } = require("openai");
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
// Function to generate an image using Dall-E from OpenAI
async function continueThread(messages) {
const promptText = messages.map(msg => msg.content).join(' '); // assume that the content key exist in the messages object
const response = await openai.createImage({
prompt: promptText,
n: 1,
size: "512x512",
response_format: "url"
});
const imageUrl = await response.data.url;// oder response.content.url()
const imageResponse = await fetch(imageUrl);
const imageBuffer = await imageResponse.buffer();
return imageBuffer;
}
module.exports = { continueThread }