From b364885daf845dff3bc74a617b5e63b7310a1fba Mon Sep 17 00:00:00 2001 From: hugy <504650082@qq.com> Date: Tue, 8 Aug 2023 17:41:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8F=91=E9=80=81@=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/3.9.5.81.md | 100 ++++++++++++++++++++++++++++++++++++ src/http_server_callback.cc | 38 ++++++++++++-- src/manager.cc | 100 ++++++++++++++++++++++++++++++++++++ src/manager.h | 6 +++ src/wechat_function.h | 16 ++++++ 5 files changed, 257 insertions(+), 3 deletions(-) diff --git a/doc/3.9.5.81.md b/doc/3.9.5.81.md index a98368b..c3f8143 100644 --- a/doc/3.9.5.81.md +++ b/doc/3.9.5.81.md @@ -1265,4 +1265,104 @@ enableHttp=0时,使用ip,port的tcp服务回传消息。 "data": null, "msg": "success" } +``` + +#### 25.发送@消息** +###### 接口功能 +> 发送@消息 + +###### 接口地址 +> [/api/sendAtText](/api/sendAtText) + +###### HTTP请求方式 +> POST JSON + +###### 请求参数 +|参数|必选|类型|说明| +|---|---|---|---| +|wxids|string|wxid字符串,多个用,分隔,发送所有人传值"notify@all"| +|chatRoomId|string|群id| +|msg|string|消息内容| + +###### 返回字段 +|返回字段|字段类型|说明 | +|---|---|---| +|code|int|返回状态,大于0成功, -1失败| +|msg|string|成功提示| +|data|object|null| + + +###### 接口示例 + +入参: +``` javascript +{ + + "wxids":"notify@all", + "chatRoomId":"123@chatroom", + "msg":"你们好啊" + +} + +``` +响应: +``` javascript +{ + "code": 67316444768, + "data": null, + "msg": "success" +} +``` + +#### 26.获取群成员信息** +###### 接口功能 +> 获取群成员基础信息 + +###### 接口地址 +> [/api/getContactProfile](/api/getContactProfile) + +###### HTTP请求方式 +> POST JSON + +###### 请求参数 +|参数|必选|类型|说明| +|---|---|---|---| +|wxid|string|wxid| + + +###### 返回字段 +|返回字段|字段类型|说明 | +|---|---|---| +|code|int|返回状态,大于0成功, -1失败| +|msg|string|成功提示| +|data|object|null| +|  account|string|账号| +|  headImage|string|头像| +|  nickname|string|昵称| +|  v3|string|v3| +|  wxid|string|wxid| + +###### 接口示例 + +入参: +``` javascript + +{ + "wxid":"wxid_123" +} + +``` +响应: +``` javascript +{ + "code": 1, + "data": { + "account": "account", + "headImage": "https://wx.qlogo.cn/mmhead/ver_1/0", + "nickname": "test", + "v3": "wxid_123", + "wxid": "wxid_123" + }, + "msg": "success" +} ``` \ No newline at end of file diff --git a/src/http_server_callback.cc b/src/http_server_callback.cc index d76be63..b914430 100644 --- a/src/http_server_callback.cc +++ b/src/http_server_callback.cc @@ -467,12 +467,44 @@ std::string HttpDispatch(struct mg_connection *c, struct mg_http_message *hm) { {"code", success}, {"msg", "success"}, {"data", {}}}; ret = ret_data.dump(); return ret; - } else { + } else if (mg_http_match_uri(hm, "/api/sendAtText")) { + std::wstring chat_room_id = GetWStringParam(j_param, "chatRoomId"); + std::vector wxids = GetArrayParam(j_param, "wxids"); + std::wstring msg = GetWStringParam(j_param, "msg"); + std::vector wxid_list; + for (unsigned int i = 0; i < wxids.size(); i++) { + wxid_list.push_back(wxids[i]); + } + INT64 success = wxhelper::GlobalContext::GetInstance().mgr->SendAtText( + chat_room_id, wxid_list, msg); nlohmann::json ret_data = { - {"code", 200}, {"data", {}}, {"msg", "not support url"}}; + {"code", success}, {"msg", "success"}, {"data", {}}}; ret = ret_data.dump(); return ret; - } + } else if (mg_http_match_uri(hm, "/api/getContactProfile")) { + std::wstring wxid = GetWStringParam(j_param, "wxid"); + common::ContactProfileInner profile; + int success = wxhelper::GlobalContext::GetInstance().mgr->GetContactByWxid( + wxid, profile); + nlohmann::json ret_data = { + {"code", success}, {"msg", "success"}, {"data", {}}}; + if (success == 1) { + nlohmann::json contact_profile = { + {"account", profile.account}, {"headImage", profile.head_image}, + {"nickname", profile.nickname}, {"v3", profile.v3}, + {"wxid", profile.wxid}, + }; + ret_data["data"] = contact_profile; + } + ret = ret_data.dump(); + return ret; + + } else { + nlohmann::json ret_data = { + {"code", 200}, {"data", {}}, {"msg", "not support url"}}; + ret = ret_data.dump(); + return ret; + } nlohmann::json ret_data = { {"code", 200}, {"data", {}}, {"msg", "unreachable code."}}; ret = ret_data.dump(); diff --git a/src/manager.cc b/src/manager.cc index 1639638..713afd3 100644 --- a/src/manager.cc +++ b/src/manager.cc @@ -683,4 +683,104 @@ INT64 Manager::AddFavFromImage(const std::wstring &wxid, return success; } +INT64 Manager::SendAtText(const std::wstring &room_id, + const std::vector &wxids, + const std::wstring &msg) { + INT64 success = -1; + std::vector wxid_list; + common::VectorInner *list = (common::VectorInner *)&wxid_list; + std::wstring at_msg = L""; + int number = 0; + for (unsigned int i = 0; i < wxids.size(); i++) { + std::wstring nickname; + std::wstring at_all = L"notify@all"; + if (at_all.compare(wxids[i]) == 0 ) { + nickname = L"所有人"; + } else { + nickname = GetContactOrChatRoomNickname(wxids[i]); + } + if (nickname.length() == 0) { + continue; + } + prototype::WeChatString id(wxids[i]); + wxid_list.push_back(id); + at_msg = at_msg + L"@" + nickname + L" "; + number++; + } + if (number < 1) { + return success; + } + at_msg += msg; + + INT64 head = (INT64)&list->start; + prototype::WeChatString to_user(room_id); + prototype::WeChatString text_msg(at_msg); + UINT64 send_message_mgr_addr = base_addr_ + offset::kGetSendMessageMgr; + UINT64 send_text_msg_addr = base_addr_ + offset::kSendTextMsg; + UINT64 free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg; + char chat_msg[0x460] = {0}; + func::__GetSendMessageMgr mgr; + mgr = (func::__GetSendMessageMgr)send_message_mgr_addr; + func::__SendTextMsg send; + send = (func::__SendTextMsg)send_text_msg_addr; + func::__FreeChatMsg free; + free = (func::__FreeChatMsg)free_chat_msg_addr; + mgr(); + success = send(reinterpret_cast(&chat_msg), + reinterpret_cast(&to_user), + reinterpret_cast(&text_msg), head, 1, 1, 0, 0); + free(reinterpret_cast(&chat_msg)); + return success; +} + +std::wstring Manager::GetContactOrChatRoomNickname(const std::wstring &wxid) { + prototype::WeChatString to_user(wxid); + UINT64 get_contact_mgr_addr = base_addr_ + offset::kGetContactMgr; + UINT64 new_contact_addr = base_addr_ + offset::kNewContact; + UINT64 get_contact_addr = base_addr_ + offset::kGetContact; + UINT64 free_contact_addr = base_addr_ + offset::kFreeContact; + func::__GetContactMgr get_contact_mgr = + (func::__GetContactMgr)get_contact_mgr_addr; + func::__GetContact get_contact = (func::__GetContact)get_contact_addr; + func::__NewContact new_contact = (func::__NewContact)new_contact_addr; + func::__FreeContact free_contact = (func::__FreeContact)free_contact_addr; + char buff[0x6A9] = {0}; + UINT64 contact = new_contact(reinterpret_cast(&buff)); + UINT64 mgr = get_contact_mgr(); + INT64 success = get_contact(mgr, reinterpret_cast(&to_user), contact); + if (success == 1) { + std::wstring nickname = Utils::ReadWstring(contact + 0xA0); + free_contact(contact); + return nickname; + } else { + free_contact(contact); + return L""; + } +} + +INT64 Manager::GetContactByWxid(const std::wstring &wxid, + common::ContactProfileInner &profile) { + INT64 success = -1; + prototype::WeChatString to_user(wxid); + UINT64 get_contact_mgr_addr = base_addr_ + offset::kGetContactMgr; + UINT64 new_contact_addr = base_addr_ + offset::kNewContact; + UINT64 get_contact_addr = base_addr_ + offset::kGetContact; + UINT64 free_contact_addr = base_addr_ + offset::kFreeContact; + func::__GetContactMgr get_contact_mgr = + (func::__GetContactMgr)get_contact_mgr_addr; + func::__GetContact get_contact = (func::__GetContact)get_contact_addr; + func::__NewContact new_contact = (func::__NewContact)new_contact_addr; + func::__FreeContact free_contact = (func::__FreeContact)free_contact_addr; + char buff[0x6A9] = {0}; + UINT64 contact = new_contact(reinterpret_cast(&buff)); + UINT64 mgr = get_contact_mgr(); + success = get_contact(mgr, reinterpret_cast(&to_user), contact); + profile.wxid = Utils::ReadWstringThenConvert(contact + 0x10); + profile.account = Utils::ReadWstringThenConvert(contact + 0x30); + profile.v3 = Utils::ReadWstringThenConvert(contact + 0x50); + profile.nickname = Utils::ReadWstringThenConvert(contact + 0xA0); + profile.head_image = Utils::ReadWstringThenConvert(contact + 0x188); + free_contact(contact); + return success; +} } // namespace wxhelper \ No newline at end of file diff --git a/src/manager.h b/src/manager.h index eb3cc24..ed7c46f 100644 --- a/src/manager.h +++ b/src/manager.h @@ -37,6 +37,12 @@ class Manager { INT64 AddFavFromMsg(UINT64 msg_id); INT64 AddFavFromImage(const std::wstring& wxid, const std::wstring& image_path); + INT64 SendAtText(const std::wstring& room_id, + const std::vector& wxids, + const std::wstring& msg); + std::wstring GetContactOrChatRoomNickname(const std::wstring& wxid); + INT64 GetContactByWxid(const std::wstring& wxid, + common::ContactProfileInner& profile); private: UINT64 base_addr_; diff --git a/src/wechat_function.h b/src/wechat_function.h index 9939277..4acd43f 100644 --- a/src/wechat_function.h +++ b/src/wechat_function.h @@ -198,6 +198,16 @@ struct ChatRoomMemberInner { member("") {} }; +struct ContactProfileInner { + std::string wxid; + std::string account; + std::string v3; + std::string nickname; + std::string head_image; + ContactProfileInner() + : wxid(""), account(""), v3(""), nickname(""), head_image("") {} +}; + } // namespace common namespace V3_9_5_81 { namespace function { @@ -251,6 +261,9 @@ typedef UINT64 (*__AddFavFromMsg)(UINT64,UINT64); typedef UINT64 (*__GetChatMgr)(); typedef UINT64 (*__GetFavoriteMgr)(); typedef UINT64 (*__AddFavFromImage)(UINT64,UINT64,UINT64); +typedef UINT64 (*__GetContact)(UINT64,UINT64,UINT64); +typedef UINT64 (*__NewContact)(UINT64); +typedef UINT64 (*__FreeContact)(UINT64); } // namespace function @@ -368,6 +381,9 @@ const UINT64 kAddFavFromMsg = 0x1601520; const UINT64 kGetChatMgr = 0x8f0400; const UINT64 kGetFavoriteMgr = 0x8c69b0; const UINT64 kAddFavFromImage = 0x160b920; +const UINT64 kGetContact = 0xEA5F90; +const UINT64 kNewContact = 0x1212e40; +const UINT64 kFreeContact = 0x12134e0; } // namespace offset } // namespace V3_9_5_81