contact.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. package hook
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/gorilla/websocket"
  6. "github.com/zeromicro/go-zero/core/logx"
  7. "strings"
  8. "wechat-api/workphone"
  9. "wechat-api/workphone/wecom"
  10. )
  11. // 获取标签信息
  12. func (h *Hook) GetContactLabelList() (result GetContactLabelListReap, err error) {
  13. resp, err := h.Client.R().SetSuccessResult(&result).Post("http://" + h.ServerIp + ":" + h.WxPort + "/GetContactLabelList")
  14. if err != nil {
  15. return
  16. }
  17. if !resp.IsSuccessState() {
  18. err = fmt.Errorf("GetContactLabelList failed with status code %d", resp.StatusCode)
  19. return
  20. }
  21. return
  22. }
  23. // 获取好友和群信息
  24. func (h *Hook) GetFriendAndChatRoomList(typeStr string) (result GetFriendAndChatRoomListReap, err error) {
  25. resp, err := h.Client.R().SetBody(&GetFriendAndChatRoomListReq{
  26. Type: typeStr,
  27. }).SetSuccessResult(&result).Post("http://" + h.ServerIp + ":" + h.WxPort + "/GetFriendAndChatRoomList")
  28. if err != nil {
  29. return
  30. }
  31. if !resp.IsSuccessState() {
  32. err = fmt.Errorf("GetFriendAndChatRoomList failed with status code %d", resp.StatusCode)
  33. return
  34. }
  35. return
  36. }
  37. // 批量获取联系人简明信息(每次100个)
  38. func (h *Hook) BatchGetContactBriefInfo(wxids []string) (result BatchGetContactBriefInfoReap, err error) {
  39. wxidList := strings.Join(wxids, ",")
  40. resp, err := h.Client.R().SetBody(&BatchGetContactBriefInfoReq{
  41. WxidList: wxidList,
  42. }).SetSuccessResult(&result).Post("http://" + h.ServerIp + ":" + h.WxPort + "/BatchGetContactBriefInfo")
  43. if err != nil {
  44. return
  45. }
  46. if !resp.IsSuccessState() {
  47. err = fmt.Errorf("BatchGetChatRoomMemberWxid failed with status code %d", resp.StatusCode)
  48. return
  49. }
  50. return
  51. }
  52. // 添加新的好友
  53. func (h *Hook) AddNewFriend(v3_wxid string, v4 string, desc string, addType string, role string) (result AddNewFriendReap, err error) {
  54. resp, err := h.Client.R().SetBody(&AddNewFriendReq{
  55. V3Wxid: v3_wxid,
  56. V4: v4,
  57. Desc: desc,
  58. AddType: addType,
  59. Role: role,
  60. }).SetSuccessResult(&result).Post("http://" + h.ServerIp + ":" + h.WxPort + "/AddNewFriend")
  61. if err != nil {
  62. return
  63. }
  64. if !resp.IsSuccessState() {
  65. err = fmt.Errorf("AddNewFriend failed with status code %d", resp.StatusCode)
  66. return
  67. }
  68. return
  69. }
  70. func (h *Hook) RequestChatRoomInfo(ChatRoomId, wxWxid string) error {
  71. conn, err := h.connWorkPhone()
  72. if err != nil {
  73. err = fmt.Errorf("RequestChatRoomInfo failed")
  74. return err
  75. }
  76. defer func(conn *websocket.Conn) {
  77. err = conn.Close()
  78. if err != nil {
  79. err = fmt.Errorf("RequestChatRoomInfo failed")
  80. }
  81. }(conn)
  82. message := map[string]interface{}{
  83. "MsgType": "RequestChatRoomInfoTask",
  84. "Content": map[string]interface{}{
  85. "WeChatId": wxWxid,
  86. "Flag": 1,
  87. "ChatRoomId": ChatRoomId,
  88. },
  89. }
  90. transportMessageJSON, err := json.Marshal(message)
  91. if err != nil {
  92. return err
  93. }
  94. // 发送 JSON 消息
  95. err = conn.WriteMessage(websocket.TextMessage, transportMessageJSON)
  96. if err != nil {
  97. return fmt.Errorf("failed to send message: %v", err)
  98. }
  99. return nil
  100. }
  101. func (h *Hook) TriggerChatroomPush(wxWxid string) error {
  102. conn, err := h.connWorkPhone()
  103. if err != nil {
  104. err = fmt.Errorf("TriggerChatroomPush failed")
  105. return err
  106. }
  107. defer func(conn *websocket.Conn) {
  108. err = conn.Close()
  109. if err != nil {
  110. err = fmt.Errorf("TriggerChatroomPush failed")
  111. }
  112. }(conn)
  113. message := map[string]interface{}{
  114. "MsgType": "TriggerChatroomPushTask",
  115. "Content": map[string]interface{}{
  116. "WeChatId": wxWxid,
  117. "Flag": 1,
  118. },
  119. }
  120. transportMessageJSON, err := json.Marshal(message)
  121. if err != nil {
  122. return err
  123. }
  124. // 发送 JSON 消息
  125. err = conn.WriteMessage(websocket.TextMessage, transportMessageJSON)
  126. if err != nil {
  127. return fmt.Errorf("failed to send message: %v", err)
  128. }
  129. return nil
  130. }
  131. // TriggerCustomerPushTask 刷新企微联系人
  132. func (h *Hook) TriggerCustomerPushTask(wxWxid string) error {
  133. conn, err := h.connWorkPhone()
  134. if err != nil {
  135. err = fmt.Errorf("TriggerCustomerPushTask failed")
  136. return err
  137. }
  138. defer func(conn *websocket.Conn) {
  139. err = conn.Close()
  140. if err != nil {
  141. err = fmt.Errorf("TriggerCustomerPushTask failed")
  142. }
  143. }(conn)
  144. message := map[string]interface{}{
  145. "MsgType": "TriggerCustomerPushTask",
  146. "Content": map[string]interface{}{
  147. "WxId": wxWxid,
  148. },
  149. }
  150. transportMessageJSON, err := json.Marshal(message)
  151. if err != nil {
  152. return err
  153. }
  154. // 发送 JSON 消息
  155. err = conn.WriteMessage(websocket.TextMessage, transportMessageJSON)
  156. if err != nil {
  157. return fmt.Errorf("failed to send message: %v", err)
  158. }
  159. return nil
  160. }
  161. // TriggerConversationPushTask 刷新企微群组
  162. func (h *Hook) TriggerConversationPushTask(wxWxid string) error {
  163. conn, err := h.connWorkPhone()
  164. if err != nil {
  165. err = fmt.Errorf("TriggerConversationPushTask failed")
  166. return err
  167. }
  168. defer func(conn *websocket.Conn) {
  169. err = conn.Close()
  170. if err != nil {
  171. err = fmt.Errorf("TriggerConversationPushTask failed")
  172. }
  173. }(conn)
  174. message := map[string]interface{}{
  175. "MsgType": "TriggerConversationPushTask",
  176. "Content": map[string]interface{}{
  177. "WxId": wxWxid,
  178. },
  179. }
  180. transportMessageJSON, err := json.Marshal(message)
  181. if err != nil {
  182. return err
  183. }
  184. // 发送 JSON 消息
  185. err = conn.WriteMessage(websocket.TextMessage, transportMessageJSON)
  186. if err != nil {
  187. return fmt.Errorf("failed to send message: %v", err)
  188. }
  189. return nil
  190. }
  191. func (h *Hook) TriggerUserLabelTask(wxWxid string) error {
  192. conn, err := h.connWorkPhone()
  193. if err != nil {
  194. err = fmt.Errorf("TriggerUserLabelTask failed")
  195. return err
  196. }
  197. defer func(conn *websocket.Conn) {
  198. err = conn.Close()
  199. if err != nil {
  200. err = fmt.Errorf("TriggerUserLabelTask failed")
  201. }
  202. }(conn)
  203. message := map[string]interface{}{
  204. "MsgType": "TriggerUserLabelTask",
  205. "Content": map[string]interface{}{
  206. "WxId": wxWxid,
  207. },
  208. }
  209. transportMessageJSON, err := json.Marshal(message)
  210. if err != nil {
  211. return err
  212. }
  213. // 发送 JSON 消息
  214. err = conn.WriteMessage(websocket.TextMessage, transportMessageJSON)
  215. if err != nil {
  216. return fmt.Errorf("failed to send message: %v", err)
  217. }
  218. return nil
  219. }
  220. func (h *Hook) AddFriendInChatRoom(ChatRoomId, wxWxid, friendId, desc string) error {
  221. conn, err := h.connWorkPhone()
  222. if err != nil {
  223. err = fmt.Errorf("AddFriendInChatRoom failed")
  224. return err
  225. }
  226. defer func(conn *websocket.Conn) {
  227. err = conn.Close()
  228. if err != nil {
  229. err = fmt.Errorf("AddFriendInChatRoom failed")
  230. }
  231. }(conn)
  232. message := map[string]interface{}{
  233. "MsgType": "AddFriendInChatRoomTask",
  234. "Content": map[string]interface{}{
  235. "WeChatId": wxWxid,
  236. "ChatroomId": ChatRoomId,
  237. "FriendId": friendId,
  238. "Message": desc,
  239. },
  240. }
  241. transportMessageJSON, err := json.Marshal(message)
  242. if err != nil {
  243. return err
  244. }
  245. // 发送 JSON 消息
  246. err = conn.WriteMessage(websocket.TextMessage, transportMessageJSON)
  247. if err != nil {
  248. return fmt.Errorf("failed to send message: %v", err)
  249. }
  250. return nil
  251. }
  252. // AddFriendsTask AddFriendTask 用于添加好友任务的消息结构
  253. type AddFriendsTask struct {
  254. WeChatId string `json:"WeChatId"`
  255. Phones []string `json:"Phones"`
  256. Message string `json:"message"`
  257. Remark string `json:"Remark"`
  258. TaskId int64 `json:"TaskId"`
  259. }
  260. // FindContactTask 用于查找联系人任务的消息结构
  261. type FindContactTask struct {
  262. WeChatId string `json:"WeChatId"`
  263. Content string `json:"Content"`
  264. }
  265. // MessagePayload 用于封装消息的负载结构
  266. type MessagePayload[T any] struct {
  267. Id workphone.EnumMsgType `json:"Id"`
  268. MsgType string `json:"MsgType"`
  269. Content T `json:"Content"`
  270. }
  271. // SendMessage 函数用于发送消息
  272. func SendMessage[T any](hook *Hook, msgType workphone.EnumMsgType, msgTypeStr string, content T) (map[string]interface{}, error) {
  273. conn, err := hook.connWorkPhone()
  274. if err != nil {
  275. logx.Errorf("WebSocket 连接失败: %v", err)
  276. return MessagePayload[T]{}.ToMap(), err
  277. }
  278. defer func() {
  279. if cerr := conn.Close(); cerr != nil {
  280. logx.Errorf("WebSocket 关闭失败: %v", cerr)
  281. }
  282. }()
  283. message := MessagePayload[T]{
  284. Id: msgType,
  285. MsgType: msgTypeStr,
  286. Content: content,
  287. }
  288. data, err := json.Marshal(message)
  289. if err != nil {
  290. return message.ToMap(), fmt.Errorf("JSON 序列化失败: %w", err)
  291. }
  292. if err := conn.WriteMessage(websocket.TextMessage, data); err != nil {
  293. return message.ToMap(), fmt.Errorf("发送消息失败: %w", err)
  294. }
  295. return message.ToMap(), nil
  296. }
  297. // AddFriendTask 函数用于创建并发送一个添加好友的任务
  298. // 参数:
  299. //
  300. // ownerWxId: 发起添加好友请求的微信ID
  301. // phone: 目标手机号
  302. // msg: 添加好友时附带的消息
  303. // taskId: 任务ID
  304. //
  305. // 返回值:
  306. //
  307. // 成功时返回包含添加好友任务信息的消息负载和nil错误
  308. // 失败时返回空的消息负载和相应的错误
  309. func (h *Hook) AddFriendTask(ownerWxId, phone, msg string, taskId int64) (map[string]interface{}, error) {
  310. if ownerWxId == "" || phone == "" || msg == "" {
  311. return MessagePayload[AddFriendsTask]{}.ToMap(), fmt.Errorf("invalid input parameters")
  312. }
  313. content := AddFriendsTask{
  314. WeChatId: ownerWxId,
  315. Phones: []string{phone},
  316. Message: msg,
  317. Remark: "",
  318. TaskId: taskId,
  319. }
  320. return SendMessage(h, workphone.EnumMsgType_AddFriendsTask, "AddFriendsTask", content)
  321. }
  322. // FindContactByContent 函数用于创建并发送一个查找联系人的任务
  323. // 参数:
  324. //
  325. // ownerWxId: 发起查找联系人请求的微信ID
  326. // contentMessage: 查找联系人的查询内容
  327. //
  328. // 返回值:
  329. //
  330. // 成功时返回包含查找联系人任务信息的消息负载和nil错误
  331. // 失败时返回空的消息负载和相应的错误
  332. func (h *Hook) FindContactByContent(ownerWxId, contentMessage string) (map[string]interface{}, error) {
  333. if ownerWxId == "" || contentMessage == "" {
  334. return MessagePayload[FindContactTask]{}.ToMap(), fmt.Errorf("invalid input parameters")
  335. }
  336. content := FindContactTask{
  337. WeChatId: ownerWxId,
  338. Content: contentMessage,
  339. }
  340. return SendMessage(h, workphone.EnumMsgType_FindContactTask, "FindContactTask", content)
  341. }
  342. func (m MessagePayload[T]) ToMap() map[string]interface{} {
  343. return map[string]interface{}{
  344. "Id": m.Id,
  345. "MsgType": m.MsgType,
  346. "Content": m.Content,
  347. }
  348. }
  349. // AddWecomCustomerFromSearchTask 函数用于创建并发送一个添加好友的任务
  350. // 参数:
  351. //
  352. // ownerWxId: 发起添加好友请求的微信ID
  353. // phone: 目标手机号 //qq号//微信id
  354. // msg: 添加好友时附带的消息
  355. // taskId: 任务ID
  356. //
  357. // 返回值:
  358. //
  359. // 成功时返回包含添加好友任务信息的消息负载和nil错误
  360. // 失败时返回空的消息负载和相应的错误
  361. func (h *Hook) AddWecomCustomerFromSearchTask(ownerWxId, phone, msg string, taskId int64) (map[string]interface{}, error) {
  362. if ownerWxId == "" || phone == "" {
  363. return MessagePayload[AddWecomCustomerFromSearchTask]{}.ToMap(), fmt.Errorf("invalid input parameters")
  364. }
  365. content := AddWecomCustomerFromSearchTask{
  366. WxId: ownerWxId,
  367. Key: phone,
  368. Msg: msg,
  369. Memo: "",
  370. TaskId: taskId,
  371. Labels: []string{0: ""},
  372. }
  373. return SendMessage(h, workphone.EnumMsgType(wecom.EnumMsgType_AddCustomerFromSearchTask), "AddCustomerFromSearchTask", content)
  374. }
  375. // AddWecomCustomerFromSearchTask 用于添加好友任务的消息结构
  376. type AddWecomCustomerFromSearchTask struct {
  377. WxId string `json:"WeChatId"`
  378. Key string `json:"Phones"`
  379. Msg string `json:"message"`
  380. Memo string `json:"Memo"`
  381. TaskId int64 `json:"TaskId"`
  382. Labels []string `json:"Labels"`
  383. }