package dingtalk // 旧版sdk客户端 - 在用,勿删! import ( "ai_scheduler/internal/config" "ai_scheduler/internal/pkg/l_request" "bytes" "context" "encoding/json" "errors" "io" "net/http" "net/url" "os" "strings" "github.com/faabiosr/cachego/file" "github.com/fastwego/dingding" ) type OldClient struct { config *config.Config cli *dingding.Client atm *dingding.DefaultAccessTokenManager } func NewOldClient(config *config.Config) *OldClient { atm := &dingding.DefaultAccessTokenManager{ Id: config.Tools.DingTalkBot.APIKey, Name: "access_token", GetRefreshRequestFunc: func() *http.Request { params := url.Values{} params.Add("appkey", config.Tools.DingTalkBot.APIKey) params.Add("appsecret", config.Tools.DingTalkBot.APISecret) req, _ := http.NewRequest(http.MethodGet, dingding.ServerUrl+"/gettoken?"+params.Encode(), nil) return req }, Cache: file.New(os.TempDir()), } return &OldClient{config: config, cli: dingding.NewClient(atm), atm: atm} } type UserDetail struct { UserID string `json:"userid"` Name string `json:"name"` UnionID string `json:"unionid"` } func (c *OldClient) do(ctx context.Context, method, path string, body []byte) ([]byte, error) { var r io.Reader if body != nil { r = bytes.NewReader(body) } req, err := http.NewRequestWithContext(ctx, method, path, r) if err != nil { return nil, err } if body != nil { req.Header.Set("Content-Type", "application/json") } return c.cli.Do(req) } func (c *OldClient) QueryUserDetails(ctx context.Context, userId string) (*UserDetail, error) { body := struct { UserId string `json:"userid"` Language string `json:"language,omitempty"` }{UserId: userId, Language: "zh_CN"} b, _ := json.Marshal(body) res, err := c.do(ctx, http.MethodPost, "/topapi/v2/user/get", b) if err != nil { return nil, err } var resp struct { Code int `json:"errcode"` Msg string `json:"errmsg"` Result UserDetail `json:"result"` } if err := json.Unmarshal(res, &resp); err != nil { return nil, err } if resp.Code != 0 { return nil, errors.New(resp.Msg) } return &resp.Result, nil } func (c *OldClient) QueryUserDetailsByMobile(ctx context.Context, mobile string) (*UserDetail, error) { body := struct { Mobile string `json:"mobile"` }{Mobile: mobile} b, _ := json.Marshal(body) res, err := c.do(ctx, http.MethodPost, "/topapi/v2/user/getbymobile", b) if err != nil { return nil, err } var resp struct { Code int `json:"errcode"` Msg string `json:"errmsg"` Result UserDetail `json:"result"` } if err := json.Unmarshal(res, &resp); err != nil { return nil, err } if resp.Code != 0 { return nil, errors.New(resp.Msg) } return &resp.Result, nil } // GetAccessToken 通过 fastwego 的 AccessTokenManager 获取当前可用 access_token func (c *OldClient) GetAccessToken() (string, error) { return c.atm.GetAccessToken() } // CreateInternalGroupConversation 创建企业内部群聊 func (c *OldClient) CreateInternalGroupConversation(ctx context.Context, accessToken, groupName string, userIds []string) (chatId, openConversationId string, err error) { body := struct { Name string `json:"name"` Owner string `json:"owner"` UserIds []string `json:"useridlist"` ShowHistoryType int `json:"showHistoryType"` Searchable int `json:"searchable"` ValidationType int `json:"validationType"` MentionAllAuthority int `json:"mentionAllAuthority"` ManagementType int `json:"managementType"` ChatBannedType int `json:"chatBannedType"` }{ Name: groupName, Owner: userIds[0], UserIds: userIds, } b, _ := json.Marshal(body) req := l_request.Request{ Method: "POST", JsonByte: b, Url: "https://oapi.dingtalk.com/chat/create?access_token=" + accessToken, Headers: map[string]string{ "Content-Type": "application/json", }, } res, err := req.Send() if err != nil { return } var resp struct { Code int `json:"errcode"` Msg string `json:"errmsg"` ChatId string `json:"chatid"` OpenConversationId string `json:"openConversationId"` ConversationTag int `json:"conversationTag"` } if err = json.Unmarshal(res.Content, &resp); err != nil { return } if resp.Code != 0 { return "", "", errors.New(resp.Msg) } return resp.ChatId, resp.OpenConversationId, nil } // CreateSceneGroupConversation 创建场景群-基于群模板 func (c *OldClient) CreateSceneGroupConversation(ctx context.Context, accessToken, groupName string, userIds []string, templateId string) (chatId, openConversationId string, err error) { body := struct { Title string `json:"title"` // 群名称 TemplateId string `json:"template_id"` // 群模板ID OwnerUserID string `json:"owner_user_id"` // 群主的userid。 UserIds string `json:"user_ids"` // 群成员userid列表。 SubAdminIds string `json:"subadmin_ids"` // 群管理员userid列表。 UUID string `json:"uuid"` // 建群去重的业务ID,由接口调用方指定。 Icon string `json:"icon"` // 群头像,格式为mediaId。需要调用上传媒体文件接口上传群头像,获取mediaId。 MentionAllAuthority int `json:"mention_all_authority"` // @all 权限:0(默认):所有人都可以@all 1:仅群主可@all ShowHistoryType int `json:"show_history_type"` // 新成员是否可查看聊天历史消息:0(默认):不可以查看历史记录 1:可以查看历史记录 ValidationType int `json:"validation_type"` // 入群是否需要验证:0(默认):不验证入群 1:入群验证 Searchable int `json:"searchable"` // 群是否可搜索:0(默认):不可搜索 1:可搜索 ChatBannedType int `json:"chat_banned_type"` // 是否开启群禁言:0(默认):不禁言 1:全员禁言 ManagementType int `json:"management_type"` // 管理类型:0(默认):所有人可管理 1:仅群主可管理 OnlyAdminCanDing int `json:"only_admin_can_ding"` // 群内发DING权限:0(默认):所有人可发DING 1:仅群主和管理员可发DING AllMembersCanCreateMcsConf int `json:"all_members_can_create_mcs_conf"` // 群会议权限:0:仅群主和管理员可发起视频和语音会议 1(默认):所有人可发起视频和语音会议 AllMembersCanCreateCalendar int `json:"all_members_can_create_calendar"` // 群日历权限:0:仅群主和管理员可创建群日历 1(默认):所有人可创建群日历 GroupEmailDisabled int `json:"group_email_disabled"` // 群邮件权限:0(默认):群内成员可以对本群发送群邮件 1:群内成员不可对本群发送群邮件 OnlyAdminCanSetMsgTop int `json:"only_admin_can_set_msg_top"` // 置顶群消息权限:0(默认):所有人可置顶群消息 1:仅群主和管理员可置顶群消息 AddFriendForbidden int `json:"add_friend_forbidden"` // 群成员私聊权限:0(默认):所有人可私聊 1:普通群成员之间不能够加好友、单聊,且部分功能使用受限(管理员与非管理员之间不受影响) GroupLiveSwitch int `json:"group_live_switch"` // 群直播权限:0:仅群主与管理员可发起直播 1(默认):群内任意成员可发起群直播 MembersToAdminChat int `json:"members_to_admin_chat"` // 是否禁止非管理员向管理员发起单聊:0(默认):非管理员可以向管理员发起单聊 1:禁止非管理员向管理员发起单聊 }{ Title: groupName, TemplateId: templateId, OwnerUserID: userIds[0], UserIds: strings.Join(userIds, ","), SubAdminIds: strings.Join(userIds, ","), } b, _ := json.Marshal(body) req := l_request.Request{ Method: "POST", JsonByte: b, Url: "https://oapi.dingtalk.com/topapi/im/chat/scenegroup/create?access_token=" + accessToken, Headers: map[string]string{ "Content-Type": "application/json", }, } res, err := req.Send() if err != nil { return } var resp struct { Code int `json:"errcode"` Msg string `json:"errmsg"` Result struct { ChatId string `json:"chat_id"` OpenConversationId string `json:"open_conversation_id"` } `json:"result"` } if err = json.Unmarshal(res.Content, &resp); err != nil { return } if resp.Code != 0 { return "", "", errors.New(resp.Msg) } return resp.Result.ChatId, resp.Result.OpenConversationId, nil } // 获取入群二维码链接 func (c *OldClient) GetJoinGroupQrcode(ctx context.Context, chatId, userId string) (string, error) { body := struct { ChatId string `json:"chatid"` UserId string `json:"userid"` }{ChatId: chatId, UserId: userId} b, _ := json.Marshal(body) res, err := c.do(ctx, http.MethodPost, "/topapi/chat/qrcode/get", b) if err != nil { return "", err } var resp struct { Code int `json:"errcode"` Msg string `json:"errmsg"` Result string `json:"result"` } if err := json.Unmarshal(res, &resp); err != nil { return "", err } if resp.Code != 0 { return "", errors.New(resp.Msg) } return resp.Result, nil }