diff --git a/README.md b/README.md index d90b36c..b8c588b 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ release:编译好的dll。 4.特别注意数据库查询接口需要先调用获取到句柄之后,才能进行查询。 5.相关功能只在win11环境下进行简单测试,其他环境无法保证。 6.注意个别接口在3.8.0.41版本没有实现,具体参考源码。 +7.对应分支接口文档都是支持指定版本的,其他版本不支持,请特别注意版本。 #### 编译环境 @@ -67,18 +68,30 @@ vcpkg } ``` -4.vscode中右键configure all projects,在Terminal中点击Run Task,如没有先配置build任务,然后运行即可 +4.vscode中右键configure all projects,在Terminal中点击Run Task,如没有先配置build任务,然后运行即可 + +5.命令行注入工具,注入命令 +``` javascript + //-i 注入程序名 -p 注入dll路径 + // -u 卸载程序名 -d 卸载dll名称 + //注入 + ConsoleInject.exe -i demo.exe -p E:\testInject.dll + //卸载 + ConsoleInject.exe -u demo.exe -d testInject.dll +``` #### 更新说明 2022-12-26 : 增加3.8.1.26版本支持。 2022-12-29 : 新增提取文字功能。 -2022-01-02 : 退出微信登录。 +2023-01-02 : 退出微信登录。 -2022-01-31 : 新增修改群昵称(仅支持3.8.1.26)。 +2023-01-31 : 新增修改群昵称(仅支持3.8.1.26)。 -2022-02-01 : 新增拍一拍(仅支持3.8.1.26)。 +2023-02-01 : 新增拍一拍(仅支持3.8.1.26)。 + +2023-02-04 : 新增群消息置顶和取消置顶。 ### 接口文档: #### 0.检查微信登录** @@ -934,6 +947,81 @@ vcpkg ``` +#### 51.群内消息置顶** +###### 接口功能 +> 在群聊里置顶某条消息,可以置顶文字和图片消息,其他消息未测试,部分低版本移动端置顶消息点击后会直接取消,高版本会一直置顶,其他未测试。 + +###### 接口地址 +> [/api/?type=51](/api/?type=51) + +###### HTTP请求方式 +> POST JSON + +###### 请求参数 +|参数|必选|类型|说明| +|---|---|---|---| +|wxid |ture |string| 置顶消息的发送人wxid | +|msgid |ture |string| 消息id | +###### 返回字段 +|返回字段|字段类型|说明 | +|---|---|---| +|code|int|返回状态,0成功, -1失败,-2 未查到该消息| +|result|string|成功提示| + + + +###### 接口示例 +入参: +``` javascript +{ + "wxid":"wxid_oy11111p4422", + "msgid":3334956046278903121 +} + +``` +响应: +``` javascript +{"code":0,"result":"OK"} +``` + + +#### 52.取消群内消息置顶** +###### 接口功能 +> 取消置顶的消息。部分低版本移动端会不显示移除消息,但是会正常移除。 + +###### 接口地址 +> [/api/?type=52](/api/?type=52) + +###### HTTP请求方式 +> POST JSON + +###### 请求参数 +|参数|必选|类型|说明| +|---|---|---|---| +|chatRoomId |ture |string| 微信群聊id | +|msgid |ture |string| 消息id | +###### 返回字段 +|返回字段|字段类型|说明 | +|---|---|---| +|code|int|返回状态,0成功, -1失败| +|result|string|成功提示| + + + +###### 接口示例 +入参: +``` javascript +{ + "chatRoomId":"2136311004@chatroom", + "msgid":3374951233278903120 +} + +``` +响应: +``` javascript +{"code":0,"result":"OK"} +``` + #### 感谢 https://github.com/ljc545w/ComWeChatRobot diff --git a/src/api.cc b/src/api.cc index 61efb34..7751bf7 100644 --- a/src/api.cc +++ b/src/api.cc @@ -568,6 +568,22 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) { ret = ret_data.dump(); break; } + case WECHAT_SET_TOP_MSG:{ + wstring wxid = get_http_req_param(hm, j_param, "wxid", is_post); + ULONG64 msgid = get_http_param_ulong64(hm, j_param, "msgid", is_post); + int success = SetTopMsg(WS2LW(wxid),msgid); + json ret_data = {{"code", success}, {"result", "OK"}}; + ret = ret_data.dump(); + break; + } + case WECHAT_REMOVE_TOP_MSG:{ + wstring room_id = get_http_req_param(hm, j_param, "chatRoomId", is_post); + ULONG64 msgid = get_http_param_ulong64(hm, j_param, "msgid", is_post); + int success = RemoveTopMsg(WS2LW(room_id),msgid); + json ret_data = {{"code", success}, {"result", "OK"}}; + ret = ret_data.dump(); + break; + } default: break; } diff --git a/src/api.h b/src/api.h index 1c2a361..2cff9e5 100644 --- a/src/api.h +++ b/src/api.h @@ -65,6 +65,8 @@ typedef enum WECHAT_HTTP_APISTag WECHAT_GET_IMG_BY_NAME, WECHAT_DO_OCR, WECHAT_SEND_PAT_MSG, + WECHAT_SET_TOP_MSG, + WECHAT_REMOVE_TOP_MSG, } WECHAT_HTTP_APIS, *PWECHAT_HTTP_APIS; diff --git a/src/chat_room.cc b/src/chat_room.cc index 162da51..c031975 100644 --- a/src/chat_room.cc +++ b/src/chat_room.cc @@ -2,8 +2,9 @@ #include "chat_room.h" #include "common.h" - +#include "get_db_handle.h" #include "wechat_data.h" +#include "base64.h" #define WX_CHAT_ROOM_MGR_OFFSET 0x67ee70 #define WX_GET_CHAT_ROOM_DETAIL_INFO_OFFSET 0xa73a80 #define WX_NEW_CHAT_ROOM_INFO_OFFSET 0xd07010 @@ -16,6 +17,9 @@ #define WX_INIT_CHAT_ROOM_OFFSET 0xd04d80 #define WX_FREE_CHAT_ROOM_OFFSET 0xa7c620 #define WX_MOD_CHAT_ROOM_MEMBER_NICK_NAME_OFFSET 0xa6f8f0 +#define WX_NEW_CHAT_MSG_OFFSET 0x64adc0 +#define WX_TOP_MSG_OFFSET 0xa76e60 +#define WX_REMOVE_TOP_MSG_OFFSET 0xa76c50 int GetChatRoomDetailInfo(wchar_t* chat_room_id, ChatRoomInfoInner& room_info) { int success = 0; @@ -216,5 +220,96 @@ int ModChatRoomMemberNickName(wchar_t* chat_room_id,wchar_t* wxid,wchar_t * nick MOV success,EAX POPAD } + return success; +} + + +int SetTopMsg(wchar_t* wxid,ULONG64 msg_id){ + int success = -1; + char chat_msg[0x2A8] ={0}; + DWORD base = GetWeChatWinBase(); + DWORD new_chat_msg_addr = base + WX_NEW_CHAT_MSG_OFFSET; + DWORD get_chat_room_mgr_addr = base + WX_CHAT_ROOM_MGR_OFFSET; + DWORD handle_top_msg_addr = base + WX_TOP_MSG_OFFSET; + vector local_msg = GetChatMsgByMsgId(msg_id); + if(local_msg.empty()){ + return -2; + } + string type = local_msg[3]; + string status = local_msg[10]; + string talker = local_msg[13]; + string content = local_msg[14]; + wstring w_talker = String2Wstring(talker); + wstring w_content = String2Wstring(content); + int msg_type =stoi(type); + int msg_status =stoi(status); + + #ifdef _DEBUG + wcout << "w_talker:" < GetChatMsgByMsgId(ULONG64 msgid){ + char sql[260] = {0}; + sprintf_s(sql, "select localId,TalkerId,MsgSvrID,Type,SubType,IsSender,CreateTime,Sequence,StatusEx,FlagEx,Status,MsgServerSeq,MsgSequence,StrTalker,StrContent,BytesExtra from MSG where MsgSvrID=%llu;", msgid); + wchar_t dbname[20] = {0}; + for (int i = 0;; i++) { + swprintf_s(dbname, L"MSG%d.db", i); + DWORD handle = GetDbHandleByDbName(dbname); + if (handle == 0) return {}; + vector> result; + int ret = Select(handle, (const char *)sql, result); + #ifdef _DEBUG + cout <<" size =" < +#include std::vector GetDbHandles(); DWORD GetDbHandleByDbName(wchar_t *dbname); unsigned int GetLocalIdByMsgId(ULONG64 msgid, int &dbIndex); +std::vector GetChatMsgByMsgId(ULONG64 msgid); #endif \ No newline at end of file