UNPKG

@warriorteam/zalo-personal

Version:

Unofficial Zalo Personal API for JavaScript - A powerful library for interacting with Zalo personal accounts with URL attachment support, auto-reply, product catalog, and business features

108 lines (107 loc) 4.63 kB
import { loginQR, LoginQRCallbackEventType } from "./apis/loginQR.js"; import { getServerInfo, login } from "./apis/login.js"; import { createContext, isContextSession, } from "./context.js"; import { generateZaloUUID, logger } from "./utils.js"; import toughCookie from "tough-cookie"; import { ZaloApiError } from "./Errors/ZaloApiError.js"; import { checkUpdate } from "./update.js"; import { API } from "./apis.js"; export class Zalo { constructor(options = {}) { this.options = options; this.enableEncryptParam = true; } parseCookies(cookie) { const cookieArr = Array.isArray(cookie) ? cookie : cookie.cookies; cookieArr.forEach((e, i) => { if (typeof e.domain == "string" && e.domain.startsWith(".")) cookieArr[i].domain = e.domain.slice(1); }); const jar = new toughCookie.CookieJar(); for (const each of cookieArr) { try { const cookieObj = toughCookie.Cookie.fromJSON(Object.assign(Object.assign({}, each), { key: each.key || each.name })); if (cookieObj) { const domain = cookieObj.domain || "chat.zalo.me"; const url = `https://${domain.startsWith(".") ? domain.slice(1) : domain}`; jar.setCookieSync(cookieObj, url); } } catch (error) { logger({ options: { logging: this.options.logging, }, }).error("Failed to set cookie:", error); } } return jar; } validateParams(credentials) { if (!credentials.imei || !credentials.cookie || !credentials.userAgent) { throw new ZaloApiError("Missing required params"); } } async login(credentials) { const ctx = createContext(this.options.apiType, this.options.apiVersion); Object.assign(ctx.options, this.options); return this.loginCookie(ctx, credentials); } async loginCookie(ctx, credentials) { await checkUpdate(ctx); this.validateParams(credentials); ctx.imei = credentials.imei; ctx.cookie = this.parseCookies(credentials.cookie); ctx.userAgent = credentials.userAgent; ctx.language = credentials.language || "vi"; const loginData = await login(ctx, this.enableEncryptParam); const serverInfo = await getServerInfo(ctx, this.enableEncryptParam); const loginInfo = loginData === null || loginData === void 0 ? void 0 : loginData.data; if (!loginData || !loginInfo || !serverInfo) throw new ZaloApiError("Đăng nhập thất bại"); ctx.secretKey = loginInfo.zpw_enk; ctx.uid = loginInfo.uid; // Zalo currently responds with setttings instead of settings // they might fix this in the future, so we should have a fallback just in case ctx.settings = serverInfo.setttings || serverInfo.settings; ctx.extraVer = serverInfo.extra_ver; ctx.loginInfo = loginInfo; if (!isContextSession(ctx)) throw new ZaloApiError("Khởi tạo ngữ cảnh thất bại."); logger(ctx).info("Logged in as", loginInfo.uid); return new API(ctx, loginInfo.zpw_service_map_v3, loginInfo.zpw_ws); } async loginQR(options, callback) { if (!options) options = {}; if (!options.userAgent) options.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0"; if (!options.language) options.language = "vi"; const ctx = createContext(this.options.apiType, this.options.apiVersion); Object.assign(ctx.options, this.options); const loginQRResult = await loginQR(ctx, options, callback); if (!loginQRResult) throw new ZaloApiError("Unable to login with QRCode"); const imei = generateZaloUUID(options.userAgent); if (callback) { // Thanks to @YanCastle for this great suggestion! callback({ type: LoginQRCallbackEventType.GotLoginInfo, data: { cookie: loginQRResult.cookies, imei, userAgent: options.userAgent, }, actions: null, }); } return this.loginCookie(ctx, { cookie: loginQRResult.cookies, imei, userAgent: options.userAgent, language: options.language, }); } } export { API };