wcfLink 是一个可复用的 Go 核心库,用来接入 iLink 微信通道。
它提供两种使用方式:
- 作为 Go 库嵌入到你自己的程序里
- 作为一个本地 HTTP 服务独立运行
桌面应用已经拆分到独立项目 wcfLink-GUI。
- 扫码登录
- 登录状态轮询
- 已登录账号持久化
- iLink
getupdates长轮询 - 文本消息收发
- 图片、视频、文件发送
- 图片、语音、视频、文件接收与落盘
- 本地事件存储
context_token管理- 本地 HTTP API
- SQLite 状态存储
- 公开入口:engine/engine.go
- 后台入口:cmd/wcfLink/main.go
- 应用服务:internal/app/app.go
- 协议实现:internal/ilink/client.go
- 媒体协议:internal/ilink/media.go
- 存储层:internal/store/store.go
- HTTP API:internal/httpapi/server.go
- 轮询 worker:internal/worker/poller.go
- Go
1.25+ - 默认使用 SQLite
构建并启动:
go build -o ./bin/wcfLink ./cmd/wcfLink
./bin/wcfLink默认监听地址:
127.0.0.1:17890
启动后你可以通过 HTTP API 完成扫码登录、查询账号、拉取事件、发送消息。
查看当前二进制版本:
./bin/wcfLink -version先安装模块:
go get github.com/lich0821/wcfLink@latest最小示例:
package main
import (
"context"
"log/slog"
"os"
"github.com/lich0821/wcfLink/engine"
)
func main() {
ctx := context.Background()
cfg := engine.LoadConfig()
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
eng, err := engine.New(ctx, cfg, logger)
if err != nil {
panic(err)
}
defer eng.Shutdown()
if err := eng.StartBackground(ctx); err != nil {
panic(err)
}
select {}
}无论你是通过 Go 库还是 HTTP API,登录流程都一样:
- 发起登录,拿到二维码会话
- 轮询登录状态
- 用户扫码确认
- 登录成功后账号会自动持久化,并启动长轮询
session, err := eng.StartLogin(ctx, "")
if err != nil {
return err
}
png, err := eng.GetLoginQRCodePNG(ctx, session.SessionID)
if err != nil {
return err
}
_ = os.WriteFile("qrcode.png", png, 0o644)
status, err := eng.GetLoginStatus(ctx, session.SessionID)
if err != nil {
return err
}
_ = status发起登录:
curl -s -X POST http://127.0.0.1:17890/api/accounts/login/start \
-H 'Content-Type: application/json' \
-d '{}'返回里会包含:
session_idqr_code_url
轮询登录状态:
curl -s "http://127.0.0.1:17890/api/accounts/login/status?session_id=login_xxx"如果你要直接拿二维码 PNG:
curl -o qrcode.png "http://127.0.0.1:17890/api/accounts/login/qr?session_id=login_xxx"当前 engine.Engine 已公开这些核心方法:
StartBackgroundShutdownStartLoginGetLoginStatusGetLoginSessionGetLoginQRCodePNGListAccountsListEventsGetSettingsUpdateSettingsSendTextSendMediaLogoutAccount
当前公开的版本接口:
engine.CurrentVersion()
err := eng.SendText(ctx, accountID, toUserID, "你好", "")说明:
- 如果
contextToken传空,会尝试从本地已保存的会话上下文里查 - 当前发送仍然要求对方至少先来过一条消息
err := eng.SendMedia(ctx, accountID, toUserID, "image", "/abs/path/demo.jpg", "图片说明", "")mediaType 当前支持:
imagevideofile
说明:
text不为空时,会先发文本,再发媒体- 音频内容发送当前不可用
当前可用接口:
GET /health/liveGET /health/readyGET /api/versionPOST /api/accounts/login/startGET /api/accounts/login/statusGET /api/accounts/login/qrGET /api/accountsGET /api/eventsGET /api/settingsPOST /api/settingsPOST /api/messages/send-textPOST /api/messages/send-media
curl -s http://127.0.0.1:17890/api/accountscurl -s http://127.0.0.1:17890/api/versioncurl -s "http://127.0.0.1:17890/api/events?after_id=0&limit=100"返回的事件里会包含:
directionevent_typefrom_user_idto_user_idbody_textmedia_pathmedia_file_namemedia_mime_type
curl -s -X POST http://127.0.0.1:17890/api/messages/send-text \
-H 'Content-Type: application/json' \
-d '{
"account_id": "xxx@im.bot",
"to_user_id": "yyy@im.wechat",
"text": "你好"
}'curl -s -X POST http://127.0.0.1:17890/api/messages/send-media \
-H 'Content-Type: application/json' \
-d '{
"account_id": "xxx@im.bot",
"to_user_id": "yyy@im.wechat",
"type": "image",
"file_path": "/absolute/path/to/demo.jpg",
"text": "图片说明"
}'说明:
type可传image、video、filetext可选- 当前音频内容发送不可用
入站媒体默认保存到:
<state-dir>/media/
事件记录中会保存:
media_pathmedia_file_namemedia_mime_type
支持环境变量:
WCFLINK_LISTEN_ADDRWCFLINK_STATE_DIRWCFLINK_DB_PATHWCFLINK_MEDIA_DIRWCFLINK_BASE_URLWCFLINK_CDN_BASE_URLWCFLINK_CHANNEL_VERSIONWCFLINK_POLL_TIMEOUTWCFLINK_LOG_LEVEL
默认配置:
- 数据目录:
./bin/data/ - 数据库:
./bin/data/wcfLink.db - 媒体目录:
<state-dir>/media/