Skip to content

Commit bd0e6cd

Browse files
authored
refactor: code-structure (#553)
1 parent c8c73e0 commit bd0e6cd

File tree

1 file changed

+158
-86
lines changed

1 file changed

+158
-86
lines changed

bot.go

Lines changed: 158 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"errors"
7+
"fmt"
78
"io"
89
"log"
910
"net/url"
@@ -137,117 +138,188 @@ func (b *Bot) loginFromURL(path *url.URL) error {
137138
return b.webInit()
138139
}
139140

140-
// WebInit 根据有效凭证获取和初始化用户信息
141-
func (b *Bot) webInit() error {
142-
req := b.Storage.Request
143-
info := b.Storage.LoginInfo
144-
// 获取初始化的用户信息和一些必要的参数
145-
resp, err := b.Caller.WebInit(b.Context(), req)
146-
if err != nil {
147-
return err
141+
func (b *Bot) initContacts(resp *WebInitResponse) {
142+
if resp.ContactList != nil {
143+
resp.ContactList.init(b.self)
148144
}
149-
// 设置当前的用户
150-
b.self = &Self{bot: b, User: resp.User}
151-
b.self.formatEmoji()
152-
b.self.self = b.self
153-
resp.ContactList.init(b.self)
154-
// 读取和装载SyncKey
145+
}
146+
147+
func (b *Bot) updateSyncKey(resp *WebInitResponse) {
155148
if b.Storage.Response != nil {
156149
resp.SyncKey = b.Storage.Response.SyncKey
157150
}
158151
b.Storage.Response = resp
152+
}
159153

160-
if b.hotReloadStorage != nil {
161-
if err = b.DumpHotReloadStorage(); err != nil {
162-
return err
163-
}
154+
// 拆分为小函数
155+
func (b *Bot) initUserInfo() error {
156+
resp, err := b.Caller.WebInit(b.Context(), b.Storage.Request)
157+
if err != nil {
158+
return err
164159
}
165160

166-
// 构建通知手机客户端已经登录的参数
167-
notifyOption := &CallerWebWxStatusNotifyOptions{
168-
BaseRequest: req,
169-
WebInitResponse: resp,
170-
LoginInfo: info,
161+
b.initSelf(resp)
162+
b.initContacts(resp)
163+
b.updateSyncKey(resp)
164+
165+
return nil
166+
}
167+
168+
func (b *Bot) initSelf(resp *WebInitResponse) {
169+
b.self = &Self{
170+
bot: b,
171+
User: resp.User,
171172
}
172-
// 通知手机客户端已经登录
173-
if err = b.Caller.WebWxStatusNotify(b.Context(), notifyOption); err != nil {
174-
return err
173+
b.self.formatEmoji()
174+
b.self.self = b.self
175+
}
176+
177+
func (b *Bot) saveHotReloadData() error {
178+
if b.hotReloadStorage == nil {
179+
return nil
175180
}
176-
// 开启协程,轮询获取是否有新的消息返回
181+
return b.DumpHotReloadStorage()
182+
}
177183

178-
go func() {
179-
if b.MessageErrorHandler == nil {
180-
b.MessageErrorHandler = defaultMessageErrorHandler
181-
}
182-
for {
183-
if !b.Alive() {
184+
func (b *Bot) notifyMobileClient() error {
185+
notifyOption := &CallerWebWxStatusNotifyOptions{
186+
BaseRequest: b.Storage.Request,
187+
WebInitResponse: b.Storage.Response,
188+
LoginInfo: b.Storage.LoginInfo,
189+
}
190+
return b.Caller.WebWxStatusNotify(b.Context(), notifyOption)
191+
}
192+
193+
func (b *Bot) startMessageSync() {
194+
go b.runMessageLoop()
195+
}
196+
197+
func (b *Bot) runMessageLoop() {
198+
b.initMessageErrorHandler()
199+
200+
for b.Alive() {
201+
if err := b.syncCheck(); err != nil {
202+
if err = b.handleSyncError(err); err != nil {
203+
b.ExitWith(err)
184204
return
185205
}
186-
if err = b.syncCheck(); err != nil {
187-
// 判断是否继续, 如果不继续则退出
188-
if err = b.MessageErrorHandler(err); err != nil {
189-
b.ExitWith(err)
190-
return
191-
}
192-
}
193206
}
194-
}()
207+
}
208+
}
209+
210+
func (b *Bot) initMessageErrorHandler() {
211+
if b.MessageErrorHandler == nil {
212+
b.MessageErrorHandler = defaultMessageErrorHandler
213+
}
214+
}
215+
216+
func (b *Bot) handleSyncError(err error) error {
217+
return b.MessageErrorHandler(err)
218+
}
219+
220+
func (b *Bot) webInit() error {
221+
// 1. 初始化用户信息
222+
if err := b.initUserInfo(); err != nil {
223+
return fmt.Errorf("init user info: %w", err)
224+
}
225+
226+
// 2. 保存热重载数据
227+
if err := b.saveHotReloadData(); err != nil {
228+
return fmt.Errorf("save hot reload data: %w", err)
229+
}
230+
231+
// 3. 通知移动端
232+
if err := b.notifyMobileClient(); err != nil {
233+
return fmt.Errorf("notify mobile client: %w", err)
234+
}
235+
236+
// 4. 启动消息同步
237+
b.startMessageSync()
238+
239+
return nil
240+
}
241+
242+
func (b *Bot) executeSyncCallback(resp *SyncCheckResponse) {
243+
if b.SyncCheckCallback != nil {
244+
b.SyncCheckCallback(*resp)
245+
}
246+
}
247+
248+
func (b *Bot) handleMessages(messages []*Message) {
249+
if b.MessageHandler == nil {
250+
return
251+
}
252+
253+
for _, msg := range messages {
254+
msg.init(b)
255+
b.MessageHandler(msg)
256+
}
257+
}
258+
259+
func (b *Bot) processNewMessages() error {
260+
// 获取新消息
261+
messages, err := b.syncMessage()
262+
if err != nil {
263+
return fmt.Errorf("sync message failed: %w", err)
264+
}
265+
266+
// 保存热重载数据
267+
_ = b.DumpHotReloadStorage()
268+
269+
// 处理消息
270+
b.handleMessages(messages)
271+
195272
return nil
196273
}
197274

275+
func (b *Bot) handleSyncSelector(selector Selector) error {
276+
switch selector {
277+
case SelectorNormal:
278+
return nil
279+
default:
280+
return b.processNewMessages()
281+
}
282+
}
283+
284+
func (b *Bot) doSyncCheck(option *CallerSyncCheckOptions) error {
285+
// 更新同步检查参数
286+
b.updateSyncCheckOptions(option)
287+
288+
// 执行同步检查
289+
resp, err := b.Caller.SyncCheck(b.Context(), option)
290+
if err != nil {
291+
return fmt.Errorf("sync check failed: %w", err)
292+
}
293+
294+
// 执行心跳回调
295+
b.executeSyncCallback(resp)
296+
297+
// 检查响应状态
298+
if err := resp.Err(); err != nil {
299+
return resp.Err()
300+
}
301+
302+
// 处理消息
303+
return b.handleSyncSelector(resp.Selector)
304+
}
305+
306+
func (b *Bot) updateSyncCheckOptions(option *CallerSyncCheckOptions) {
307+
option.BaseRequest = b.Storage.Request
308+
option.WebInitResponse = b.Storage.Response
309+
option.LoginInfo = b.Storage.LoginInfo
310+
}
311+
198312
// 轮询请求
199313
// 根据状态码判断是否有新的请求
200314
func (b *Bot) syncCheck() error {
201-
var (
202-
err error
203-
resp *SyncCheckResponse
204-
)
205-
206-
syncCheckOption := &CallerSyncCheckOptions{}
315+
option := &CallerSyncCheckOptions{}
207316

208317
for b.Alive() {
209-
// 重制相关参数,因为它们可能是动态的
210-
syncCheckOption.BaseRequest = b.Storage.Request
211-
syncCheckOption.WebInitResponse = b.Storage.Response
212-
syncCheckOption.LoginInfo = b.Storage.LoginInfo
213-
// 长轮询检查是否有消息返回
214-
resp, err = b.Caller.SyncCheck(b.Context(), syncCheckOption)
215-
if err != nil {
318+
if err := b.doSyncCheck(option); err != nil {
216319
return err
217320
}
218-
// 执行心跳回调
219-
if b.SyncCheckCallback != nil {
220-
b.SyncCheckCallback(*resp)
221-
}
222-
// 如果不是正常的状态码返回,发生了错误,直接退出
223-
if !resp.Success() {
224-
return resp.Err()
225-
}
226-
// TODO 添加更多的状态码处理
227-
switch resp.Selector {
228-
case SelectorNormal:
229-
continue
230-
default:
231-
messages, err := b.syncMessage()
232-
if err != nil {
233-
return err
234-
}
235-
// todo 将这个错误处理交给用户
236-
_ = b.DumpHotReloadStorage()
237-
238-
for _, message := range messages {
239-
message.init(b)
240-
// 默认同步调用
241-
// 如果异步调用则需自行处理
242-
// 如配合 openwechat.MessageMatchDispatcher 使用
243-
// NOTE: 请确保 MessageHandler 不会阻塞,否则会导致收不到后续的消息
244-
if b.MessageHandler != nil {
245-
b.MessageHandler(message)
246-
}
247-
}
248-
}
249321
}
250-
return err
322+
return nil
251323
}
252324

253325
// 获取新的消息

0 commit comments

Comments
 (0)