@warriorteam/redai-zalo-sdk
Version:
Comprehensive TypeScript/JavaScript SDK for Zalo APIs - Official Account v3.0, ZNS with Full Type Safety, Consultation Service, Broadcast Service, Group Messaging with List APIs, Social APIs, Enhanced Article Management, Promotion Service v3.0 with Multip
1 lines • 942 kB
Source Map (JSON)
{"version":3,"sources":["../src/types/common.ts","../src/types/auth.ts","../src/types/oa.ts","../src/types/user.ts","../src/types/zns.ts","../src/types/article.ts","../src/types/broadcast.ts","../src/types/purchase.ts","../src/constants/zns.constants.ts","../src/types/webhook.ts","../src/utils/type-guards.ts","../src/clients/base-client.ts","../src/clients/zalo-client.ts","../src/services/auth.service.ts","../src/services/oa.service.ts","../src/services/user.service.ts","../src/services/zns.service.ts","../src/services/group-message.service.ts","../src/services/group-management.service.ts","../src/services/article.service.ts","../src/services/video-upload.service.ts","../src/services/consultation.service.ts","../src/services/transaction.service.ts","../src/services/promotion.service.ts","../src/services/general-message.service.ts","../src/services/message-management.service.ts","../src/services/broadcast.service.ts","../src/services/purchase.service.ts","../src/services/anonymous-message.service.ts","../src/services/message-reaction.service.ts","../src/services/miniapp-message.service.ts","../src/zalo-sdk.ts"],"sourcesContent":["/**\r\n * Common types and interfaces for Zalo SDK\r\n */\r\n\r\n/**\r\n * Standard Zalo API response wrapper\r\n */\r\nexport interface ZaloResponse<T = any> {\r\n /**\r\n * Error code (0 = success)\r\n */\r\n error: number;\r\n\r\n /**\r\n * Response message\r\n */\r\n message: string;\r\n\r\n /**\r\n * Response data\r\n */\r\n data?: T;\r\n}\r\n\r\n/**\r\n * Zalo API error response\r\n */\r\nexport interface ZaloErrorResponse {\r\n /**\r\n * Error code\r\n */\r\n error: number;\r\n\r\n /**\r\n * Error name\r\n */\r\n error_name?: string;\r\n\r\n /**\r\n * Error reason\r\n */\r\n error_reason?: string;\r\n\r\n /**\r\n * Error description\r\n */\r\n error_description?: string;\r\n\r\n /**\r\n * Reference documentation link\r\n */\r\n ref_doc?: string;\r\n}\r\n\r\n/**\r\n * Union type for Zalo API responses\r\n */\r\nexport type ZaloApiResponse<T> = ZaloResponse<T> | (ZaloErrorResponse & Partial<T>);\r\n\r\n/**\r\n * SDK Configuration\r\n */\r\nexport interface ZaloSDKConfig {\r\n /**\r\n * Application ID\r\n */\r\n appId: string;\r\n\r\n /**\r\n * Application Secret\r\n */\r\n appSecret: string;\r\n\r\n /**\r\n * API timeout in milliseconds (default: 30000)\r\n */\r\n timeout?: number;\r\n\r\n /**\r\n * Enable debug logging (default: false)\r\n */\r\n debug?: boolean;\r\n\r\n /**\r\n * Custom API base URL (optional)\r\n */\r\n apiBaseUrl?: string;\r\n\r\n /**\r\n * Retry configuration\r\n */\r\n retry?: {\r\n /**\r\n * Number of retry attempts (default: 3)\r\n */\r\n attempts?: number;\r\n\r\n /**\r\n * Delay between retries in milliseconds (default: 1000)\r\n */\r\n delay?: number;\r\n };\r\n}\r\n\r\n/**\r\n * HTTP method types\r\n */\r\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\r\n\r\n/**\r\n * Request configuration\r\n */\r\nexport interface RequestConfig {\r\n /**\r\n * HTTP method\r\n */\r\n method: HttpMethod;\r\n\r\n /**\r\n * Request URL\r\n */\r\n url: string;\r\n\r\n /**\r\n * Request headers\r\n */\r\n headers?: Record<string, string>;\r\n\r\n /**\r\n * Query parameters\r\n */\r\n params?: Record<string, any>;\r\n\r\n /**\r\n * Request body data\r\n */\r\n data?: any;\r\n\r\n /**\r\n * Request timeout\r\n */\r\n timeout?: number;\r\n}\r\n\r\n/**\r\n * Pagination parameters\r\n */\r\nexport interface PaginationParams {\r\n /**\r\n * Offset for pagination\r\n */\r\n offset?: number;\r\n\r\n /**\r\n * Number of items per page\r\n */\r\n count?: number;\r\n\r\n /**\r\n * Maximum items per page (default: 50)\r\n */\r\n limit?: number;\r\n}\r\n\r\n/**\r\n * Paginated response\r\n */\r\nexport interface PaginatedResponse<T> {\r\n /**\r\n * Array of items\r\n */\r\n items: T[];\r\n\r\n /**\r\n * Total number of items\r\n */\r\n total: number;\r\n\r\n /**\r\n * Current offset\r\n */\r\n offset: number;\r\n\r\n /**\r\n * Number of items in current page\r\n */\r\n count: number;\r\n\r\n /**\r\n * Whether there are more items\r\n */\r\n hasMore: boolean;\r\n\r\n /**\r\n * Next offset for pagination\r\n */\r\n nextOffset?: number;\r\n}\r\n\r\n/**\r\n * File upload information\r\n */\r\nexport interface FileUpload {\r\n /**\r\n * File buffer or stream\r\n */\r\n file: Buffer | NodeJS.ReadableStream;\r\n\r\n /**\r\n * Original filename\r\n */\r\n filename: string;\r\n\r\n /**\r\n * MIME type\r\n */\r\n mimetype: string;\r\n\r\n /**\r\n * File size in bytes\r\n */\r\n size?: number;\r\n}\r\n\r\n/**\r\n * Attachment information\r\n */\r\nexport interface Attachment {\r\n /**\r\n * Attachment ID from Zalo\r\n */\r\n attachment_id: string;\r\n\r\n /**\r\n * File URL\r\n */\r\n url: string;\r\n\r\n /**\r\n * File type\r\n */\r\n type?: string;\r\n\r\n /**\r\n * File size in bytes\r\n */\r\n size?: number;\r\n}\r\n\r\n/**\r\n * SDK Error class\r\n */\r\nexport class ZaloSDKError extends Error {\r\n public readonly code: number;\r\n public readonly details?: any;\r\n\r\n constructor(message: string, code: number = -1, details?: any) {\r\n super(message);\r\n this.name = 'ZaloSDKError';\r\n this.code = code;\r\n this.details = details;\r\n }\r\n}\r\n\r\n/**\r\n * Logger interface\r\n */\r\nexport interface Logger {\r\n debug(message: string, ...args: any[]): void;\r\n info(message: string, ...args: any[]): void;\r\n warn(message: string, ...args: any[]): void;\r\n error(message: string, ...args: any[]): void;\r\n}\r\n\r\n/**\r\n * Default console logger implementation\r\n */\r\nexport class ConsoleLogger implements Logger {\r\n constructor(private readonly enableDebug: boolean = false) {}\r\n\r\n debug(message: string, ...args: any[]): void {\r\n if (this.enableDebug) {\r\n console.debug(`[ZALO-SDK:DEBUG] ${message}`, ...args);\r\n }\r\n }\r\n\r\n info(message: string, ...args: any[]): void {\r\n console.info(`[ZALO-SDK:INFO] ${message}`, ...args);\r\n }\r\n\r\n warn(message: string, ...args: any[]): void {\r\n console.warn(`[ZALO-SDK:WARN] ${message}`, ...args);\r\n }\r\n\r\n error(message: string, ...args: any[]): void {\r\n console.error(`[ZALO-SDK:ERROR] ${message}`, ...args);\r\n }\r\n}\r\n","/**\r\n * Authentication related types and interfaces\r\n */\r\n\r\n/**\r\n * Access token information\r\n */\r\nexport interface AccessToken {\r\n /**\r\n * Access token string\r\n */\r\n access_token: string;\r\n\r\n /**\r\n * Token expiration time in seconds\r\n */\r\n expires_in: number;\r\n\r\n /**\r\n * Refresh token (if available)\r\n */\r\n refresh_token?: string;\r\n}\r\n\r\n/**\r\n * Refresh token response\r\n */\r\nexport interface RefreshTokenResponse {\r\n /**\r\n * New access token\r\n */\r\n access_token: string;\r\n\r\n /**\r\n * Token expiration time in seconds\r\n */\r\n expires_in: number;\r\n\r\n /**\r\n * New refresh token (if available)\r\n */\r\n refresh_token?: string;\r\n}\r\n\r\n/**\r\n * OAuth authorization parameters\r\n */\r\nexport interface OAuthParams {\r\n /**\r\n * Application ID\r\n */\r\n app_id: string;\r\n\r\n /**\r\n * Redirect URI\r\n */\r\n redirect_uri: string;\r\n\r\n /**\r\n * OAuth state parameter\r\n */\r\n state?: string;\r\n\r\n /**\r\n * Code verifier for PKCE (Social API)\r\n */\r\n code_verifier?: string;\r\n\r\n /**\r\n * Code challenge for PKCE (Social API)\r\n */\r\n code_challenge?: string;\r\n\r\n /**\r\n * Code challenge method for PKCE (Social API)\r\n */\r\n code_challenge_method?: 'S256' | 'plain';\r\n}\r\n\r\n/**\r\n * Authorization code exchange parameters\r\n */\r\nexport interface AuthCodeParams {\r\n /**\r\n * Application ID\r\n */\r\n app_id: string;\r\n\r\n /**\r\n * Application secret\r\n */\r\n app_secret: string;\r\n\r\n /**\r\n * Authorization code\r\n */\r\n code: string;\r\n\r\n /**\r\n * Redirect URI (must match the one used in authorization)\r\n */\r\n redirect_uri: string;\r\n\r\n /**\r\n * Code verifier for PKCE (supports both Social API and Official Account API)\r\n */\r\n code_verifier?: string;\r\n}\r\n\r\n/**\r\n * Refresh token parameters\r\n */\r\nexport interface RefreshTokenParams {\r\n /**\r\n * Application ID\r\n */\r\n app_id: string;\r\n\r\n /**\r\n * Application secret\r\n */\r\n app_secret: string;\r\n\r\n /**\r\n * Refresh token\r\n */\r\n refresh_token: string;\r\n}\r\n\r\n/**\r\n * Social user information from Zalo\r\n */\r\nexport interface SocialUserInfo {\r\n /**\r\n * User ID\r\n */\r\n id: string;\r\n\r\n /**\r\n * Display name\r\n */\r\n name: string;\r\n\r\n /**\r\n * Profile picture\r\n */\r\n picture?: {\r\n data: {\r\n url: string;\r\n };\r\n };\r\n\r\n /**\r\n * Gender\r\n */\r\n gender?: string;\r\n\r\n /**\r\n * Birthday\r\n */\r\n birthday?: string;\r\n\r\n /**\r\n * Location\r\n */\r\n location?: {\r\n name: string;\r\n };\r\n\r\n /**\r\n * Whether the account is sensitive (under 18)\r\n */\r\n is_sensitive?: boolean;\r\n}\r\n\r\n/**\r\n * Token validation result\r\n */\r\nexport interface TokenValidation {\r\n /**\r\n * Whether the token is valid\r\n */\r\n valid: boolean;\r\n\r\n /**\r\n * Token expiration timestamp\r\n */\r\n expires_at?: number;\r\n\r\n /**\r\n * Associated user information (if available)\r\n */\r\n user_info?: SocialUserInfo;\r\n}\r\n\r\n/**\r\n * Authentication scope for different APIs\r\n */\r\nexport enum AuthScope {\r\n /**\r\n * Official Account API scope\r\n */\r\n OA = 'oa',\r\n\r\n /**\r\n * Social API scope\r\n */\r\n SOCIAL = 'social',\r\n\r\n /**\r\n * ZNS (Zalo Notification Service) scope\r\n */\r\n ZNS = 'zns',\r\n}\r\n\r\n/**\r\n * Authentication method\r\n */\r\nexport enum AuthMethod {\r\n /**\r\n * OAuth 2.0 Authorization Code flow\r\n */\r\n AUTHORIZATION_CODE = 'authorization_code',\r\n\r\n /**\r\n * Refresh token flow\r\n */\r\n REFRESH_TOKEN = 'refresh_token',\r\n}\r\n\r\n/**\r\n * PKCE (Proof Key for Code Exchange) configuration\r\n */\r\nexport interface PKCEConfig {\r\n /**\r\n * Code verifier\r\n */\r\n code_verifier: string;\r\n\r\n /**\r\n * Code challenge\r\n */\r\n code_challenge: string;\r\n\r\n /**\r\n * Code challenge method\r\n */\r\n code_challenge_method: 'S256' | 'plain';\r\n}\r\n\r\n/**\r\n * Authentication URLs\r\n */\r\nexport interface AuthUrls {\r\n /**\r\n * Official Account authorization URL\r\n */\r\n oa_auth_url: string;\r\n\r\n /**\r\n * Social API authorization URL\r\n */\r\n social_auth_url: string;\r\n\r\n /**\r\n * Token exchange URL\r\n */\r\n token_url: string;\r\n\r\n /**\r\n * Token refresh URL\r\n */\r\n refresh_url: string;\r\n}\r\n\r\n/**\r\n * Official Account authorization result\r\n */\r\nexport interface OAAuthResult {\r\n /**\r\n * Authorization URL\r\n */\r\n url: string;\r\n\r\n /**\r\n * State parameter used (auto-generated if not provided)\r\n */\r\n state: string;\r\n\r\n /**\r\n * PKCE configuration used (if PKCE was enabled)\r\n */\r\n pkce?: PKCEConfig;\r\n}\r\n","/**\r\n * Official Account (OA) related types and interfaces\r\n */\r\n\r\n/**\r\n * Official Account information\r\n */\r\nexport interface OAInfo {\r\n /**\r\n * Official Account ID\r\n */\r\n oa_id: string;\r\n\r\n /**\r\n * OA name\r\n */\r\n name: string;\r\n\r\n /**\r\n * OA description\r\n */\r\n description: string;\r\n\r\n /**\r\n * OA alias\r\n */\r\n oa_alias: string;\r\n\r\n /**\r\n * Verification status\r\n */\r\n is_verified: boolean;\r\n\r\n /**\r\n * OA type (number)\r\n */\r\n oa_type: number;\r\n\r\n /**\r\n * Category name\r\n */\r\n cate_name: string;\r\n\r\n /**\r\n * Number of followers\r\n */\r\n num_follower: number;\r\n\r\n /**\r\n * Avatar URL\r\n */\r\n avatar: string;\r\n\r\n /**\r\n * Cover image URL\r\n */\r\n cover: string;\r\n\r\n /**\r\n * Package name\r\n */\r\n package_name: string;\r\n\r\n /**\r\n * Package expiration date\r\n */\r\n package_valid_through_date: string;\r\n\r\n /**\r\n * Package auto-renewal date\r\n */\r\n package_auto_renew_date: string;\r\n\r\n /**\r\n * Linked Zalo Cloud Account\r\n */\r\n linked_ZCA: string;\r\n}\r\n\r\n/**\r\n * Message quota information\r\n */\r\nexport interface MessageQuota {\r\n /**\r\n * Daily quota limit\r\n */\r\n daily_quota: number;\r\n\r\n /**\r\n * Remaining quota for today\r\n */\r\n remaining_quota: number;\r\n\r\n /**\r\n * Quota type (e.g., \"free\", \"paid\")\r\n */\r\n quota_type: string;\r\n\r\n /**\r\n * Quota reset time (Unix timestamp)\r\n */\r\n reset_time: number;\r\n}\r\n\r\n/**\r\n * Detailed quota information request\r\n */\r\nexport interface QuotaMessageRequest {\r\n /**\r\n * Quota owner (OA or APP)\r\n */\r\n quota_owner: string;\r\n\r\n /**\r\n * Product type\r\n */\r\n product_type?: 'cs' | 'transaction' | 'gmf10' | 'gmf50' | 'gmf100';\r\n\r\n /**\r\n * Quota type\r\n */\r\n quota_type?: 'sub_quota' | 'purchase_quota' | 'reward_quota';\r\n}\r\n\r\n/**\r\n * Quota asset information\r\n */\r\nexport interface QuotaAsset {\r\n /**\r\n * Asset ID\r\n */\r\n asset_id: string;\r\n\r\n /**\r\n * Product type\r\n */\r\n product_type: string;\r\n\r\n /**\r\n * Quota type\r\n */\r\n quota_type: string;\r\n\r\n /**\r\n * Expiration date\r\n */\r\n valid_through: string;\r\n\r\n /**\r\n * Auto-renewal status\r\n */\r\n auto_renew: boolean;\r\n\r\n /**\r\n * Asset status\r\n */\r\n status: 'available' | 'used';\r\n\r\n /**\r\n * Used ID (for GMF, this is group_id)\r\n */\r\n used_id: string | null;\r\n\r\n /**\r\n * Total quota (legacy)\r\n */\r\n total?: number;\r\n\r\n /**\r\n * Remaining quota (legacy)\r\n */\r\n remain?: number;\r\n}\r\n\r\n/**\r\n * Quota message response\r\n */\r\nexport interface QuotaMessageResponse {\r\n /**\r\n * List of quota assets\r\n */\r\n data: QuotaAsset[];\r\n\r\n /**\r\n * Error code\r\n */\r\n error: number;\r\n\r\n /**\r\n * Response message\r\n */\r\n message: string;\r\n}\r\n\r\n/**\r\n * GMF product types\r\n */\r\nexport enum GMFProductType {\r\n GMF10 = 'gmf10',\r\n GMF50 = 'gmf50',\r\n GMF100 = 'gmf100',\r\n}\r\n\r\n/**\r\n * Quota types\r\n */\r\nexport enum QuotaType {\r\n SUB_QUOTA = 'sub_quota',\r\n PURCHASE_QUOTA = 'purchase_quota',\r\n REWARD_QUOTA = 'reward_quota',\r\n}\r\n\r\n/**\r\n * OA settings\r\n */\r\nexport interface OASettings {\r\n /**\r\n * Auto-reply settings\r\n */\r\n auto_reply?: {\r\n enabled: boolean;\r\n message?: string;\r\n };\r\n\r\n /**\r\n * Welcome message settings\r\n */\r\n welcome_message?: {\r\n enabled: boolean;\r\n message?: string;\r\n };\r\n\r\n /**\r\n * Business hours\r\n */\r\n business_hours?: {\r\n enabled: boolean;\r\n schedule?: Array<{\r\n day: number; // 0-6 (Sunday-Saturday)\r\n start_time: string; // HH:mm format\r\n end_time: string; // HH:mm format\r\n }>;\r\n };\r\n}\r\n\r\n/**\r\n * OA statistics\r\n */\r\nexport interface OAStatistics {\r\n /**\r\n * Total followers\r\n */\r\n total_followers: number;\r\n\r\n /**\r\n * New followers today\r\n */\r\n new_followers_today: number;\r\n\r\n /**\r\n * Messages sent today\r\n */\r\n messages_sent_today: number;\r\n\r\n /**\r\n * Messages received today\r\n */\r\n messages_received_today: number;\r\n\r\n /**\r\n * Engagement rate\r\n */\r\n engagement_rate?: number;\r\n}\r\n\r\n/**\r\n * OA profile update request\r\n */\r\nexport interface UpdateOAProfileRequest {\r\n /**\r\n * OA name\r\n */\r\n name?: string;\r\n\r\n /**\r\n * OA description\r\n */\r\n description?: string;\r\n\r\n /**\r\n * Avatar image (base64 or URL)\r\n */\r\n avatar?: string;\r\n\r\n /**\r\n * Cover image (base64 or URL)\r\n */\r\n cover?: string;\r\n}\r\n\r\n/**\r\n * OA verification request\r\n */\r\nexport interface OAVerificationRequest {\r\n /**\r\n * Business license number\r\n */\r\n business_license: string;\r\n\r\n /**\r\n * Business name\r\n */\r\n business_name: string;\r\n\r\n /**\r\n * Contact person name\r\n */\r\n contact_name: string;\r\n\r\n /**\r\n * Contact phone number\r\n */\r\n contact_phone: string;\r\n\r\n /**\r\n * Contact email\r\n */\r\n contact_email: string;\r\n\r\n /**\r\n * Additional documents\r\n */\r\n documents?: Array<{\r\n type: string;\r\n url: string;\r\n }>;\r\n}\r\n","/**\r\n * User management related types and interfaces\r\n */\r\n\r\n/**\r\n * User information from Zalo API v3.0\r\n */\r\nexport interface UserInfo {\r\n /**\r\n * User ID\r\n */\r\n user_id: string;\r\n\r\n /**\r\n * User ID by app\r\n */\r\n user_id_by_app: string;\r\n\r\n /**\r\n * External user ID in business system\r\n */\r\n user_external_id: string;\r\n\r\n /**\r\n * Display name\r\n */\r\n display_name: string;\r\n\r\n /**\r\n * User alias\r\n */\r\n user_alias: string;\r\n\r\n /**\r\n * Whether user is under 18\r\n */\r\n is_sensitive: boolean;\r\n\r\n /**\r\n * Last interaction date (dd/MM/yyyy)\r\n */\r\n user_last_interaction_date: string;\r\n\r\n /**\r\n * Whether user is following OA\r\n */\r\n user_is_follower: boolean;\r\n\r\n /**\r\n * Avatar URL\r\n */\r\n avatar: string;\r\n\r\n /**\r\n * Avatar URLs with different sizes\r\n */\r\n avatars: {\r\n \"120\": string;\r\n \"240\": string;\r\n };\r\n\r\n /**\r\n * Dynamic param from last access\r\n */\r\n dynamic_param?: string;\r\n\r\n /**\r\n * Tags and notes information\r\n */\r\n tags_and_notes_info: {\r\n notes: string[];\r\n tag_names: string[];\r\n };\r\n\r\n /**\r\n * Shared information from user\r\n */\r\n shared_info?: {\r\n address?: string;\r\n city?: string;\r\n district?: string;\r\n phone?: string;\r\n name?: string;\r\n user_dob?: string;\r\n };\r\n}\r\n\r\n/**\r\n * User list request parameters\r\n */\r\nexport interface UserListRequest {\r\n /**\r\n * Offset for pagination\r\n */\r\n offset: number;\r\n\r\n /**\r\n * Number of users to fetch (max 50)\r\n */\r\n count: number;\r\n\r\n /**\r\n * Filter by tag name\r\n */\r\n tag_name?: string;\r\n\r\n /**\r\n * Filter by last interaction period\r\n */\r\n last_interaction_period?: \"TODAY\" | \"YESTERDAY\" | \"L7D\" | \"L30D\" | string;\r\n\r\n /**\r\n * Filter by follower status\r\n */\r\n is_follower?: boolean;\r\n}\r\n\r\n/**\r\n * User list response\r\n */\r\nexport interface UserListResponse {\r\n /**\r\n * Total number of users\r\n */\r\n total: number;\r\n\r\n /**\r\n * Number of users returned\r\n */\r\n count: number;\r\n\r\n /**\r\n * Current offset\r\n */\r\n offset: number;\r\n\r\n /**\r\n * List of user IDs\r\n */\r\n users: Array<{\r\n user_id: string;\r\n }>;\r\n}\r\n\r\n/**\r\n * User label/tag information\r\n */\r\nexport interface UserLabel {\r\n /**\r\n * Label ID\r\n */\r\n label_id: string;\r\n\r\n /**\r\n * Label name\r\n */\r\n label_name: string;\r\n\r\n /**\r\n * Label description\r\n */\r\n description?: string;\r\n\r\n /**\r\n * Label color (hex)\r\n */\r\n color?: string;\r\n\r\n /**\r\n * Creation time (Unix timestamp)\r\n */\r\n created_time?: number;\r\n\r\n /**\r\n * Number of users with this label\r\n */\r\n user_count?: number;\r\n}\r\n\r\n/**\r\n * Create label request\r\n */\r\nexport interface CreateLabelRequest {\r\n /**\r\n * Label name\r\n */\r\n label_name: string;\r\n\r\n /**\r\n * Label description\r\n */\r\n description?: string;\r\n\r\n /**\r\n * Label color (hex)\r\n */\r\n color?: string;\r\n}\r\n\r\n/**\r\n * User label operation request (legacy - for label_id based operations)\r\n */\r\nexport interface UserLabelRequest {\r\n /**\r\n * User ID\r\n */\r\n user_id: string;\r\n\r\n /**\r\n * Label ID\r\n */\r\n label_id: string;\r\n}\r\n\r\n/**\r\n * Tag user request - for Zalo API v2.0/oa/tag/tagfollower\r\n */\r\nexport interface TagUserRequest {\r\n /**\r\n * User ID (long in API spec, but sent as string)\r\n */\r\n user_id: string;\r\n\r\n /**\r\n * Tag name to assign to user\r\n * Note: If tag doesn't exist, API will create it automatically\r\n */\r\n tag_name: string;\r\n}\r\n\r\n/**\r\n * Remove tag from user request - for Zalo API v2.0/oa/tag/rmfollowerfromtag\r\n */\r\nexport interface RemoveTagFromUserRequest {\r\n /**\r\n * User ID\r\n */\r\n user_id: string;\r\n\r\n /**\r\n * Tag name to remove from user\r\n */\r\n tag_name: string;\r\n}\r\n\r\n/**\r\n * Get tags list response - for Zalo API v2.0/oa/tag/gettagsofoa\r\n */\r\nexport interface GetTagsResponse {\r\n /**\r\n * Error code (0 = success)\r\n */\r\n error: number;\r\n\r\n /**\r\n * Response message\r\n */\r\n message: string;\r\n\r\n /**\r\n * Array of tag names\r\n */\r\n data: string[];\r\n}\r\n\r\n/**\r\n * Delete tag request - for Zalo API v2.0/oa/tag/rmtag\r\n */\r\nexport interface DeleteTagRequest {\r\n /**\r\n * Tag name to delete\r\n */\r\n tag_name: string;\r\n}\r\n\r\n/**\r\n * Update user request - for Zalo API v3.0/oa/user/update\r\n */\r\nexport interface UpdateUserRequest {\r\n /**\r\n * User ID (required)\r\n */\r\n user_id: string;\r\n\r\n /**\r\n * Shared information to update\r\n */\r\n shared_info?: {\r\n /**\r\n * Display name\r\n */\r\n name?: string;\r\n\r\n /**\r\n * Phone number\r\n */\r\n phone?: string;\r\n\r\n /**\r\n * Address\r\n */\r\n address?: string;\r\n\r\n /**\r\n * City ID (see Zalo documentation for city codes)\r\n */\r\n city_id?: number;\r\n\r\n /**\r\n * District ID (see Zalo documentation for district codes)\r\n */\r\n district_id?: number;\r\n\r\n /**\r\n * Date of birth (dd/MM/yyyy format, from 1/1/1970)\r\n */\r\n user_dob?: string;\r\n };\r\n\r\n /**\r\n * User alias name\r\n */\r\n user_alias?: string;\r\n\r\n /**\r\n * External user ID in business system (unique per customer)\r\n */\r\n user_external_id?: string;\r\n}\r\n\r\n/**\r\n * Delete user info request - for Zalo API v2.0/oa/deletefollowerinfo\r\n */\r\nexport interface DeleteUserInfoRequest {\r\n /**\r\n * User ID to delete info for\r\n */\r\n user_id: string;\r\n}\r\n\r\n/**\r\n * Get user custom info request - for Zalo API v3.0/oa/user/detail/custominfo\r\n */\r\nexport interface GetUserCustomInfoRequest {\r\n /**\r\n * User ID to get custom info for\r\n */\r\n user_id: string;\r\n\r\n /**\r\n * List of custom fields to export (optional)\r\n * If not specified, API returns all available custom info\r\n * For table type fields, only parent field is accepted\r\n */\r\n fields_to_export?: string[];\r\n}\r\n\r\n/**\r\n * User custom info response - for Zalo API v3.0/oa/user/detail/custominfo\r\n */\r\nexport interface UserCustomInfoResponse {\r\n /**\r\n * Error code (0 = success)\r\n */\r\n error: number;\r\n\r\n /**\r\n * Response message\r\n */\r\n message: string;\r\n\r\n /**\r\n * Custom info data\r\n */\r\n data: {\r\n /**\r\n * User ID\r\n */\r\n user_id: string;\r\n\r\n /**\r\n * Custom information fields\r\n * All values are returned as strings for consistency\r\n */\r\n custom_info: Record<string, any>;\r\n };\r\n}\r\n\r\n/**\r\n * Update user custom info request - for Zalo API v3.0/oa/user/update/custominfo\r\n */\r\nexport interface UpdateUserCustomInfoRequest {\r\n /**\r\n * User ID to update custom info for\r\n */\r\n user_id: string;\r\n\r\n /**\r\n * Custom information to update\r\n * Structure depends on OA's custom field configuration\r\n */\r\n custom_info: Record<string, any>;\r\n}\r\n\r\n/**\r\n * User custom information\r\n */\r\nexport interface UserCustomInfo {\r\n /**\r\n * User ID\r\n */\r\n user_id: string;\r\n\r\n /**\r\n * Custom fields (key-value pairs)\r\n */\r\n custom_fields: Record<string, any>;\r\n\r\n /**\r\n * Last updated timestamp\r\n */\r\n last_updated?: number;\r\n}\r\n\r\n/**\r\n * Update custom info request\r\n */\r\nexport interface UpdateCustomInfoRequest {\r\n /**\r\n * User ID\r\n */\r\n user_id: string;\r\n\r\n /**\r\n * Custom fields to update\r\n */\r\n custom_fields: Record<string, any>;\r\n}\r\n\r\n/**\r\n * User info field types\r\n */\r\nexport enum UserInfoFieldType {\r\n TEXT = \"text\",\r\n NUMBER = \"number\",\r\n DATE = \"date\",\r\n SELECT = \"select\",\r\n}\r\n\r\n/**\r\n * Field option for select type\r\n */\r\nexport interface FieldOption {\r\n /**\r\n * Option value\r\n */\r\n value: string;\r\n\r\n /**\r\n * Option label\r\n */\r\n label: string;\r\n}\r\n\r\n/**\r\n * User info field definition\r\n */\r\nexport interface UserInfoField {\r\n /**\r\n * Field ID\r\n */\r\n field_id: string;\r\n\r\n /**\r\n * Field name\r\n */\r\n field_name: string;\r\n\r\n /**\r\n * Field type\r\n */\r\n field_type: UserInfoFieldType;\r\n\r\n /**\r\n * Field description\r\n */\r\n description?: string;\r\n\r\n /**\r\n * Whether field is required\r\n */\r\n required?: boolean;\r\n\r\n /**\r\n * Options for select type\r\n */\r\n options?: FieldOption[];\r\n\r\n /**\r\n * Default value\r\n */\r\n default_value?: string;\r\n\r\n /**\r\n * Display order\r\n */\r\n display_order?: number;\r\n\r\n /**\r\n * Whether it's a system field\r\n */\r\n is_system_field?: boolean;\r\n\r\n /**\r\n * Creation time\r\n */\r\n created_time?: number;\r\n\r\n /**\r\n * Last update time\r\n */\r\n updated_time?: number;\r\n}\r\n\r\n/**\r\n * Create user info field request\r\n */\r\nexport interface CreateUserInfoFieldRequest {\r\n /**\r\n * Field name\r\n */\r\n field_name: string;\r\n\r\n /**\r\n * Field type\r\n */\r\n field_type: UserInfoFieldType;\r\n\r\n /**\r\n * Field description\r\n */\r\n description?: string;\r\n\r\n /**\r\n * Whether field is required\r\n */\r\n required?: boolean;\r\n\r\n /**\r\n * Options for select type\r\n */\r\n options?: FieldOption[];\r\n\r\n /**\r\n * Default value\r\n */\r\n default_value?: string;\r\n\r\n /**\r\n * Display order\r\n */\r\n display_order?: number;\r\n}\r\n\r\n/**\r\n * Update user info field request\r\n */\r\nexport interface UpdateUserInfoFieldRequest {\r\n /**\r\n * Field name\r\n */\r\n field_name?: string;\r\n\r\n /**\r\n * Field description\r\n */\r\n description?: string;\r\n\r\n /**\r\n * Whether field is required\r\n */\r\n required?: boolean;\r\n\r\n /**\r\n * Options for select type\r\n */\r\n options?: FieldOption[];\r\n\r\n /**\r\n * Default value\r\n */\r\n default_value?: string;\r\n\r\n /**\r\n * Display order\r\n */\r\n display_order?: number;\r\n}\r\n\r\n/**\r\n * Advanced filter options for getAllUsersWithAdvancedFilters\r\n * Dựa trên các trường trong UserInfo\r\n */\r\nexport interface AdvancedUserFilters {\r\n /**\r\n * Filter by specific user IDs (exact match)\r\n * Chỉ lấy những users có ID trong danh sách này\r\n */\r\n userIds?: string[];\r\n\r\n /**\r\n * Filter by tag name (existing from basic filters)\r\n */\r\n tag_name?: string;\r\n\r\n /**\r\n * Filter by last interaction period (existing from basic filters)\r\n */\r\n last_interaction_period?: \"TODAY\" | \"YESTERDAY\" | \"L7D\" | \"L30D\" | string;\r\n\r\n /**\r\n * Filter by follower status (existing from basic filters)\r\n */\r\n is_follower?: boolean;\r\n\r\n /**\r\n * Filter by display name (contains search)\r\n */\r\n display_name_contains?: string;\r\n\r\n /**\r\n * Filter by user alias (contains search)\r\n */\r\n user_alias_contains?: string;\r\n\r\n /**\r\n * Filter by whether user is sensitive (under 18)\r\n */\r\n is_sensitive?: boolean;\r\n\r\n /**\r\n * Filter by specific interaction date range\r\n */\r\n last_interaction_date_range?: {\r\n from: string; // dd/MM/yyyy format\r\n to: string; // dd/MM/yyyy format\r\n };\r\n\r\n /**\r\n * Filter by specific tags (multiple tags - OR operation)\r\n */\r\n tag_names?: string[];\r\n\r\n /**\r\n * Filter by tags (ALL tags must match - AND operation)\r\n */\r\n require_all_tags?: string[];\r\n\r\n /**\r\n * Filter by notes content (contains search)\r\n */\r\n notes_contains?: string;\r\n\r\n /**\r\n * Filter by shared info - city\r\n */\r\n city?: string;\r\n\r\n /**\r\n * Filter by shared info - district\r\n */\r\n district?: string;\r\n\r\n /**\r\n * Filter by shared info - phone (contains search)\r\n */\r\n phone_contains?: string;\r\n\r\n /**\r\n * Filter by shared info - name (contains search)\r\n */\r\n name_contains?: string;\r\n\r\n /**\r\n * Filter by shared info - address (contains search)\r\n */\r\n address_contains?: string;\r\n\r\n /**\r\n * Filter by date of birth range\r\n */\r\n dob_range?: {\r\n from: string; // dd/MM/yyyy format\r\n to: string; // dd/MM/yyyy format\r\n };\r\n\r\n /**\r\n * Filter by age range (calculated from dob)\r\n */\r\n age_range?: {\r\n min: number;\r\n max: number;\r\n };\r\n\r\n /**\r\n * Filter by external user ID (contains search)\r\n */\r\n external_id_contains?: string;\r\n\r\n /**\r\n * Exclude users with specific tags\r\n */\r\n exclude_tags?: string[];\r\n\r\n /**\r\n * Filter by users who have shared info vs those who don't\r\n */\r\n has_shared_info?: boolean;\r\n\r\n /**\r\n * Filter by users who have phone number\r\n */\r\n has_phone?: boolean;\r\n\r\n /**\r\n * Filter by users who have address\r\n */\r\n has_address?: boolean;\r\n}\r\n","/**\r\n * ZNS (Zalo Notification Service) Type Definitions\r\n */\r\n\r\n// ZNS Template Types\r\nexport enum ZNSTemplateType {\r\n /** ZNS tùy chỉnh */\r\n CUSTOM = 1,\r\n /** ZNS xác thực */\r\n AUTHENTICATION = 2,\r\n /** ZNS yêu cầu thanh toán */\r\n PAYMENT_REQUEST = 3,\r\n /** ZNS voucher */\r\n VOUCHER = 4,\r\n /** ZNS Đánh giá dịch vụ */\r\n SERVICE_RATING = 5\r\n}\r\n\r\n// ZNS Template Tags\r\nexport enum ZNSTemplateTag {\r\n /** Transaction */\r\n TRANSACTION = \"1\",\r\n /** Customer care */\r\n CUSTOMER_CARE = \"2\",\r\n /** Promotion */\r\n PROMOTION = \"3\"\r\n}\r\n\r\n// ZNS Button Types\r\n// ZNS Button Types\r\nexport enum ZNSButtonType {\r\n /** Trang doanh nghiệp */\r\n ENTERPRISE_PAGE = 1,\r\n /** Gọi điện */\r\n PHONE = 2,\r\n /** Trang OA */\r\n OA_PAGE = 3,\r\n /** Zalo Mini App */\r\n ZALO_MINI_APP = 4,\r\n /** Tải App */\r\n DOWNLOAD_APP = 5,\r\n /** Phân phối sản phẩm */\r\n PRODUCT_DISTRIBUTION = 6,\r\n /** Web/Zalo Mini App khác */\r\n OTHER_WEB_APP = 7,\r\n /** App khác */\r\n OTHER_APP = 8,\r\n /** Bài viết OA */\r\n OA_ARTICLE = 9,\r\n /** Sao chép */\r\n COPY = 10,\r\n /** Thanh toán ngay */\r\n PAY_NOW = 11,\r\n /** Xem chi tiết */\r\n VIEW_DETAILS = 12,\r\n}\r\n\r\n// ZNS Parameter Types\r\nexport enum ZNSParamType {\r\n /** Tên khách hàng (30) */\r\n CUSTOMER_NAME = \"1\",\r\n /** Số điện thoại (15) */\r\n PHONE_NUMBER = \"2\",\r\n /** Địa chỉ (200) */\r\n ADDRESS = \"3\",\r\n /** Mã số (30) */\r\n CODE = \"4\",\r\n /** Nhãn tùy chỉnh (30) */\r\n CUSTOM_LABEL = \"5\",\r\n /** Trạng thái giao dịch (30) */\r\n TRANSACTION_STATUS = \"6\",\r\n /** Thông tin liên hệ (50) */\r\n CONTACT_INFO = \"7\",\r\n /** Giới tính / Danh xưng (5) */\r\n GENDER_TITLE = \"8\",\r\n /** Tên sản phẩm / Thương hiệu (200) */\r\n PRODUCT_BRAND = \"9\",\r\n /** Số lượng / Số tiền (20) */\r\n QUANTITY_AMOUNT = \"10\",\r\n /** Thời gian (20) */\r\n TIME = \"11\",\r\n /** OTP (10) */\r\n OTP = \"12\",\r\n /** URL (200) */\r\n URL = \"13\",\r\n /** Tiền tệ (VNĐ) (12) */\r\n CURRENCY = \"14\",\r\n /** Bank transfer note (90) */\r\n BANK_TRANSFER_NOTE = \"15\"\r\n}\r\n\r\nexport interface ZNSMessage {\r\n phone: string;\r\n template_id: string;\r\n template_data: Record<string, any>;\r\n tracking_id?: string;\r\n}\r\n\r\nexport interface ZNSHashPhoneMessage {\r\n phone_hash: string;\r\n template_id: string;\r\n template_data: Record<string, any>;\r\n tracking_id?: string;\r\n}\r\n\r\nexport interface ZNSDevModeMessage {\r\n phone: string;\r\n template_id: string;\r\n template_data: Record<string, any>;\r\n tracking_id?: string;\r\n mode: \"development\";\r\n}\r\n\r\nexport interface ZNSRsaMessage {\r\n phone_rsa: string;\r\n template_id: string;\r\n template_data: Record<string, any>;\r\n tracking_id?: string;\r\n}\r\n\r\nexport interface ZNSJourneyMessage {\r\n phone: string;\r\n template_id: string;\r\n template_data: Record<string, any>;\r\n tracking_id?: string;\r\n journey_id: string;\r\n}\r\n\r\n/**\r\n * ZBS/ZNS Template Message by UID\r\n * API: POST https://openapi.zalo.me/v3.0/oa/message/template\r\n * Send template message using user_id instead of phone number\r\n */\r\nexport interface ZNSUidMessage {\r\n /** ID của người nhận - Định danh người dùng theo OA */\r\n user_id: string;\r\n /** ID của template muốn sử dụng */\r\n template_id: string;\r\n /** Các thuộc tính của template mà đối tác đã đăng ký với Zalo */\r\n template_data: Record<string, any>;\r\n}\r\n\r\n/**\r\n * Response from sending ZBS/ZNS template message by UID\r\n */\r\nexport interface ZNSUidSendResult {\r\n error: number;\r\n message: string;\r\n data?: {\r\n /** ID của tin nhắn */\r\n message_id: string;\r\n /** ID của người dùng */\r\n user_id: string;\r\n };\r\n /** Thời gian gửi tin (timestamp) */\r\n sent_time?: string;\r\n}\r\n\r\nexport interface ZNSSendResult {\r\n error: number;\r\n message: string;\r\n data?: {\r\n msg_id: string;\r\n sent_time: string;\r\n quota?: {\r\n remainingQuota: number;\r\n dailyQuota: number;\r\n };\r\n };\r\n}\r\n\r\nexport interface ZNSTemplate {\r\n templateId: string;\r\n templateName: string;\r\n status: \"PENDING_REVIEW\" | \"ENABLE\" | \"REJECT\" | \"DISABLE\";\r\n listParams: Array<{\r\n name: string;\r\n require: boolean;\r\n type: \"STRING\" | \"NUMBER\" | \"DATE\";\r\n maxLength?: number;\r\n minLength?: number;\r\n }>;\r\n timeout?: number;\r\n previewUrl?: string;\r\n templateQuality?: \"HIGH\" | \"MEDIUM\" | \"LOW\";\r\n templateTag?: string;\r\n price?: number;\r\n applyTemplateQuota?: boolean;\r\n templateDailyQuota?: number;\r\n templateRemainingQuota?: number;\r\n}\r\n\r\nexport interface ZNSTemplateDetails {\r\n error: number;\r\n message: string;\r\n data: {\r\n templateId: string; // ID của template\r\n templateName: string; // Tên của template\r\n status: \"ENABLE\" | \"PENDING_REVIEW\" | \"DELETE\" | \"REJECT\" | \"DISABLE\"; // Trạng thái template\r\n reason?: string; // Lý do template có trạng thái hiện tại\r\n listParams: Array<{\r\n name: string; // Tên thuộc tính\r\n require: boolean; // Tính bắt buộc của thuộc tính\r\n type: string; // Định dạng validate của thuộc tính\r\n maxLength: number; // Số ký tự tối đa\r\n minLength: number; // Số ký tự tối thiểu\r\n acceptNull: boolean; // Thuộc tính có thể nhận giá trị rỗng hay không\r\n }>;\r\n listButtons: Array<{\r\n type: number; // Button type (1-12)\r\n title: string; // Nội dung Button\r\n content: string; // Đường dẫn liên kết/số điện thoại\r\n }>;\r\n timeout: number; // Thời gian timeout của template\r\n previewUrl: string; // Đường dẫn đến bản xem trước của template\r\n templateQuality: string; // Chất lượng template (null từ 10/12)\r\n templateTag: \"TRANSACTION\" | \"CUSTOMER_CARE\" | \"PROMOTION\"; // Loại nội dung template\r\n price_sdt: string; // Đơn giá gửi tin qua SĐT\r\n price_uid: string; // Đơn giá gửi tin qua UID\r\n price: string; // [DEPRECATED] Đơn giá gửi tin qua SĐT (sử dụng price_sdt thay thế)\r\n };\r\n}\r\n\r\nexport interface ZNSTemplateList {\r\n error: number;\r\n message: string;\r\n data: Array<{\r\n templateId: string; // ID của template\r\n templateName: string; // Tên của template\r\n createdTime: number; // Thời gian tạo template\r\n status: \"PENDING_REVIEW\" | \"DISABLE\" | \"ENABLE\" | \"REJECT\"; // Trạng thái template\r\n templateQuality: \"HIGH\" | \"MEDIUM\" | \"LOW\" | \"UNDEFINED\"; // Chất lượng gửi tin\r\n }>;\r\n metadata: {\r\n total: number; // Tổng số lượng template\r\n };\r\n}\r\n\r\n/**\r\n * ZNS Template Create Request - theo chuẩn Zalo API\r\n * API: POST https://business.openapi.zalo.me/template/create\r\n */\r\nexport interface ZNSCreateTemplateRequest {\r\n /** Tên mẫu tin (10-60 ký tự) */\r\n template_name: string;\r\n\r\n /** Loại mẫu tin */\r\n template_type: 1 | 2 | 3 | 4 | 5; // 1: ZNS tùy chỉnh, 2: ZNS xác thực, 3: ZNS yêu cầu thanh toán, 4: ZNS voucher, 5: ZNS Đánh giá dịch vụ\r\n\r\n /** Tag mẫu tin */\r\n tag: \"1\" | \"2\" | \"3\"; // 1: Transaction, 2: Customer care, 3: Promotion\r\n\r\n /** Layout của template */\r\n layout: ZNSTemplateLayout;\r\n\r\n /** Thông tin về param (optional) */\r\n params?: ZNSTemplateParam[];\r\n\r\n /** Ghi chú kiểm duyệt (1-400 ký tự, optional) */\r\n note?: string;\r\n\r\n /** Mã tracking do đối tác tự định nghĩa */\r\n tracking_id: string;\r\n}\r\n\r\n/**\r\n * ZNS Template Edit Request - theo chuẩn Zalo API\r\n * API: POST https://business.openapi.zalo.me/template/edit\r\n * Chỉ có thể chỉnh sửa template có trạng thái REJECT\r\n */\r\nexport interface ZNSUpdateTemplateRequest {\r\n /** Template ID được hệ thống tự tạo */\r\n template_id: string;\r\n\r\n /** Tên mẫu tin (10-60 ký tự) */\r\n template_name: string;\r\n\r\n /** Loại mẫu tin */\r\n template_type: 1 | 2 | 3 | 4 | 5; // 1: ZNS tùy chỉnh, 2: ZNS xác thực, 3: ZNS yêu cầu thanh toán, 4: ZNS voucher, 5: ZNS Đánh giá dịch vụ\r\n\r\n /** Tag mẫu tin */\r\n tag: \"1\" | \"2\" | \"3\"; // 1: Transaction, 2: Customer care, 3: Promotion\r\n\r\n /** Layout của template */\r\n layout: ZNSTemplateLayout;\r\n\r\n /** Thông tin về param (optional) */\r\n params?: ZNSTemplateParam[];\r\n\r\n /** Ghi chú kiểm duyệt (1-400 ký tự, optional) */\r\n note?: string;\r\n\r\n /** Mã tracking do đối tác tự định nghĩa */\r\n tracking_id: string;\r\n}\r\n\r\n/**\r\n * Layout của ZNS Template\r\n */\r\nexport interface ZNSTemplateLayout {\r\n /** Header components (optional) */\r\n header?: {\r\n components: ZNSValidationComponent[];\r\n };\r\n\r\n /** Body components (required) */\r\n body: {\r\n components: ZNSValidationComponent[];\r\n };\r\n\r\n /** Footer components (optional) */\r\n footer?: {\r\n components: ZNSValidationComponent[];\r\n };\r\n}\r\n\r\n\r\n\r\n/**\r\n * Template parameter theo chuẩn Zalo API\r\n */\r\nexport interface ZNSTemplateParam {\r\n /** Loại param */\r\n type: \"1\" | \"2\" | \"3\" | \"4\" | \"5\" | \"6\" | \"7\" | \"8\" | \"9\" | \"10\" | \"11\" | \"12\" | \"13\" | \"14\" | \"15\"; // Xem danh sách param type trong docs\r\n\r\n /** Tên của param */\r\n name: string;\r\n\r\n /** Dữ liệu mẫu của param */\r\n sample_value: string;\r\n}\r\n\r\n/**\r\n * Response từ API create/edit template\r\n */\r\nexport interface ZNSTemplateCreateEditResponse {\r\n error: number;\r\n message: string;\r\n data: {\r\n /** Template ID */\r\n template_id: string;\r\n /** Tên template */\r\n template_name: string;\r\n /** Loại template */\r\n template_type: number;\r\n /** Trạng thái template sau khi submit */\r\n status: \"PENDING_REVIEW\";\r\n /** Template tag */\r\n tag: number;\r\n /** App ID của template */\r\n app_id: string;\r\n /** OA ID của template */\r\n oa_id: string;\r\n /** Đơn giá gửi tin qua SĐT */\r\n price_sdt: string;\r\n /** Đơn giá gửi tin qua UID */\r\n price_uid: string;\r\n /** Timeout của template */\r\n timeout: number;\r\n /** Link preview template */\r\n preview_url: string;\r\n };\r\n}\r\n\r\nexport interface ZNSUploadImageResult {\r\n error: number;\r\n message: string;\r\n data?: {\r\n media_id: string;\r\n };\r\n}\r\n\r\nexport interface ZNSStatusInfo {\r\n error: number;\r\n message: string;\r\n data?: {\r\n status: \"PENDING\" | \"SENT\" | \"RECEIVED\" | \"FAILED\";\r\n sent_time?: string;\r\n received_time?: string;\r\n fail_reason?: string;\r\n };\r\n}\r\n\r\nexport interface ZNSMessageStatusInfo {\r\n error: number;\r\n message: string;\r\n data?: {\r\n delivery_time: string; // Thời gian thiết bị nhận được thông báo ZNS\r\n message: string; // Mô tả trạng thái thông báo\r\n status: number; // Trạng thái: -1 (không tồn tại), 0 (đã gửi lên server), 1 (đã giao đến thiết bị)\r\n };\r\n}\r\n\r\nexport interface ZNSBatchMessageStatusRequest {\r\n message_ids: string[]; // Danh sách message IDs cần kiểm tra trạng thái\r\n}\r\n\r\nexport interface ZNSBatchMessageStatusResponse {\r\n error: number;\r\n message: string;\r\n data?: {\r\n [messageId: string]: {\r\n delivery_time: string; // Thời gian thiết bị nhận được thông báo ZNS\r\n message: string; // Mô tả trạng thái thông báo\r\n status: number; // Trạng thái: -1 (không tồn tại), 0 (đã gửi lên server), 1 (đã giao đến thiết bị)\r\n };\r\n };\r\n}\r\n\r\nexport interface ZNSQuotaInfo {\r\n error: number;\r\n message: string;\r\n data?: {\r\n dailyQuota: string; // Số thông báo ZNS OA được gửi trong 1 ngày\r\n remainingQuota: string; // Số thông báo ZNS OA được gửi trong ngày còn lại\r\n dailyQuotaPromotion: string | null; // Số tin ZNS hậu mãi OA được gửi trong ngày (null từ 1/11)\r\n remainingQuotaPromotion: string | null; // Số tin ZNS hậu mãi còn lại OA được gửi trong ngày (null từ 1/11)\r\n monthlyPromotionQuota: number; // Số tin ZNS hậu mãi OA được gửi trong tháng\r\n remainingMonthlyPromotionQuota: number; // Số tin ZNS hậu mãi còn lại OA được gửi trong tháng\r\n estimatedNextMonthPromotionQuota: number; // Số tin ZNS hậu mãi dự kiến mà OA có thể gửi trong tháng tiếp theo\r\n };\r\n}\r\n\r\nexport interface ZNSAllowedContentTypes {\r\n error: number;\r\n message: string;\r\n data?: string[]; // Mảng các loại nội dung: [\"TRANSACTION\", \"CUSTOMER_CARE\", \"PROMOTION\"]\r\n}\r\n\r\nexport interface ZNSTemplateSampleData {\r\n error: number;\r\n message: string;\r\n data: Record<string, any>; // Chứa tham số và dữ liệu mẫu của template\r\n}\r\n\r\nexport interface ZNSCustomerRatingResponse {\r\n error: number;\r\n data: {\r\n total: number; // Tổng số lượng đánh giá được trả về\r\n data: Array<{\r\n note: string; // Phần ghi chú thêm của khách hàng\r\n rate: number; // Số sao được khách hàng đánh giá\r\n submitDate: string; // Thời điểm khách hàng submit đánh giá (timestamp millisecond)\r\n msgId: string; // ID của thông tin đánh giá\r\n feedbacks: string[]; // Phần nhận xét từ khách hàng\r\n trackingId: string; // Tracking ID từ phía đối tác\r\n }>;\r\n };\r\n}\r\n\r\nexport interface ZNSOAQualityInfo {\r\n error: number;\r\n message: string;\r\n data: {\r\n oaCurrentQuality: \"HIGH\" | \"MEDIUM\" | \"LOW\" | \"UNDEFINED\"; // Chất lượng gửi ZNS trong 48 giờ gần nhất\r\n oa7dayQuality: \"HIGH\" | \"MEDIUM\" | \"LOW\" | \"UNDEFINED\"; // Chất lượng gửi ZNS trong 7 ngày gần nhất\r\n };\r\n}\r\n\r\nexport interface ZNSQualityHistoryList {\r\n error: number;\r\n message: string;\r\n data?: {\r\n history: Array<{\r\n date: string;\r\n quality: \"HIGH\" | \"MEDIUM\" | \"LOW\";\r\n qualityScore: number;\r\n metrics: {\r\n sent: number;\r\n delivered: number;\r\n read: number;\r\n responded: number;\r\n complained: number;\r\n };\r\n }>;\r\n };\r\n}\r\n\r\nexport interface ZNSTemplateStatus {\r\n templateId: string;\r\n status: \"PENDING_REVIEW\" | \"ENABLE\" | \"REJECT\" | \"DISABLE\";\r\n rejectReason?: string;\r\n enabledTime?: string;\r\n disabledTime?: string;\r\n}\r\n\r\n// ZNS Component Types for Template Creation\r\nexport interface ZNSComponent {\r\n type: \"HEADER\" | \"BODY\" | \"FOOTER\";\r\n format?: \"TEXT\" | \"IMAGE\" | \"VIDEO\";\r\n text?: string;\r\n url?: string;\r\n example?: {\r\n header_text?: string[];\r\n body_text?: string[][];\r\n header_handle?: string[];\r\n };\r\n}\r\n\r\nexport interface ZNSTemplateComponent {\r\n type: \"TITLE\" | \"PARAGRAPH\" | \"TABLE\" | \"LOGO\" | \"IMAGE\" | \"BUTTONS\";\r\n content?: string;\r\n url?: string;\r\n buttons?: Array<{\r\n title: string;\r\n type: \"PHONE_NUMBER\" | \"URL\";\r\n payload: string;\r\n }>;\r\n table?: {\r\n headers: string[];\r\n rows: string[][];\r\n };\r\n}\r\n\r\n// ZNS Error Types\r\nexport interface ZNSError {\r\n error: number;\r\n message: string;\r\n details?: {\r\n field?: string;\r\n code?: string;\r\n description?: string;\r\n };\r\n}\r\n\r\n// ZNS Analytics Types\r\nexport interface ZNSAnalytics {\r\n templateId: string;\r\n period: {\r\n from: string;\r\n to: string;\r\n };\r\n metrics: {\r\n sent: number;\r\n delivered: number;\r\n read: number;\r\n clicked: number;\r\n failed: number;\r\n deliveryRate: number;\r\n readRate: number;\r\n clickRate: number;\r\n };\r\n breakdown?: {\r\n daily?: Array<{\r\n date: string;\r\n sent: number;\r\n delivered: number;\r\n read: number;\r\n clicked: number;\r\n failed: number;\r\n }>;\r\n hourly?: Array<{\r\n hour: number;\r\n sent: number;\r\n delivered: number;\r\n read: number;\r\n clicked: number;\r\n failed: number;\r\n }>;\r\n };\r\n}\r\n\r\n// ===== ZNS Component Validation Types =====\r\n// Các interface cụ thể cho validation từng component\r\n\r\n/** Attachment object cho LOGO và IMAGES */\r\nexport interface ZNSAttachment {\r\n type: \"IMAGE\";\r\n media_id: string;\r\n}\r\n\r\n/** TITLE component */\r\nexport interface ZNSTitleComponent {\r\n value: string; // 9-65 ký tự, tối đa 4 params\r\n}\r\n\r\n/** PARAGRAPH component */\r\nexport interface ZNSParagraphComponent {\r\n value: string; // 9-400 ký tự, tối đa 10 params\r\n}\r\n\r\n/** OTP component */\r\nexport interface ZNSOTPComponent {\r\n value: string; // 1-10 ký tự, tham số cần define type OTP(10)\r\n}\r\n\r\n/** TABLE component */\r\nexport interface ZNSTableComponent {\r\n rows: ZNSTableRow[]; // 2-8 rows\r\n}\r\n\r\nexport interface ZNSTableRow {\r\n title: string; // 3-36 ký tự, chỉ text cố định\r\n value: string; // 3-90 ký tự, có thể có params\r\n row_type?: 0 | 1 | 2 | 3 | 4 | 5; // Hiệu ứng row\r\n}\r\n\r\n/** LOGO component */\r\nexport interface ZNSLogoComponent {\r\n light: ZNSAttachment;\r\n dark: ZNSAttachment;\r\n}\r\n\r\n/** IMAGES component */\r\nexport interface ZNSImagesComponent {\r\n items: ZNSAttachment[]; // 1-3 attachments\r\n}\r\n\r\n/** BUTTONS component */\r\nexport interface ZNSButtonsComponent {\r\n items: ZNSButtonItem[]; // 1-2 buttons\r\n}\r\n\r\nexport interface ZNSButtonItem {\r\n type: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12; // Button types\r\n title: string; // 5-30 ký tự, chỉ text cố định\r\n content: string; // URL/phone, có thể có params (URL(200) sub domain)\r\n}\r\n\r\n/** PAYMENT component */\r\nexport interface ZNSPaymentComponent {\r\n bank_code: string; // Bank code cố định\r\n account_name: string; // 1-100 ký tự, text cố định\r\n bank_account: string; // 1-100 ký tự, text cố định (Doc: bank_account)\r\n amount: string; // 2,000 - 500,000,000 hoặc param (VNĐ 12)\r\n note?: string; // 1-90 ký tự, có thể có params (Bank transfer note 90)\r\n}\r\n\r\n/** VOUCHER component */\r\nexport interface ZNSVoucherComponent {\r\n name: string; // 1-30 ký tự, có thể có params\r\n condition: string; // 1-40 ký tự, có thể có params\r\n start_date?: string; // Có thể có params/datetime\r\n end_date: string; // Có thể có params/datetime\r\n voucher_code: string; // 1-25 ký tự, có thể có params (Mã số 30)\r\n}\r\n\r\n/** RATING component */\r\nexport interface ZNSRatingComponent {\r\n items: ZNSRatingItem[]; // Đúng 5 items\r\n}\r\n\r\nexport interface ZNSRatingItem {\r\n star: 1 | 2 | 3 | 4 | 5; // Số sao\r\n title: string; // 1-50 ký tự\r\n question?: string; // 1-100 ký tự\r\n answers?: string[]; // Danh sách câu trả lời (Doc: answers List string)\r\n thanks: string; // 1-100 ký tự\r\n description: string; // 1-200 ký tự\r\n}\r\n\r\n/** Union type cho tất cả các component */\r\nexport type ZNSValidationComponent =\r\n | { TITLE: ZNSTitleComponent }\r\n | { PARAGRAPH: ZNSParagraphComponent }\r\n | { OTP: ZNSOTPComponent }\r\n | { TABLE: ZNSTableComponent }\r\n | { LOGO: ZNSLogoComponent }\r\n | { IMAGES: ZNSImagesComponent }\r\n | { BUTTONS: ZNSButtonsComponent }\r\n | { PAYMENT: ZNSPaymentComponent }\r\n | { VOUCHER: ZNSVoucherComponent }\r\n | { RATING: ZNSRatingComponent };\r\n","/**\r\n * Types for Zalo Official Account Article Management\r\n * Based on Zalo Article API v2.0\r\n */\r\n\r\nimport { ZaloApiResponse, ZaloResponse } from \"./common\";\r\n\r\n// ==================== ARTICLE COVER TYPES ====================\r\n\r\n/**\r\n * Article cover configuration\r\n */\r\nexport interface ArticleCover {\r\n /** Cover type: photo or video */\r\n cover_type: 'photo' | 'video';\r\n /** Photo URL (required when cover_type is 'photo') */\r\n photo_url?: string;\r\n /** Video ID (required when cover_type is 'video') */\r\n video_id?: string;\r\n /** Cover vie