mirror of
https://github.com/matrixgpt/matrix-chatgpt-bot.git
synced 2024-10-01 01:25:41 -04:00
Update ChatGPT API wrapper to latest, uses Puppeteer
This commit is contained in:
parent
22a896c6f8
commit
0175a09e33
77
Dockerfile
77
Dockerfile
@ -1,8 +1,71 @@
|
||||
FROM node:18
|
||||
RUN git clone https://github.com/jakecoppinger/matrix-chatgpt-bot.git
|
||||
WORKDIR matrix-chatgpt-bot
|
||||
COPY env .env
|
||||
#RUN yarn install
|
||||
RUN yarn install --har --production=true
|
||||
FROM node:18 as builder
|
||||
|
||||
# Create app directory
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Install app dependencies
|
||||
COPY package*.json ./
|
||||
|
||||
# We don't need the standalone Chromium here.
|
||||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
|
||||
|
||||
RUN yarn install --frozen-lockfile && yarn cache clean
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN yarn build
|
||||
RUN yarn start
|
||||
|
||||
|
||||
FROM node:18-slim
|
||||
|
||||
RUN mkdir -p /home/pptruser/Downloads
|
||||
# Create app directory
|
||||
WORKDIR /home/pptruser
|
||||
|
||||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
|
||||
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
|
||||
ENV CHROME_PATH=/usr/bin/chromium
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt update -qq \
|
||||
&& apt install -qq -y --no-install-recommends \
|
||||
curl \
|
||||
git \
|
||||
gnupg \
|
||||
libgconf-2-4 \
|
||||
libxss1 \
|
||||
libxtst6 \
|
||||
python \
|
||||
g++ \
|
||||
build-essential \
|
||||
chromium \
|
||||
chromium-sandbox \
|
||||
dumb-init \
|
||||
fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& rm -rf /src/*.deb
|
||||
|
||||
# To run Headful mode, you will need to have a display, which is not present in a server.
|
||||
# To avoid this, we will use Xvfb, and create a fake display, so the chrome will think there is a display and run properly.
|
||||
# So we just need to install Xvfb and Puppeteer related dependencies.
|
||||
RUN apt-get update && apt-get install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget x11vnc x11-xkb-utils xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic x11-apps xvfb
|
||||
|
||||
# Install app dependencies
|
||||
COPY package*.json ./
|
||||
|
||||
COPY .env .env
|
||||
|
||||
RUN yarn install --frozen-lockfile --production && yarn cache clean
|
||||
|
||||
COPY --from=builder /usr/src/app/dist ./dist
|
||||
|
||||
RUN npm install puppeteer@19.4.1 \
|
||||
# Add user so we don't need --no-sandbox.
|
||||
# same layer as npm install to keep re-chowned files from using up several hundred MBs more space
|
||||
&& groupadd -r pptruser && useradd -rm -g pptruser -G audio,video pptruser \
|
||||
&& chown -R pptruser:pptruser /home/pptruser
|
||||
USER pptruser
|
||||
|
||||
# We run a fake display and run our script.
|
||||
# Start script on Xvfb
|
||||
CMD xvfb-run --server-args="-screen 0 1024x768x24" yarn start
|
17
README.md
17
README.md
@ -7,6 +7,17 @@ Talk to ChatGPT via your favourite Matrix client!
|
||||
|
||||
This is an unofficial Matrix bot that uses https://github.com/transitive-bullshit/chatgpt-api to access the unofficial ChatGPT API.
|
||||
|
||||
It is worth reading the [authentication instructions](https://www.npmjs.com/package/chatgpt#usage) for the unofficial ChatGPT API.
|
||||
|
||||
Your user-agent and IP address must match from the real browser window you're logged in with to the one you're using for ChatGPTAPI. This means that you currently can't log in with your laptop and then run the bot on a server or proxy somewhere.
|
||||
|
||||
Cloudflare will still sometimes ask you to complete a CAPTCHA, so you may need to keep an eye on it and manually resolve the CAPTCHA.
|
||||
|
||||
You should not be using this ChatGPT account while the bot is using it, because that browser window may refresh one of your tokens and invalidate the bot's session.
|
||||
|
||||
If your OpenAI account uses Google Auth, you shouldn't encounter any of the more complicated Recaptchas — and can avoid using paid third-party CAPTCHA solving providers. To use Google auth, make sure your OpenAI account is using Google and then set IS_GOOGLE_LOGIN to true.
|
||||
|
||||
|
||||
# Usage
|
||||
- Create an unencrypted room
|
||||
- Add the bot
|
||||
@ -27,9 +38,9 @@ This is an unofficial Matrix bot that uses https://github.com/transitive-bullshi
|
||||
MATRIX_HOMESERVER_URL=
|
||||
MATRIX_ACCESS_TOKEN=
|
||||
|
||||
# The value of the __Secure-next-auth.session-token cookie. See instructions on
|
||||
# https://www.npmjs.com/package/chatgpt
|
||||
CHATGPT_SESSION_TOKEN=
|
||||
OPENAI_EMAIL=
|
||||
OPENAI_PASSWORD=
|
||||
IS_GOOGLE_LOGIN=true
|
||||
|
||||
# With the @ and :DOMAIN, ie @SOMETHING:DOMAIN
|
||||
MATRIX_BOT_USERNAME=
|
||||
|
@ -15,9 +15,10 @@
|
||||
"typecheck": "npx tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"chatgpt": "^2.0.5",
|
||||
"chatgpt": "^3.3.1",
|
||||
"dotenv": "^14.2.0",
|
||||
"matrix-bot-sdk": "^0.6.2",
|
||||
"puppeteer": "^19.4.1",
|
||||
"typescript": "^4.5.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -12,7 +12,11 @@ export const homeserverUrl = process.env.MATRIX_HOMESERVER_URL as string;
|
||||
/** The full username: eg @bot:server.com */
|
||||
export const matrixBotUsername = process.env.MATRIX_BOT_USERNAME as string;
|
||||
export const matrixBotPassword = process.env.MATRIX_BOT_PASSWORD as string;
|
||||
export const chatGPTApiKey = process.env.CHATGPT_SESSION_TOKEN as string;
|
||||
|
||||
/** ChatGPT specific stuff */
|
||||
export const openAiEmail = process.env.OPENAI_EMAIL as string;
|
||||
export const openAiPassword = process.env.OPENAI_PASSWORD as string;
|
||||
export const isGoogleLogin = Boolean(process.env.IS_GOOGLE_LOGIN) as boolean;
|
||||
|
||||
if(accessToken === undefined) {
|
||||
console.error("MATRIX_ACCESS_TOKEN env variable is undefined");
|
||||
@ -30,7 +34,15 @@ if(matrixBotPassword === undefined) {
|
||||
console.error("MATRIX_BOT_PASSWORD env variable is undefined");
|
||||
process.exit(1);
|
||||
}
|
||||
if(chatGPTApiKey === undefined) {
|
||||
console.error("MATRIX_BOT_PASSWORD env variable is undefined");
|
||||
if(openAiEmail === undefined) {
|
||||
console.error("OPENAI_EMAIL env variable is undefined");
|
||||
process.exit(1);
|
||||
}
|
||||
if(openAiPassword === undefined) {
|
||||
console.error("OPENAI_PASSWORD env variable is undefined");
|
||||
process.exit(1);
|
||||
}
|
||||
if(isGoogleLogin === undefined) {
|
||||
console.error("IS_GOOGLE_LOGIN env variable is undefined");
|
||||
process.exit(1);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ChatGPTAPI } from "chatgpt";
|
||||
import { ChatGPTAPIBrowser } from "chatgpt";
|
||||
import { MatrixClient } from "matrix-bot-sdk";
|
||||
import { matrixBotUsername } from "./config.js";
|
||||
import { isEventAMessage } from "./utils.js";
|
||||
@ -8,7 +8,7 @@ import { isEventAMessage } from "./utils.js";
|
||||
* @param client
|
||||
* @returns Room event handler, which itself returnings nothing
|
||||
*/
|
||||
export async function handleRoomEvent(client: MatrixClient, chatGPT: ChatGPTAPI): Promise<(roomId: string, event: any) => Promise<void>> {
|
||||
export async function handleRoomEvent(client: MatrixClient, chatGPT: ChatGPTAPIBrowser): Promise<(roomId: string, event: any) => Promise<void>> {
|
||||
return async (roomId: string, event: any) => {
|
||||
if (event.sender === matrixBotUsername) {
|
||||
return;
|
||||
@ -31,10 +31,13 @@ Please add me to an unencrypted chat.`);
|
||||
await client.sendReadReceipt(roomId, event.event_id);
|
||||
await client.setTyping(roomId, true, 10000)
|
||||
try {
|
||||
const response = await chatGPT.sendMessage(
|
||||
question)
|
||||
// timeout after 2 minutes (which will also abort the underlying HTTP request)
|
||||
const result = await chatGPT.sendMessage(question, {
|
||||
timeoutMs: 2 * 60 * 1000
|
||||
})
|
||||
await client.setTyping(roomId, false, 500)
|
||||
await client.sendText(roomId, `${response}`);
|
||||
|
||||
await client.sendText(roomId, `${result.response}`);
|
||||
await client.sendReadReceipt(roomId, event.event_id);
|
||||
} catch (e) {
|
||||
await client.setTyping(roomId, false, 500)
|
||||
@ -45,4 +48,4 @@ Please add me to an unencrypted chat.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
src/index.ts
15
src/index.ts
@ -4,10 +4,10 @@ import {
|
||||
RichConsoleLogger,
|
||||
// RustSdkCryptoStorageProvider,
|
||||
} from "matrix-bot-sdk";
|
||||
import { chatGPTApiKey, homeserverUrl, matrixBotPassword, matrixBotUsername } from './config.js'
|
||||
import { openAiEmail, openAiPassword, isGoogleLogin, homeserverUrl, matrixBotPassword, matrixBotUsername } from './config.js'
|
||||
import { parseMatrixUsernamePretty } from './utils.js';
|
||||
import { handleRoomEvent } from './handlers.js';
|
||||
import { ChatGPTAPI } from 'chatgpt'
|
||||
import { ChatGPTAPIBrowser } from 'chatgpt'
|
||||
|
||||
LogService.setLogger(new RichConsoleLogger());
|
||||
|
||||
@ -29,12 +29,13 @@ async function main() {
|
||||
const authedClient = await (new MatrixAuth(homeserverUrl)).passwordLogin(botUsernameWithoutDomain, matrixBotPassword);
|
||||
const client = new MatrixClient(authedClient.homeserverUrl, authedClient.accessToken, storage);
|
||||
|
||||
const chatGPT = new ChatGPTAPI({
|
||||
sessionToken: chatGPTApiKey
|
||||
// use puppeteer to bypass cloudflare (headful because of captchas)
|
||||
const chatGPT = new ChatGPTAPIBrowser({
|
||||
email: openAiEmail,
|
||||
password: openAiPassword,
|
||||
isGoogleLogin: isGoogleLogin
|
||||
})
|
||||
|
||||
// ensure the API is properly authenticated
|
||||
await chatGPT.ensureAuth()
|
||||
await chatGPT.initSession()
|
||||
|
||||
// Automatically join rooms the bot is invited to
|
||||
AutojoinRoomsMixin.setupOnClient(client);
|
||||
|
Loading…
Reference in New Issue
Block a user