UNPKG

@baileys-md/baileys

Version:

Baileys WhatsApp API

233 lines 7.79 kB
//=======================================================// import { getBinaryNodeChild, getBinaryNodeChildren, getBinaryNodeChildString } from "../WABinary/index.js"; import { getStream, getUrlFromDirectPath } from "./messages-media.js"; import { createWriteStream, promises as fs } from "fs"; import { generateMessageIDV2 } from "./generics.js"; import { createHash } from "crypto"; import { Boom } from "@hapi/boom"; import { tmpdir } from "os"; import { join } from "path"; //=======================================================// export const parseCatalogNode = (node) => { const catalogNode = getBinaryNodeChild(node, "product_catalog"); const products = getBinaryNodeChildren(catalogNode, "product").map(parseProductNode); const paging = getBinaryNodeChild(catalogNode, "paging"); return { products, nextPageCursor: paging ? getBinaryNodeChildString(paging, "after") : undefined }; }; //=======================================================// export const parseCollectionsNode = (node) => { const collectionsNode = getBinaryNodeChild(node, "collections"); const collections = getBinaryNodeChildren(collectionsNode, "collection").map(collectionNode => { const id = getBinaryNodeChildString(collectionNode, "id"); const name = getBinaryNodeChildString(collectionNode, "name"); const products = getBinaryNodeChildren(collectionNode, "product").map(parseProductNode); return { id, name, products, status: parseStatusInfo(collectionNode) }; }); return { collections }; }; //=======================================================// export const parseOrderDetailsNode = (node) => { const orderNode = getBinaryNodeChild(node, "order"); const products = getBinaryNodeChildren(orderNode, "product").map(productNode => { const imageNode = getBinaryNodeChild(productNode, "image"); return { id: getBinaryNodeChildString(productNode, "id"), name: getBinaryNodeChildString(productNode, "name"), imageUrl: getBinaryNodeChildString(imageNode, "url"), price: +getBinaryNodeChildString(productNode, "price"), currency: getBinaryNodeChildString(productNode, "currency"), quantity: +getBinaryNodeChildString(productNode, "quantity") }; }); const priceNode = getBinaryNodeChild(orderNode, "price"); const orderDetails = { price: { total: +getBinaryNodeChildString(priceNode, "total"), currency: getBinaryNodeChildString(priceNode, "currency") }, products }; return orderDetails; }; //=======================================================// export const toProductNode = (productId, product) => { const attrs = {}; const content = []; if (typeof productId !== "undefined") { content.push({ tag: "id", attrs: {}, content: Buffer.from(productId) }); } if (typeof product.name !== "undefined") { content.push({ tag: "name", attrs: {}, content: Buffer.from(product.name) }); } if (typeof product.description !== "undefined") { content.push({ tag: "description", attrs: {}, content: Buffer.from(product.description) }); } if (typeof product.retailerId !== "undefined") { content.push({ tag: "retailer_id", attrs: {}, content: Buffer.from(product.retailerId) }); } if (product.images.length) { content.push({ tag: "media", attrs: {}, content: product.images.map(img => { if (!("url" in img)) { throw new Boom("Expected img for product to already be uploaded", { statusCode: 400 }); } return { tag: "image", attrs: {}, content: [ { tag: "url", attrs: {}, content: Buffer.from(img.url.toString()) } ] }; }) }); } if (typeof product.price !== "undefined") { content.push({ tag: "price", attrs: {}, content: Buffer.from(product.price.toString()) }); } if (typeof product.currency !== "undefined") { content.push({ tag: "currency", attrs: {}, content: Buffer.from(product.currency) }); } if ("originCountryCode" in product) { if (typeof product.originCountryCode === "undefined") { attrs["compliance_category"] = "COUNTRY_ORIGIN_EXEMPT"; } else { content.push({ tag: "compliance_info", attrs: {}, content: [ { tag: "country_code_origin", attrs: {}, content: Buffer.from(product.originCountryCode) } ] }); } } if (typeof product.isHidden !== "undefined") { attrs["is_hidden"] = product.isHidden.toString(); } const node = { tag: "product", attrs, content }; return node; }; //=======================================================// export const parseProductNode = (productNode) => { const isHidden = productNode.attrs.is_hidden === "true"; const id = getBinaryNodeChildString(productNode, "id"); const mediaNode = getBinaryNodeChild(productNode, "media"); const statusInfoNode = getBinaryNodeChild(productNode, "status_info"); const product = { id, imageUrls: parseImageUrls(mediaNode), reviewStatus: { whatsapp: getBinaryNodeChildString(statusInfoNode, "status") }, availability: "in stock", name: getBinaryNodeChildString(productNode, "name"), retailerId: getBinaryNodeChildString(productNode, "retailer_id"), url: getBinaryNodeChildString(productNode, "url"), description: getBinaryNodeChildString(productNode, "description"), price: +getBinaryNodeChildString(productNode, "price"), currency: getBinaryNodeChildString(productNode, "currency"), isHidden }; return product; }; //=======================================================// export async function uploadingNecessaryImagesOfProduct(product, waUploadToServer, timeoutMs = 30000) { product = { ...product, images: product.images ? await uploadingNecessaryImages(product.images, waUploadToServer, timeoutMs) : product.images }; return product; } //=======================================================// export const uploadingNecessaryImages = async (images, waUploadToServer, timeoutMs = 30000) => { const results = await Promise.all(images.map(async (img) => { if ("url" in img) { const url = img.url.toString(); if (url.includes(".whatsapp.net")) { return { url }; } } const { stream } = await getStream(img); const hasher = createHash("sha256"); const filePath = join(tmpdir(), "img" + generateMessageIDV2()); const encFileWriteStream = createWriteStream(filePath); for await (const block of stream) { hasher.update(block); encFileWriteStream.write(block); } const sha = hasher.digest("base64"); const { directPath } = await waUploadToServer(filePath, { mediaType: "product-catalog-image", fileEncSha256B64: sha, timeoutMs }); await fs.unlink(filePath).catch(err => console.log("Error deleting temp file ", err)); return { url: getUrlFromDirectPath(directPath) }; })); return results; }; const parseImageUrls = (mediaNode) => { const imgNode = getBinaryNodeChild(mediaNode, "image"); return { requested: getBinaryNodeChildString(imgNode, "request_image_url"), original: getBinaryNodeChildString(imgNode, "original_image_url") }; }; const parseStatusInfo = (mediaNode) => { const node = getBinaryNodeChild(mediaNode, "status_info"); return { status: getBinaryNodeChildString(node, "status"), canAppeal: getBinaryNodeChildString(node, "can_appeal") === "true" }; }; //=======================================================//