fix(feishu): guard thread store startup order (#1700)
This commit is contained in:
@@ -20,6 +20,65 @@ import {
|
||||
stripGroupPrefix
|
||||
} from "./lib.mjs";
|
||||
|
||||
class ThreadStore {
|
||||
static async open(filePath) {
|
||||
const store = new ThreadStore(filePath);
|
||||
await store.load();
|
||||
return store;
|
||||
}
|
||||
|
||||
constructor(filePath) {
|
||||
this.filePath = filePath;
|
||||
this.data = { chats: {} };
|
||||
}
|
||||
|
||||
async load() {
|
||||
try {
|
||||
const raw = await fs.readFile(this.filePath, "utf8");
|
||||
this.data = JSON.parse(raw);
|
||||
if (!this.data.chats) this.data.chats = {};
|
||||
if (!this.data.messages) this.data.messages = [];
|
||||
} catch (error) {
|
||||
if (error.code !== "ENOENT") throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async recordMessage(messageId) {
|
||||
if (!messageId) return false;
|
||||
if (!Array.isArray(this.data.messages)) this.data.messages = [];
|
||||
if (this.data.messages.includes(messageId)) return true;
|
||||
this.data.messages.push(messageId);
|
||||
this.data.messages = this.data.messages.slice(-200);
|
||||
await this.save();
|
||||
return false;
|
||||
}
|
||||
|
||||
async getChat(chatId) {
|
||||
return this.data.chats[chatId] || null;
|
||||
}
|
||||
|
||||
async setChat(chatId, state) {
|
||||
this.data.chats[chatId] = state;
|
||||
await this.save();
|
||||
return state;
|
||||
}
|
||||
|
||||
async patchChat(chatId, patch) {
|
||||
const current = this.data.chats[chatId] || {};
|
||||
this.data.chats[chatId] = { ...current, ...patch };
|
||||
await this.save();
|
||||
return this.data.chats[chatId];
|
||||
}
|
||||
|
||||
async save() {
|
||||
const dir = path.dirname(this.filePath);
|
||||
await fs.mkdir(dir, { recursive: true, mode: 0o700 });
|
||||
const tmp = `${this.filePath}.tmp`;
|
||||
await fs.writeFile(tmp, `${JSON.stringify(this.data, null, 2)}\n`, { mode: 0o600 });
|
||||
await fs.rename(tmp, this.filePath);
|
||||
}
|
||||
}
|
||||
|
||||
const config = {
|
||||
appId: requiredEnv("FEISHU_APP_ID"),
|
||||
appSecret: requiredEnv("FEISHU_APP_SECRET"),
|
||||
@@ -509,62 +568,3 @@ function resolveLarkDomain(domain) {
|
||||
if (normalized === "feishu") return Lark.Domain?.Feishu || "https://open.feishu.cn";
|
||||
return domain;
|
||||
}
|
||||
|
||||
class ThreadStore {
|
||||
static async open(filePath) {
|
||||
const store = new ThreadStore(filePath);
|
||||
await store.load();
|
||||
return store;
|
||||
}
|
||||
|
||||
constructor(filePath) {
|
||||
this.filePath = filePath;
|
||||
this.data = { chats: {} };
|
||||
}
|
||||
|
||||
async load() {
|
||||
try {
|
||||
const raw = await fs.readFile(this.filePath, "utf8");
|
||||
this.data = JSON.parse(raw);
|
||||
if (!this.data.chats) this.data.chats = {};
|
||||
if (!this.data.messages) this.data.messages = [];
|
||||
} catch (error) {
|
||||
if (error.code !== "ENOENT") throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async recordMessage(messageId) {
|
||||
if (!messageId) return false;
|
||||
if (!Array.isArray(this.data.messages)) this.data.messages = [];
|
||||
if (this.data.messages.includes(messageId)) return true;
|
||||
this.data.messages.push(messageId);
|
||||
this.data.messages = this.data.messages.slice(-200);
|
||||
await this.save();
|
||||
return false;
|
||||
}
|
||||
|
||||
async getChat(chatId) {
|
||||
return this.data.chats[chatId] || null;
|
||||
}
|
||||
|
||||
async setChat(chatId, state) {
|
||||
this.data.chats[chatId] = state;
|
||||
await this.save();
|
||||
return state;
|
||||
}
|
||||
|
||||
async patchChat(chatId, patch) {
|
||||
const current = this.data.chats[chatId] || {};
|
||||
this.data.chats[chatId] = { ...current, ...patch };
|
||||
await this.save();
|
||||
return this.data.chats[chatId];
|
||||
}
|
||||
|
||||
async save() {
|
||||
const dir = path.dirname(this.filePath);
|
||||
await fs.mkdir(dir, { recursive: true, mode: 0o700 });
|
||||
const tmp = `${this.filePath}.tmp`;
|
||||
await fs.writeFile(tmp, `${JSON.stringify(this.data, null, 2)}\n`, { mode: 0o600 });
|
||||
await fs.rename(tmp, this.filePath);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user