UNPKG

@racla-dev/node-iris

Version:

TypeScript port of Python irispy-client module for KakaoTalk bot development

279 lines 11.4 kB
"use strict"; /** * Utility functions for type checking and validation */ Object.defineProperty(exports, "__esModule", { value: true }); exports.isStringMessage = isStringMessage; exports.isFeedMessage = isFeedMessage; exports.isInviteUserFeed = isInviteUserFeed; exports.isLeaveUserFeed = isLeaveUserFeed; exports.isOpenChatJoinUserFeed = isOpenChatJoinUserFeed; exports.isOpenChatKickedUserFeed = isOpenChatKickedUserFeed; exports.isOpenChatPromoteManagerFeed = isOpenChatPromoteManagerFeed; exports.isOpenChatDemoteManagerFeed = isOpenChatDemoteManagerFeed; exports.isDeleteMessageFeed = isDeleteMessageFeed; exports.isOpenChatHandOverHostFeed = isOpenChatHandOverHostFeed; exports.isOpenChatHideMessageFeed = isOpenChatHideMessageFeed; exports.isMentionListAttachment = isMentionListAttachment; exports.isPhotoAttachment = isPhotoAttachment; exports.isMultiPhotoAttachment = isMultiPhotoAttachment; exports.isVideoAttachment = isVideoAttachment; exports.isAudioAttachment = isAudioAttachment; exports.isReplyAttachment = isReplyAttachment; exports.isFileAttachment = isFileAttachment; exports.isNewMultiPhotoAttachment = isNewMultiPhotoAttachment; exports.hasPathProperty = hasPathProperty; exports.getFeedLogMessage = getFeedLogMessage; exports.safeParseMessage = safeParseMessage; const utils_1 = require("@/utils"); const logger_1 = require("@/utils/logger"); const feed_types_1 = require("./feed-types"); // 타입 체크 유틸리티 함수들 function isStringMessage(msg) { return typeof msg === 'string'; } function isFeedMessage(msg) { return typeof msg === 'object' && msg !== null && 'feedType' in msg; } function isInviteUserFeed(msg) { return isFeedMessage(msg) && Number(msg.feedType) === 1; } function isLeaveUserFeed(msg) { return isFeedMessage(msg) && Number(msg.feedType) === 2; } function isOpenChatJoinUserFeed(msg) { return isFeedMessage(msg) && Number(msg.feedType) === 4; } function isOpenChatKickedUserFeed(msg) { return isFeedMessage(msg) && Number(msg.feedType) === 6; } function isOpenChatPromoteManagerFeed(msg) { return isFeedMessage(msg) && Number(msg.feedType) === 11; } function isOpenChatDemoteManagerFeed(msg) { return isFeedMessage(msg) && Number(msg.feedType) === 12; } function isDeleteMessageFeed(msg) { return isFeedMessage(msg) && Number(msg.feedType) === 14; } function isOpenChatHandOverHostFeed(msg) { return isFeedMessage(msg) && Number(msg.feedType) === 15; } function isOpenChatHideMessageFeed(msg) { return isFeedMessage(msg) && Number(msg.feedType) === 26; } // 첨부파일 타입 체크 유틸리티 함수들 function isMentionListAttachment(attachment) { return (attachment !== null && typeof attachment === 'object' && 'mentions' in attachment); } function isPhotoAttachment(attachment) { return (attachment !== null && typeof attachment === 'object' && // 기본 형식 (url, w, h 필수) (('url' in attachment && 'w' in attachment && 'h' in attachment) || // 레거시 호환 형식 (imageUrl만 있는 경우) 'imageUrl' in attachment)); } function isMultiPhotoAttachment(attachment) { return (attachment !== null && typeof attachment === 'object' && 'imageUrls' in attachment); } function isVideoAttachment(attachment) { return (attachment !== null && typeof attachment === 'object' && 'url' in attachment && 'd' in attachment); } function isAudioAttachment(attachment) { return (attachment !== null && typeof attachment === 'object' && 'url' in attachment && 'd' in attachment && 's' in attachment); } function isReplyAttachment(attachment) { return (attachment !== null && typeof attachment === 'object' && 'src_logId' in attachment); } function isFileAttachment(attachment) { return (attachment !== null && typeof attachment === 'object' && 'name' in attachment && 'url' in attachment && 'size' in attachment); } function isNewMultiPhotoAttachment(attachment) { return (attachment !== null && typeof attachment === 'object' && 'C' in attachment); } // 첨부파일에 path 속성이 있는지 확인하는 함수 function hasPathProperty(attachment) { return (attachment !== null && typeof attachment === 'object' && 'path' in attachment); } // 피드 타입별 로그 메시지 생성 함수 function getFeedLogMessage(msg) { if (isStringMessage(msg)) { return msg; } // 타입 가드를 통해 feedType이 있는 객체임을 확인 if (!isFeedMessage(msg)) { return '[Unknown FeedType]'; } try { const feedType = msg.feedType; switch (feedType) { case 1: // 사용자 초대 if (isInviteUserFeed(msg)) { const memberNames = msg.members.map((m) => m.nickName).join(', '); return `${msg.inviter.nickName}님이 ${memberNames}님을 초대했습니다. ()`; } break; case 2: // 사용자 나감 if (isLeaveUserFeed(msg)) { return msg.kicked ? `${msg.member.nickName}님이 내보내기되었습니다. (KICKED)` : `${msg.member.nickName}님이 나가셨습니다. ()`; } break; case 4: // 오픈채팅 입장 if (isOpenChatJoinUserFeed(msg)) { const joinNames = msg.members.map((m) => m.nickName).join(', '); return `${joinNames}님이 입장하셨습니다.`; } break; case 6: // 오픈채팅 강퇴 if (isOpenChatKickedUserFeed(msg)) { return `${msg.member.nickName}님이 내보내기되었습니다. (KICKED)`; } break; case 11: // 매니저 임명 if (isOpenChatPromoteManagerFeed(msg)) { return `${msg.member.nickName}님이 부방장(MANAGER)으로 임명되었습니다. (SYNCMEMT)`; } break; case 12: // 매니저 해제 if (isOpenChatDemoteManagerFeed(msg)) { return `${msg.member.nickName}님의 부방장(MANAGER) 권한이 해제되었습니다. (SYNCMEMT)`; } break; case 14: // 메시지 삭제 if (isDeleteMessageFeed(msg)) { return '메시지를 삭제되었습니다. (SYNCDLMSG)'; } break; case 15: // 호스트 이전 if (isOpenChatHandOverHostFeed(msg)) { return `방장(HOST)이/가 ${msg.prevHost.nickName}님에서 ${msg.newHost.nickName}님으로 변경되었습니다. ()`; } break; case 26: // 메시지 숨김 if (isOpenChatHideMessageFeed(msg)) { return '관리자가 메시지를 숨겨졌습니다. (SYNCREWR)'; } break; default: return `[Unknown FeedType: ${feedType}]`; } return `[Feed Message Processing Error: ${feedType}]`; } catch (error) { return `[Feed Message Parsing Error: ${JSON.stringify(msg)}]`; } } // 메시지 파싱 함수 function safeParseMessage(message) { // 빈 문자열이나 null 체크 if (!message || typeof message !== 'string') { return message || ''; } const logger = new logger_1.Logger('Models: safeParseMessage'); try { // JSON reviver 함수를 사용하여 큰 정수를 문자열로 보존 const parsed = (0, utils_1.safeJsonParseWithReviver)(message); // feedType이 존재하고 숫자인지 확인 (BigInt도 허용) if (parsed && typeof parsed === 'object' && parsed.feedType && (typeof parsed.feedType === 'number' || typeof parsed.feedType === 'bigint')) { // BigInt를 number로 변환 const feedType = typeof parsed.feedType === 'bigint' ? Number(parsed.feedType) : parsed.feedType; // 매핑 테이블에서 지원하는 feedType인지 확인 if (feedType in feed_types_1.FEED_TYPE_MAP) { // feedType을 number로 정규화 const normalizedParsed = { ...parsed, feedType: feedType, }; // 기본적인 구조 검증 const isValid = validateFeedStructure(normalizedParsed, feedType); if (isValid) { return normalizedParsed; } } // 지원하지 않는 feedType이지만 유효한 JSON인 경우 원본 반환 logger.warn(`Unsupported feedType: ${feedType}`); return message; } // feedType이 없는 일반 JSON은 원본 문자열로 반환 return message; } catch (error) { // JSON 파싱 실패 시 원본 문자열 반환 return message; } } // 피드 구조 검증 함수 function validateFeedStructure(parsed, feedType) { try { // userId는 숫자, 문자열, bigint 모두 허용 const isValidUser = (user) => user && (typeof user.userId === 'string' || typeof user.userId === 'number' || typeof user.userId === 'bigint') && typeof user.nickName === 'string'; switch (feedType) { case 1: // InviteUserFeedType return (isValidUser(parsed.inviter) && Array.isArray(parsed.members) && parsed.members.every(isValidUser)); case 2: // LeaveUserFeedType return isValidUser(parsed.member); case 4: // OpenChatJoinUserFeedType return (Array.isArray(parsed.members) && parsed.members.every(isValidUser)); case 6: // OpenChatKickedUserType return isValidUser(parsed.member); case 11: // OpenChatPromoteManagerType case 12: // OpenChatDemoteManagerType return isValidUser(parsed.member); case 14: // DeleteMessageType return (parsed.logId && (typeof parsed.logId === 'string' || typeof parsed.logId === 'number' || typeof parsed.logId === 'bigint') && typeof parsed.hidden === 'boolean'); case 15: // OpenChatHandOverHostType return isValidUser(parsed.newHost) && isValidUser(parsed.prevHost); case 26: // OpenChatHideMessageType return (parsed.logId && (typeof parsed.logId === 'string' || typeof parsed.logId === 'number' || typeof parsed.logId === 'bigint') && typeof parsed.hidden === 'boolean' && Array.isArray(parsed.chatLogInfos)); default: return false; } } catch (error) { return false; } } //# sourceMappingURL=utils.js.map