156 lines
4.6 KiB
Go
156 lines
4.6 KiB
Go
package docker
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"gitee.ltd/lxh/wechat-robot/internal/config"
|
|
"gitee.ltd/lxh/wechat-robot/internal/model"
|
|
)
|
|
|
|
const (
|
|
// WechatBotLabelKey 微信机器人容器标签键
|
|
WechatBotLabelKey = "app.type"
|
|
// WechatBotLabelValue 微信机器人容器标签值
|
|
WechatBotLabelValue = "wechat-bot"
|
|
)
|
|
|
|
// APIResponse API响应结构
|
|
type APIResponse struct {
|
|
Success bool `json:"success"`
|
|
Message string `json:"message"`
|
|
Data interface{} `json:"data"`
|
|
}
|
|
|
|
// CreateRobotContainer 创建微信机器人容器
|
|
func CreateRobotContainer(ctx context.Context, cfg *config.DockerConfig, robotName string) (string, error) {
|
|
// 创建容器标签
|
|
labels := map[string]string{
|
|
WechatBotLabelKey: WechatBotLabelValue,
|
|
"robot.name": robotName,
|
|
}
|
|
|
|
// 创建环境变量
|
|
env := []string{
|
|
"BOT_NAME=" + robotName,
|
|
}
|
|
|
|
// 创建容器
|
|
containerID, err := CreateContainer(ctx, cfg, "wechat-bot-"+robotName, env, labels)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// 启动容器
|
|
err = StartContainer(ctx, containerID)
|
|
if err != nil {
|
|
// 如果启动失败,尝试删除容器
|
|
RemoveContainer(ctx, containerID, true)
|
|
return "", err
|
|
}
|
|
|
|
return containerID, nil
|
|
}
|
|
|
|
// GetLoginQRCode 获取登录二维码
|
|
func GetLoginQRCode(ctx context.Context, containerID string) (string, error) {
|
|
// 使用新的ExecuteCommandWithOutput函数
|
|
return ExecuteCommandWithOutput(ctx, containerID, []string{"cat", "/data/qrcode.png"})
|
|
}
|
|
|
|
// LogoutWechatBot 登出微信机器人
|
|
func LogoutWechatBot(ctx context.Context, containerID string) error {
|
|
// 使用新的ExecuteCommandWithOutput函数
|
|
output, err := ExecuteCommandWithOutput(ctx, containerID, []string{"curl", "-X", "POST", "http://localhost:3000/api/logout"})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to execute logout command: %w", err)
|
|
}
|
|
|
|
// 解析API响应
|
|
var response APIResponse
|
|
if err := json.Unmarshal([]byte(output), &response); err != nil {
|
|
return fmt.Errorf("failed to parse logout response: %w", err)
|
|
}
|
|
|
|
if !response.Success {
|
|
return fmt.Errorf("logout failed: %s", response.Message)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetWechatBotStatus 获取微信机器人状态
|
|
func GetWechatBotStatus(ctx context.Context, containerID string) (model.RobotStatus, string, error) {
|
|
// 检查容器状态
|
|
status, err := GetContainerStatus(ctx, containerID)
|
|
if err != nil {
|
|
return model.RobotStatusError, "", fmt.Errorf("failed to get container status: %w", err)
|
|
}
|
|
|
|
if status != "running" {
|
|
return model.RobotStatusOffline, "", nil
|
|
}
|
|
|
|
// 使用新的ExecuteCommandWithOutput函数
|
|
output, err := ExecuteCommandWithOutput(ctx, containerID, []string{"curl", "http://localhost:3000/api/status"})
|
|
if err != nil {
|
|
return model.RobotStatusError, "", fmt.Errorf("failed to get status result: %w", err)
|
|
}
|
|
|
|
// 解析API响应
|
|
var response APIResponse
|
|
if err := json.Unmarshal([]byte(output), &response); err != nil {
|
|
return model.RobotStatusError, "", fmt.Errorf("failed to parse status response: %w", err)
|
|
}
|
|
|
|
if !response.Success {
|
|
return model.RobotStatusError, response.Message, nil
|
|
}
|
|
|
|
// 解析状态数据
|
|
data, ok := response.Data.(map[string]interface{})
|
|
if !ok {
|
|
return model.RobotStatusError, "invalid status data format", nil
|
|
}
|
|
|
|
isLoggedIn, ok := data["isLoggedIn"].(bool)
|
|
if !ok {
|
|
return model.RobotStatusError, "invalid login status format", nil
|
|
}
|
|
|
|
if isLoggedIn {
|
|
return model.RobotStatusOnline, "", nil
|
|
}
|
|
|
|
return model.RobotStatusOffline, "", nil
|
|
}
|
|
|
|
// ListWechatBots 列出所有微信机器人容器
|
|
func ListWechatBots(ctx context.Context) ([]ContainerInfo, error) {
|
|
// 过滤条件:所有微信机器人容器
|
|
filter := map[string][]string{
|
|
"label": {fmt.Sprintf("%s=%s", WechatBotLabelKey, WechatBotLabelValue)},
|
|
}
|
|
|
|
return ListContainers(ctx, filter)
|
|
}
|
|
|
|
// GetWechatContacts 获取微信联系人列表
|
|
func GetWechatContacts(ctx context.Context, containerID string) (string, error) {
|
|
return ExecuteCommandWithOutput(ctx, containerID, []string{"curl", "http://localhost:3000/api/contacts"})
|
|
}
|
|
|
|
// GetWechatGroupMembers 获取微信群成员
|
|
func GetWechatGroupMembers(ctx context.Context, containerID string, groupID string) (string, error) {
|
|
return ExecuteCommandWithOutput(ctx, containerID, []string{
|
|
"curl", fmt.Sprintf("http://localhost:3000/api/group/%s/members", groupID),
|
|
})
|
|
}
|
|
|
|
// GetWechatMessages 获取微信消息历史
|
|
func GetWechatMessages(ctx context.Context, containerID string, contactID string, limit int) (string, error) {
|
|
return ExecuteCommandWithOutput(ctx, containerID, []string{
|
|
"curl", fmt.Sprintf("http://localhost:3000/api/messages/%s?limit=%d", contactID, limit),
|
|
})
|
|
}
|