refactor(wechat_kf): persist sync_msg cursor under $HOME

Move the sync_msg cursor file from the project-local tmp/ dir to ~/.wechat_kf_cursors.json so it survives tmp/ cleanups and cwd changes across restarts. Aligns with the weixin channel's credentials file convention.

- add wechat_kf_cursor_path config (default ~/.wechat_kf_cursors.json)
- expand ~ via os.path.expanduser in the channel init
- chmod the cursor file to 0o600 after each flush (no-op on Windows)
This commit is contained in:
6vision
2026-05-28 14:33:45 +08:00
parent 877b848370
commit 37661daf40
3 changed files with 12 additions and 3 deletions

View File

@@ -82,9 +82,11 @@ class WechatKfChannel(ChatChannel):
# corrupts URLs and triggers errcode 40014.
self.client = WeChatClient(self.corp_id, self.secret)
# Cursor file is an internal implementation detail — fixed under
# the project's `tmp/` dir, not exposed as a user-facing config.
cursor_path = os.path.join("tmp", "wechat_kf_cursors.json")
# Persist sync_msg cursor under the user's home dir by default,
# so it survives `tmp/` cleanups and cwd changes across restarts.
cursor_path = os.path.expanduser(
conf().get("wechat_kf_cursor_path") or "~/.wechat_kf_cursors.json"
)
self.cursor_store = CursorStore(cursor_path)
# WeCom requires the callback HTTP response to return within ~5s,

View File

@@ -48,6 +48,12 @@ class CursorStore:
with open(tmp_path, "w", encoding="utf-8") as f:
json.dump(self._data, f, ensure_ascii=False)
os.replace(tmp_path, self._file_path)
# Tighten permissions: cursor file lives in $HOME, restrict to owner.
# No-op on Windows.
try:
os.chmod(self._file_path, 0o600)
except Exception:
pass
except Exception as e:
logger.warning(f"[wechat_kf] failed to flush cursor file {self._file_path}: {e}")
try:

View File

@@ -157,6 +157,7 @@ available_setting = {
"wechat_kf_port": 9888, # 微信客服回调服务端口
"wechat_kf_secret": "", # 微信客服应用的secret
"wechat_kf_aes_key": "", # 微信客服回调aes_key
"wechat_kf_cursor_path": "~/.wechat_kf_cursors.json", # 微信客服sync_msg游标持久化文件路径
# 飞书配置
"feishu_port": 80, # 飞书bot监听端口仅webhook模式需要
"feishu_app_id": "", # 飞书机器人应用APP Id