djmuted commited on
Commit
0e39520
1 Parent(s): d899182

Add multiple slack support

Browse files
Files changed (5) hide show
  1. .gitignore +3 -1
  2. Dockerfile +2 -2
  3. src/config.json.example +11 -0
  4. src/openai.js +24 -8
  5. src/slack.js +7 -8
.gitignore CHANGED
@@ -127,4 +127,6 @@ dist
127
  .yarn/unplugged
128
  .yarn/build-state.yml
129
  .yarn/install-state.gz
130
- .pnp.*
 
 
 
127
  .yarn/unplugged
128
  .yarn/build-state.yml
129
  .yarn/install-state.gz
130
+ .pnp.*
131
+
132
+ src/config.json
Dockerfile CHANGED
@@ -1,8 +1,8 @@
1
  FROM node:18-bullseye-slim
2
  COPY . /app
3
  WORKDIR /app
4
- RUN --mount=type=secret,id=ENV,mode=0444,required=true \
5
- cat /run/secrets/ENV > /app/.env && yarn install
6
  EXPOSE 7860
7
  ENV NODE_ENV=production
8
  CMD [ "yarn", "start" ]
 
1
  FROM node:18-bullseye-slim
2
  COPY . /app
3
  WORKDIR /app
4
+ RUN --mount=type=secret,id=CONFIG,mode=0444,required=true \
5
+ cat /run/secrets/CONFIG > /app/src/config.json && yarn install
6
  EXPOSE 7860
7
  ENV NODE_ENV=production
8
  CMD [ "yarn", "start" ]
src/config.json.example ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "slacks": [
3
+ {
4
+ "token": "",
5
+ "cookie": "",
6
+ "teamId": "",
7
+ "claudeId": ""
8
+ }
9
+ ],
10
+ "apiKey": ""
11
+ }
src/openai.js CHANGED
@@ -1,6 +1,6 @@
1
  const { Router } = require('express');
2
  const bodyParser = require('body-parser');
3
- const config = require('./config');
4
  const slack = require('./slack');
5
  const yup = require('yup');
6
  const { splitJsonArray, dataToResponse, buildPrompt } = require("./utils");
@@ -29,12 +29,18 @@ openaiRouter.get("/models", (req, res) => {
29
  ]);
30
  });
31
 
32
- const parallelQueries = 1;
 
 
 
 
 
 
33
  const myq = new Queue(parallelQueries, 100);
34
 
