github.com/Mrs4s/MiraiGo@v0.0.0-20240226124653-54bdd873e3fe/client/recall.go (about) 1 package client 2 3 import ( 4 "github.com/pkg/errors" 5 6 "github.com/Mrs4s/MiraiGo/client/internal/network" 7 "github.com/Mrs4s/MiraiGo/client/pb/msg" 8 "github.com/Mrs4s/MiraiGo/internal/proto" 9 "github.com/Mrs4s/MiraiGo/message" 10 ) 11 12 // 撤回相关处理逻辑 13 14 func (c *QQClient) RecallGroupMessage(groupCode int64, msgID, msgInternalId int32) error { 15 if m, _ := c.GetGroupMessages(groupCode, int64(msgID), int64(msgID)); len(m) > 0 { 16 content := m[0].OriginalObject.Content 17 if content.PkgNum.Unwrap() > 1 { 18 if m, err := c.GetGroupMessages(groupCode, int64(msgID-content.PkgIndex.Unwrap()-1), int64(msgID+(content.PkgNum.Unwrap()-content.PkgIndex.Unwrap()+1))); err == nil { 19 if flag, _ := c.internalGroupRecall(groupCode, msgInternalId, m); flag { 20 return nil 21 } 22 } 23 } 24 } 25 _, err := c.sendAndWait(c.buildGroupRecallPacket(groupCode, msgID, msgInternalId)) 26 return err 27 } 28 29 func (c *QQClient) internalGroupRecall(groupCode int64, msgInternalID int32, m []*message.GroupMessage) (flag bool, err error) { 30 for _, item := range m { 31 if item.InternalId == msgInternalID { 32 flag = true 33 if _, err := c.sendAndWait(c.buildGroupRecallPacket(groupCode, item.Id, item.InternalId)); err != nil { 34 return false, err 35 } 36 } 37 } 38 return flag, nil 39 } 40 41 func (c *QQClient) RecallPrivateMessage(uin, ts int64, msgID, msgInternalId int32) error { 42 _, err := c.sendAndWait(c.buildPrivateRecallPacket(uin, ts, msgID, msgInternalId)) 43 return err 44 } 45 46 // PbMessageSvc.PbMsgWithDraw 47 func (c *QQClient) buildGroupRecallPacket(groupCode int64, msgSeq, msgRan int32) (uint16, []byte) { 48 req := &msg.MsgWithDrawReq{ 49 GroupWithDraw: []*msg.GroupMsgWithDrawReq{ 50 { 51 SubCmd: proto.Int32(1), 52 GroupCode: proto.Some(groupCode), 53 MsgList: []*msg.GroupMsgInfo{ 54 { 55 MsgSeq: proto.Some(msgSeq), 56 MsgRandom: proto.Some(msgRan), 57 MsgType: proto.Int32(0), 58 }, 59 }, 60 UserDef: []byte{0x08, 0x00}, 61 }, 62 }, 63 } 64 payload, _ := proto.Marshal(req) 65 return c.uniPacket("PbMessageSvc.PbMsgWithDraw", payload) 66 } 67 68 func (c *QQClient) buildPrivateRecallPacket(uin, ts int64, msgSeq, random int32) (uint16, []byte) { 69 req := &msg.MsgWithDrawReq{C2CWithDraw: []*msg.C2CMsgWithDrawReq{ 70 { 71 MsgInfo: []*msg.C2CMsgInfo{ 72 { 73 FromUin: proto.Some(c.Uin), 74 ToUin: proto.Some(uin), 75 MsgTime: proto.Some(ts), 76 MsgUid: proto.Int64(0x0100_0000_0000_0000 | (int64(random) & 0xFFFFFFFF)), 77 MsgSeq: proto.Some(msgSeq), 78 MsgRandom: proto.Some(random), 79 RoutingHead: &msg.RoutingHead{ 80 C2C: &msg.C2C{ 81 ToUin: proto.Some(uin), 82 }, 83 }, 84 }, 85 }, 86 LongMessageFlag: proto.Int32(0), 87 Reserved: []byte{0x08, 0x00}, 88 SubCmd: proto.Int32(1), 89 }, 90 }} 91 payload, _ := proto.Marshal(req) 92 return c.uniPacket("PbMessageSvc.PbMsgWithDraw", payload) 93 } 94 95 func decodeMsgWithDrawResponse(_ *QQClient, pkt *network.Packet) (any, error) { 96 rsp := msg.MsgWithDrawResp{} 97 if err := proto.Unmarshal(pkt.Payload, &rsp); err != nil { 98 return nil, errors.Wrap(err, "failed to unmarshal protobuf message") 99 } 100 if len(rsp.C2CWithDraw) > 0 { 101 if rsp.C2CWithDraw[0].ErrMsg.Unwrap() != "" && rsp.C2CWithDraw[0].ErrMsg.Unwrap() != "Success" { 102 return nil, errors.Errorf("recall error: %v msg: %v", rsp.C2CWithDraw[0].Result.Unwrap(), rsp.C2CWithDraw[0].ErrMsg.Unwrap()) 103 } 104 } 105 if len(rsp.GroupWithDraw) > 0 { 106 if rsp.GroupWithDraw[0].ErrMsg.Unwrap() != "" && rsp.GroupWithDraw[0].ErrMsg.Unwrap() != "Success" { 107 return nil, errors.Errorf("recall error: %v msg: %v", rsp.GroupWithDraw[0].Result.Unwrap(), rsp.GroupWithDraw[0].ErrMsg.Unwrap()) 108 } 109 } 110 return nil, nil 111 }