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  }