35
  openaiRouter.post("/chat/completions", jsonParser, async (req, res) => {
36
  try {
37
- if (req.token !== config.API_KEY) {
38
  res.status(401).json({ error: "Unauthorized" });
39
  return;
40
  }
@@ -45,9 +51,6 @@ openaiRouter.post("/chat/completions", jsonParser, async (req, res) => {
45
  return;
46
  }
47
 
48
- const id = `chatcmpl-${(Math.random().toString(36).slice(2))}`;
49
- const created = Math.floor(Date.now() / 1000);
50
-
51
  const messagesSplit = splitJsonArray(messages, 12000);
52
 
53
  if (stream) {
@@ -74,8 +77,21 @@ openaiRouter.post("/chat/completions", jsonParser, async (req, res) => {
74
  };
75
 
76
  const result = await myq.run(async () => {
77
- await slack.sendChatReset();
78
- return await slack.waitForWebSocketResponse(messagesSplit, onData);
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  });
80
 
81
  if (stream) {
 
1
  const { Router } = require('express');
2
  const bodyParser = require('body-parser');
3
+ const config = require('./config.json');
4
  const slack = require('./slack');
5
  const yup = require('yup');
6
  const { splitJsonArray, dataToResponse, buildPrompt } = require("./utils");
 
29
  ]);
30
  });
31
 
32
+ const parallelQueries = config.slacks.length;
33
+ const slacks = config.slacks.map((slackConfig) => {
34
+ return {
35
+ ...slackConfig,
36
+ locked: false,
37
+ };
38
+ });
39
  const myq = new Queue(parallelQueries, 100);
40
 
41
  openaiRouter.post("/chat/completions", jsonParser, async (req, res) => {
42
  try {
43
+ if (config.apiKey && req.token !== config.apiKey) {
44
  res.status(401).json({ error: "Unauthorized" });
45
  return;
46
  }
 
51
  return;
52
  }
53
 
 
 
 
54
  const messagesSplit = splitJsonArray(messages, 12000);
55
 
56
  if (stream) {
 
77
  };
78
 
79
  const result = await myq.run(async () => {
80
+ let slackConfig = slacks.find((slack) => !slack.locked);
81
+ if (!slackConfig) {
82
+ throw new Error('Queue full');
83
+ }
84
+ slackConfig.locked = true;
85
+ try {
86
+ await slack.sendChatReset(slackConfig);
87
+ const response = await slack.waitForWebSocketResponse(slackConfig, messagesSplit, onData);
88
+ slackConfig.locked = false;
89
+ return response;
90
+ } catch (error) {
91
+ slackConfig.locked = false;
92
+ console.error(error);
93
+ throw new Error('Slack error');
94
+ }
95
  });
96
 
97
  if (stream) {
src/slack.js CHANGED
@@ -3,10 +3,9 @@ const { v4: uuidv4 } = require('uuid');
3
  const https = require('https');
4
  const WebSocket = require('ws');
5
 
6
- const { TOKEN, COOKIE, TEAM_ID } = require('./config');
7
  const { readBody, headers, createBaseForm, convertToUnixTime, currentTime, buildPrompt } = require('./utils');
8
 
9
- async function sendPromptMessage(prompt) {
10
  const form = createBaseForm();
11
 
12
  form.append('ts', convertToUnixTime(new Date()));
@@ -26,7 +25,7 @@ async function sendPromptMessage(prompt) {
26
  },
27
  };
28
 
29
- const req = https.request(`https://${TEAM_ID}.slack.com/api/chat.postMessage`, options, async (res) => {
30
  try {
31
  const response = await readBody(res, true);
32
  console.log(response);
@@ -42,7 +41,7 @@ async function sendPromptMessage(prompt) {
42
  form.pipe(req);
43
  }
44
 
45
- async function sendChatReset() {
46
  const form = createBaseForm();
47
 
48
  form.append('command', '/reset');
@@ -58,7 +57,7 @@ async function sendChatReset() {
58
  },
59
  };
60
 
61
- const req = https.request(`https://${TEAM_ID}.slack.com/api/chat.command`, options, async (res) => {
62
  try {
63
  const response = await readBody(res, true);
64
  console.log(response);
@@ -74,9 +73,9 @@ async function sendChatReset() {
74
  form.pipe(req);
75
  }
76
 
77
- async function waitForWebSocketResponse(messages, onData) {
78
  return new Promise(async (resolve, reject) => {
79
- const websocketURL = `wss://wss-primary.slack.com/?token=${TOKEN}`;
80
 
81
  const websocket = new WebSocket(websocketURL, {
82
  headers: headers,
@@ -95,7 +94,7 @@ async function waitForWebSocketResponse(messages, onData) {
95
  const sendNextPrompt = async () => {
96
  if (messageIndex < messages.length) {
97
  const prompt = buildPrompt(messages[messageIndex]);
98
- await sendPromptMessage(prompt);
99
  messageIndex++;
100
  }
101
  };
 
3
  const https = require('https');
4
  const WebSocket = require('ws');
5
 
 
6
  const { readBody, headers, createBaseForm, convertToUnixTime, currentTime, buildPrompt } = require('./utils');
7
 
8
+ async function sendPromptMessage(config, prompt) {
9
  const form = createBaseForm();
10
 
11
  form.append('ts', convertToUnixTime(new Date()));
 
25
  },
26
  };
27
 
28
+ const req = https.request(`https://${config.teamId}.slack.com/api/chat.postMessage`, options, async (res) => {
29
  try {
30
  const response = await readBody(res, true);
31
  console.log(response);
 
41
  form.pipe(req);
42
  }
43
 
44
+ async function sendChatReset(config) {
45
  const form = createBaseForm();
46
 
47
  form.append('command', '/reset');
 
57
  },
58
  };
59
 
60
+ const req = https.request(`https://${config.teamId}.slack.com/api/chat.command`, options, async (res) => {
61
  try {
62
  const response = await readBody(res, true);
63
  console.log(response);
 
73
  form.pipe(req);
74
  }
75
 
76
+ async function waitForWebSocketResponse(config, messages, onData) {
77
  return new Promise(async (resolve, reject) => {
78
+ const websocketURL = `wss://wss-primary.slack.com/?token=${config.token}`;
79
 
80
  const websocket = new WebSocket(websocketURL, {
81
  headers: headers,
 
94
  const sendNextPrompt = async () => {
95
  if (messageIndex < messages.length) {
96
  const prompt = buildPrompt(messages[messageIndex]);
97
+ await sendPromptMessage(config, prompt);
98
  messageIndex++;
99
  }
100
  };