Skip to content

Commit

Permalink
Merge pull request #120 from fuergaosi233/feat/add-account-reload
Browse files Browse the repository at this point in the history
✨ Add account relogin if refresh token failed
  • Loading branch information
fuergaosi233 authored Dec 9, 2022
2 parents 5ed1e7d + a0c294a commit 9ca9dab
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 8 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</p>

> Use ChatGPT On Wechat via wechaty
English | [中文文档](README.zh-CN.md)
### 🏠 [Homepage](https://github.com/fuergaosi233/wechat-chatgpt)

## 🌟 Feature
Expand All @@ -22,7 +22,7 @@
- [x] Add Dockerfile
- [x] Publish to Docker.hub
- [ ] Add Railway deploy
- [ ] Auto Reload OpenAI Accounts Pool
- [x] Auto Reload OpenAI Accounts Pool
- [ ] Add sendmessage retry for 429/503

## Use with docker (recommended)
Expand Down
4 changes: 2 additions & 2 deletions README_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</p>

> 在微信上迅速接入 ChatGPT,让它成为你最好的助手!
[English](README.md) | 中文文档
### 🏠 [主页](https://github.com/fuergaosi233/wechat-chatgpt/blob/main/README_ZH.md)

## 🌟 功能点
Expand All @@ -22,7 +22,7 @@
- [x] 加入 Dockerfile
- [x] 发布到 Docker.hub
- [ ] 通过 Railway 进行部署
- [ ] 实现 OpenAI 账户池的热加载
- [x] 实现 OpenAI 账户池的热加载
- [ ] 当 OpenAI 返回码为 429/503 时自动重试

## 通过 Docker 使用(✅ 推荐)
Expand Down
6 changes: 5 additions & 1 deletion src/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ export class Cache {
get(key: string) {
return this._cache[key];
}
set(key: string, value: any) {
async set(key: string, value: any) {
this._cache[key] = value;
fs.writeFileSync(this._file, JSON.stringify(this._cache));
}
async delete(key: string) {
delete this._cache[key];
fs.writeFileSync(this._file, JSON.stringify(this._cache));
}
}
69 changes: 66 additions & 3 deletions src/chatgpt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
AccountWithUserInfo,
isAccountWithUserInfo,
isAccountWithSessionToken,
AccountWithSessionToken,
IAccount,
} from "./interface.js";

enum MessageType {
Expand Down Expand Up @@ -53,7 +55,6 @@ export class ChatGPTPoole {
}
const cmd = `poetry run python3 src/generate_session.py ${email} ${password}`;
const platform = process.platform;

const { stdout, stderr, exitCode } = await execa(
platform === "win32" ? "powershell" : "sh",
[platform === "win32" ? "/c" : "-c", cmd]
Expand All @@ -70,6 +71,64 @@ export class ChatGPTPoole {
}
return "";
}
async resetAccount(account: IAccount) {
if (isAccountWithUserInfo(account)) {
// Remove all conversation information
this.conversationsPool.forEach((item, key) => {
if ((item.account as AccountWithUserInfo)?.email === account.email) {
this.conversationsPool.delete(key);
}
});
// Relogin and generate a new session token
const chatGPTItem = this.chatGPTPools
.filter((item) => isAccountWithUserInfo(item.account))
.find(
(
item: any
): item is IChatGPTItem & {
account: AccountWithUserInfo;
chatGpt: ChatGPTAPI;
} => item?.email === account.email
);
if (chatGPTItem) {
await this.cache.delete(account.email);
try {
const session_token = await this.getSessionToken(
chatGPTItem.account?.email,
chatGPTItem.account?.password
);
chatGPTItem.chatGpt = new ChatGPTAPI({
sessionToken: session_token,
});
} catch (err) {
//remove this object
this.chatGPTPools = this.chatGPTPools.filter(
(item) =>
(item.account as AccountWithUserInfo)?.email !== account.email
);
console.error(
`Try reset account: ${account.email} failed: ${err}, remove it from pool`
);
}
}
} else if (isAccountWithSessionToken(account)) {
// Remove all conversation information
this.conversationsPool.forEach((item, key) => {
if (
(item.account as AccountWithSessionToken)?.session_token ===
account.session_token
) {
this.conversationsPool.delete(key);
}
});
// Remove this gptItem
this.chatGPTPools = this.chatGPTPools.filter(
(item) =>
(item.account as AccountWithSessionToken)?.session_token !==
account.session_token
);
}
}
async startPools() {
const sessionAccounts = config.chatGPTAccountPool.filter(
isAccountWithSessionToken
Expand Down Expand Up @@ -125,14 +184,18 @@ export class ChatGPTPoole {
return conversationItem;
}
// send message with talkid
async sendMessage(message: string, talkid: string) {
async sendMessage(message: string, talkid: string): Promise<string> {
const conversationItem = this.getConversation(talkid);
const { conversation, account } = conversationItem;
try {
// TODO: Add Retry logic
const response = await conversation.sendMessage(message);
return response;
} catch (err: any) {
if (err.message.includes("ChatGPT failed to refresh auth token")) {
await this.resetAccount(account);
return this.sendMessage(message, talkid);
}
console.error(
`err is ${err.message}, account ${JSON.stringify(account)}`
);
Expand Down Expand Up @@ -166,7 +229,7 @@ export class ChatGPTBot {
return `@${this.botName}`;
}
async startGPTBot() {
console.debug(`Start GPT Bot Config is:${config}`);
console.debug(`Start GPT Bot Config is:${JSON.stringify(config)}`);
await this.chatGPTPool.startPools();
console.debug(`🤖️ Start GPT Bot Success, ready to handle message!`);
}
Expand Down

0 comments on commit 9ca9dab

Please sign in to comment.