码桶

发现社区成员的开源项目

早晚圈 / meeting 公开
main
meeting/src/lib/parser.ts
parser.ts2.4 KB
export interface ParsedMeeting {
  meetingId?: string; // 纯数字会议号 (如 739646719)
  dmCode?: string;    // 加密短码 (如 KbRZ4JuHSC4B)
  dedupHash: string;  // 唯一判断 Hash
  topic?: string;     // 会议主题
  rawText: string;
}

export function parseMeetingText(text: string): ParsedMeeting {
  const trimmed = text.trim();

  // 1. 提取短码 dm 链接: https://meeting.tencent.com/dm/KbRZ4JuHSC4B
  const dmMatch = trimmed.match(/meeting\.tencent\.com\/dm\/([a-zA-Z0-9]+)/);
  const dmCode = dmMatch ? dmMatch[1] : undefined;

  // 2. 提取会议主题
  const topicMatch = trimmed.match(/会议主题[::]\s*(.+)/);
  const topic = topicMatch ? topicMatch[1].trim() : undefined;

  // 3. 提取会议号数字 (如 739-646-719 或 739646719 或 739-646-7190)
  // 支持带连字符或无连字符的7-11位数字
  let meetingId: string | undefined = undefined;

  // 先搜带有 "腾讯会议:" 或 "腾讯会议:" 后面的数字
  const taggedMatch = trimmed.match(/(?:#\s*)?腾讯会议[::]?\s*([\d\-\s]+)/);
  if (taggedMatch) {
    const rawNum = taggedMatch[1].replace(/[\-\s]/g, '');
    if (rawNum.length >= 7 && rawNum.length <= 11) {
      meetingId = rawNum;
    }
  }

  // 如果没有搜到带标签的,全局正则搜索 7-11 位符合结构的数字
  if (!meetingId) {
    const numMatches = trimmed.match(/\b\d{3,4}[\-\s]?\d{3,4}[\-\s]?\d{3,4}\b/g);
    if (numMatches && numMatches.length > 0) {
      // 取第一个看起来像会议号的
      const cleaned = numMatches[0].replace(/[\-\s]/g, '');
      if (cleaned.length >= 7 && cleaned.length <= 11) {
        meetingId = cleaned;
      }
    }
  }

  // 如果只有纯数字串输入
  if (!meetingId && /^\d[\d\-\s]{5,12}\d$/.test(trimmed)) {
    const cleaned = trimmed.replace(/[\-\s]/g, '');
    if (cleaned.length >= 7 && cleaned.length <= 11) {
      meetingId = cleaned;
    }
  }

  // 计算 Dedup Hash
  let dedupHash = '';
  if (meetingId) {
    dedupHash = `mid:${meetingId}`;
  } else if (dmCode) {
    dedupHash = `dm:${dmCode}`;
  } else {
    // 兜底直接使用原文本的简单 Hash
    dedupHash = `raw:${simpleHash(trimmed)}`;
  }

  return {
    meetingId,
    dmCode,
    dedupHash,
    topic,
    rawText: trimmed,
  };
}

function simpleHash(str: string): string {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    const char = str.charCodeAt(i);
    hash = (hash << 5) - hash + char;
    hash |= 0;
  }
  return Math.abs(hash).toString(36);
}