fix(auto decrypt): fix remote serve fsnotify watch

This commit is contained in:
Shen Junzheng 2025-08-28 17:06:32 +08:00
parent 74e568085b
commit bf791e1421
6 changed files with 44 additions and 10 deletions

View File

@ -216,6 +216,8 @@ GET /api/v1/chatlog?time=2023-01-01&talker=wxid_xxx
需开启自动解密功能,当收到特定新消息时,可以通过 HTTP POST 请求将消息推送到指定的 URL。
> 延迟测试: 本地服务消息回调延迟约 13 秒; 远程同步消息回调延迟约 45 秒。
#### 0. 回调配置
使用 TUI 模式的话,在 `$HOME/.chatlog/chatlog.json` 配置文件中,新增 `webhook` 配置。

View File

@ -9,6 +9,8 @@ import (
func init() {
rootCmd.AddCommand(serverCmd)
serverCmd.PersistentPreRun = initLog
serverCmd.PersistentFlags().BoolVar(&Debug, "debug", false, "debug")
serverCmd.Flags().StringVarP(&serverAddr, "addr", "a", "", "server address")
serverCmd.Flags().StringVarP(&serverPlatform, "platform", "p", "", "platform")
serverCmd.Flags().IntVarP(&serverVer, "version", "v", 0, "version")

View File

@ -246,8 +246,8 @@ docker-compose down
#### 配置指南
- 本地配置: 同步数据目录(Data Dir),可设置为仅发送
- 远程服务器配置: 设置为仅接收
- 本地配置: 同步数据目录(Data Dir),可设置为仅发送;在首次完整同步文件后,建议将 "rescanIntervalS" 设置为 0全局扫描较为耗时且扫描过程中会暂停同步
- 远程服务器配置: 设置为仅接收,同样建议将 "rescanIntervalS" 设置为 0
- 使用 Docker / Docker Compose 启动 chatlog将数据目录映射到容器的 `/app/data` 目录
- 按需配置 `/app/work` 映射目录,可配置到远程服务器本地路径或命名卷
- 启动容器后,等待首次解密完成后,即可正常请求 API 或接入 MCP 服务

View File

@ -68,6 +68,7 @@ func (s *Service) GetDataKey(info *wechat.Account) (string, error) {
}
func (s *Service) StartAutoDecrypt() error {
log.Info().Msgf("start auto decrypt, data dir: %s", s.conf.GetDataDir())
dbGroup, err := filemonitor.NewFileGroup("wechat", s.conf.GetDataDir(), `.*\.db$`, []string{"fts"})
if err != nil {
return err
@ -94,7 +95,15 @@ func (s *Service) StopAutoDecrypt() error {
}
func (s *Service) DecryptFileCallback(event fsnotify.Event) error {
if event.Op.Has(fsnotify.Chmod) || !event.Op.Has(fsnotify.Write) {
// Local file system
// WRITE "/db_storage/message/message_0.db"
// WRITE "/db_storage/message/message_0.db"
// WRITE|CHMOD "/db_storage/message/message_0.db"
// Syncthing
// REMOVE "/app/data/db_storage/session/session.db"
// CREATE "/app/data/db_storage/session/session.db" ← "/app/data/db_storage/session/.syncthing.session.db.tmp"
// CHMOD "/app/data/db_storage/session/session.db"
if !(event.Op.Has(fsnotify.Write) || event.Op.Has(fsnotify.Create)) {
return nil
}

View File

@ -358,6 +358,11 @@ func (m *Message) PlainTextContent() string {
keylist = append(keylist, path)
}
}
if m.Contents["thumbpath"] != nil {
if thumbpath, ok := m.Contents["thumbpath"].(string); ok {
keylist = append(keylist, thumbpath)
}
}
return fmt.Sprintf("![图片](http://%s/image/%s)", m.Contents["host"], strings.Join(keylist, ","))
case MessageTypeVoice:
if voice, ok := m.Contents["voice"]; ok {

View File

@ -89,14 +89,22 @@ func (m *MessageV3) Wrap() *Message {
if _m.IsChatRoom {
_m.Sender = bytesExtra[1]
}
// FIXME xml 中的 md5 数据无法匹配到 hardlink 记录,所以直接用 proto 数据
if _m.Type == 43 {
path := bytesExtra[4]
parts := strings.Split(filepath.ToSlash(path), "/")
if len(parts) > 1 {
path = strings.Join(parts[1:], "/")
// 图片处理
if _m.Type == MessageTypeImage {
if len(bytesExtra[4]) > 0 {
_m.Contents["path"] = ParseBytesExtraPath(bytesExtra[4])
}
if len(bytesExtra[3]) > 0 {
_m.Contents["thumbpath"] = ParseBytesExtraPath(bytesExtra[3])
}
}
// FIXME xml 中的 md5 数据无法匹配到 hardlink 记录,所以直接用 proto 数据
if _m.Type == MessageTypeVideo {
if len(bytesExtra[4]) > 0 {
_m.Contents["path"] = ParseBytesExtraPath(bytesExtra[4])
}
_m.Contents["videofile"] = path
}
}
}
@ -122,3 +130,11 @@ func ParseBytesExtra(b []byte) map[int]string {
return ret
}
func ParseBytesExtraPath(s string) string {
parts := strings.Split(filepath.ToSlash(s), "/")
if len(parts) > 1 {
return strings.Join(parts[1:], "/")
}
return s
}