From f42727c8adf5d7556e2afff00f1db738b73d14a0 Mon Sep 17 00:00:00 2001
From: linyuchen <lin.yu.chen@foxmail.com>
Date: Sat, 16 Mar 2024 11:20:00 +0800
Subject: [PATCH] feat: invite join group event

---
 src/ntqqapi/types.ts                          | 12 ++++-
 src/onebot11/constructor.ts                   | 54 +++++++++----------
 .../event/notice/OB11GroupIncreaseEvent.ts    |  7 +--
 3 files changed, 40 insertions(+), 33 deletions(-)

diff --git a/src/ntqqapi/types.ts b/src/ntqqapi/types.ts
index 743b6df..6618982 100644
--- a/src/ntqqapi/types.ts
+++ b/src/ntqqapi/types.ts
@@ -178,6 +178,7 @@ export interface SendVideoElement {
     elementId: "",
     videoElement: VideoElement
 }
+
 export interface SendArkElement {
     elementType: ElementType.ARK,
     elementId: "",
@@ -243,7 +244,12 @@ export interface PicElement {
     md5HexStr?: string;
 }
 
+export enum GrayTipElementSubType {
+    INVITE_NEW_MEMBER = 12,
+}
+
 export interface GrayTipElement {
+    subElementType: GrayTipElementSubType;
     revokeElement: {
         operatorRole: string;
         operatorUid: string;
@@ -253,7 +259,10 @@ export interface GrayTipElement {
         wording: string;  // 自定义的撤回提示语
     }
     aioOpGrayTipElement: TipAioOpGrayTipElement,
-    groupElement: TipGroupElement
+    groupElement: TipGroupElement,
+    xmlElement: {
+        content: string;
+    }
 }
 
 export interface FaceElement {
@@ -398,6 +407,7 @@ export enum GroupNotifyStatus {
     APPROVE = 2,
     REJECT = 3
 }
+
 export interface GroupNotify {
     time: number;  // 自己添加的字段,时间戳,毫秒, 用于判断收到短时间内收到重复的notify
     seq: string, // 唯一标识符,转成数字再除以1000应该就是时间戳?
diff --git a/src/onebot11/constructor.ts b/src/onebot11/constructor.ts
index 02d3b96..c13cc66 100644
--- a/src/onebot11/constructor.ts
+++ b/src/onebot11/constructor.ts
@@ -11,6 +11,7 @@ import {
 import {
     AtType,
     ChatType,
+    GrayTipElementSubType,
     Group,
     GroupMember,
     IMAGE_HTTP_HOST,
@@ -19,7 +20,7 @@ import {
     TipGroupElementType,
     User
 } from '../ntqqapi/types';
-import {getFriend, getGroup, getGroupMember, selfInfo, tempGroupCodeMap} from '../common/data';
+import {getFriend, getGroupMember, selfInfo, tempGroupCodeMap} from '../common/data';
 import {getConfigUtil, log, sleep} from "../common/utils";
 import {NTQQApi} from "../ntqqapi/ntcall";
 import {EventType} from "./event/OB11BaseEvent";
@@ -206,33 +207,6 @@ export class OB11Constructor {
                 message_data["type"] = OB11MessageDataType.face;
                 message_data["data"]["id"] = element.faceElement.faceIndex.toString();
             }
-            // todo: 解析入群grayTipElement
-            else if (element.grayTipElement?.aioOpGrayTipElement) {
-                log("收到 group gray tip 消息", element.grayTipElement.aioOpGrayTipElement)
-            }
-            // if (message_data.data.file) {
-            //     let filePath: string = message_data.data.file;
-            //     if (!enableLocalFile2Url) {
-            //         message_data.data.file = "file://" + filePath
-            //     } else { // 不使用本地路径
-            //         const ignoreTypes = [OB11MessageDataType.file, OB11MessageDataType.video]
-            //         if (!ignoreTypes.includes(message_data.type)) {
-            //             if (message_data.data.url && !message_data.data.url.startsWith(IMAGE_HTTP_HOST + "/download")) {
-            //                 message_data.data.file = message_data.data.url
-            //             } else {
-            //                 let { err, data } = await file2base64(filePath);
-            //                 if (err) {
-            //                     log("文件转base64失败", filePath, err)
-            //                 } else {
-            //                     message_data.data.file = "base64://" + data
-            //                 }
-            //             }
-            //         } else {
-            //             message_data.data.file = "file://" + filePath
-            //         }
-            //     }
-            // }
-
             if (message_data.type !== "unknown" && message_data.data) {
                 const cqCode = encodeCQCode(message_data);
                 if (messagePostFormat === 'string') {
@@ -251,7 +225,8 @@ export class OB11Constructor {
             return;
         }
         for (let element of msg.elements) {
-            const groupElement = element.grayTipElement?.groupElement
+            const grayTipElement = element.grayTipElement
+            const groupElement = grayTipElement?.groupElement
             if (groupElement) {
                 // log("收到群提示消息", groupElement)
                 if (groupElement.type == TipGroupElementType.memberIncrease) {
@@ -297,6 +272,27 @@ export class OB11Constructor {
             else if (element.fileElement){
                 return new OB11GroupUploadNoticeEvent(parseInt(msg.peerUid), parseInt(msg.senderUin), {id: element.fileElement.fileName, name: element.fileElement.fileName, size: parseInt(element.fileElement.fileSize)})
             }
+
+            if (grayTipElement) {
+                if (grayTipElement.subElementType == GrayTipElementSubType.INVITE_NEW_MEMBER){
+                    log("收到新人被邀请进群消息", grayTipElement)
+                    const xmlElement = grayTipElement.xmlElement
+                    if (xmlElement?.content){
+                        const regex = /jp="(\d+)"/g;
+
+                        let matches = [];
+                        let match = null
+
+                        while ((match = regex.exec(xmlElement.content)) !== null) {
+                            matches.push(match[1]);
+                        }
+                        if (matches.length === 2){
+                            const [inviter, invitee] = matches;
+                            return new OB11GroupIncreaseEvent(parseInt(msg.peerUid), parseInt(invitee), parseInt(inviter), "invite");
+                        }
+                    }
+                }
+            }
         }
     }
 
diff --git a/src/onebot11/event/notice/OB11GroupIncreaseEvent.ts b/src/onebot11/event/notice/OB11GroupIncreaseEvent.ts
index d7e9158..3527820 100644
--- a/src/onebot11/event/notice/OB11GroupIncreaseEvent.ts
+++ b/src/onebot11/event/notice/OB11GroupIncreaseEvent.ts
@@ -1,14 +1,15 @@
 import {OB11GroupNoticeEvent} from "./OB11GroupNoticeEvent";
 
+type GroupIncreaseSubType = "approve" | "invite";
 export class OB11GroupIncreaseEvent extends OB11GroupNoticeEvent {
     notice_type = "group_increase";
-    sub_type = "approve";  // TODO: 实现其他几种子类型的识别 ("approve" | "invite")
     operator_id: number;
-
-    constructor(groupId: number, userId: number, operatorId: number) {
+    sub_type: GroupIncreaseSubType;
+    constructor(groupId: number, userId: number, operatorId: number, subType: GroupIncreaseSubType = "approve") {
         super();
         this.group_id = groupId;
         this.operator_id = operatorId;
         this.user_id = userId;
+        this.sub_type = subType
     }
 }