b2975f7d1d
registerIMAdapterFactories in internal/container/container.go had grown
to ~290 lines of platform-specific config parsing and runtime start/stop
logic across 7 IM platforms, plus three private credential helpers. The
container package is meant to wire dependencies, not own each platform's
credentials schema and websocket lifecycle.
Extract each platform's factory into its own subpackage file and expose
the credential helpers on the im package:
- New im.ParseCredentials / im.GetString / im.GetBool (formerly the
unexported parseCredentials / getString / credentialBool in container).
- New im.ResolveMode helper collapses the six identical "default to
websocket when Mode is empty" blocks.
- New {wecom,feishu,slack,telegram,dingtalk,mattermost,wechat}.NewFactory
returns an im.AdapterFactory; container.go now calls each one in a
single line.
Behavior is preserved: adapter construction, goroutine start/stop,
log messages, default modes (mattermost still defaults to "webhook";
others to "websocket"), and error strings are unchanged. The WeCom
corp_agent_id float64/int switch and the WeChat long-poll-only path
are preserved as-is.
Net: container.go drops ~320 lines and no longer needs to be touched
when adding or tuning an IM platform.
40 lines
1.3 KiB
Go
40 lines
1.3 KiB
Go
package wechat
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/Tencent/WeKnora/internal/im"
|
|
"github.com/Tencent/WeKnora/internal/logger"
|
|
)
|
|
|
|
// NewFactory returns an im.AdapterFactory for WeChat channels (iLink bot).
|
|
// WeChat only supports a long-polling mode, so there is no mode branch.
|
|
func NewFactory() im.AdapterFactory {
|
|
return func(factoryCtx context.Context, channel *im.IMChannel, msgHandler func(context.Context, *im.IncomingMessage) error) (im.Adapter, context.CancelFunc, error) {
|
|
creds, err := im.ParseCredentials(channel.Credentials)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("parse wechat credentials: %w", err)
|
|
}
|
|
|
|
botToken := im.GetString(creds, "bot_token")
|
|
ilinkBotID := im.GetString(creds, "ilink_bot_id")
|
|
|
|
if botToken == "" || ilinkBotID == "" {
|
|
return nil, nil, fmt.Errorf("wechat credentials require bot_token and ilink_bot_id")
|
|
}
|
|
|
|
adapter := NewAdapter(botToken, ilinkBotID)
|
|
client := NewLongPollClient(botToken, ilinkBotID, msgHandler)
|
|
|
|
pollCtx, pollCancel := context.WithCancel(context.Background())
|
|
go func() {
|
|
if err := client.Start(pollCtx); err != nil && pollCtx.Err() == nil {
|
|
logger.Errorf(context.Background(), "[IM] WeChat long-poll stopped for channel %s: %v", channel.ID, err)
|
|
}
|
|
}()
|
|
|
|
return adapter, pollCancel, nil
|
|
}
|
|
}
|