mirror of
https://github.com/cheveguerra/whatsapp-web.js.git
synced 2026-04-18 03:29:14 +00:00
Add support for sticker Name and author (#527)
* Added Sticker author and sticker name support This patch of Client.js includes support for sticker metadata * Docs: stickerName and stickerAuthor in MessageOpts * Hotfix_Sticker_Feature fixes a bug * Update global.html * updated * fixed comma * Fixed duplicate code * Fixing eslint * Fixing eslint again * eslint.... * fixing problem with eslint. * move sticker exif data filling to Utils.formatToWebpSticker() function * Update Client.js * Added temporary stuff * eslint * Update Util.js * eslint bad :D * eslint * polish work with files * fix error and TODOs * clean up code to match with repo code style * update typescript params * Update src/util/Util.js camel Case Co-authored-by: Pedro S. Lopez <pedroslopez@me.com> * Update Util.js * ➖ webp-converter ➕ node-webpmux * Update Util.js * ✨ Use node-webpmux * ➖ node-webpmux ➕ node-webpmux-commonjs * ✏️ Fixed require mode * :heavy_plus_sign:node-webpmux ➖ node-webpmux-commonjs * ⬆️ Node-webpmux update changes * 🚨 removing try/catch * 🚨 complier warnings * 🧐 stupid mistakes * ⬆️ Upgrade required version * 🐛 creating a buffer the right way * 🐛 linting and simplification * 🐛 unsimplification * 🚨 eslint loves singlequotes * ✨ Added emojis / categories in metadata * 🏷️ TypeScript Declarations * ✨ Sticker Categories in sendMessage * 🏷️ Improved TS declarations * fix stickerCategories type * fix: don't set name/author if not defined Co-authored-by: Marcelo Carvalho <mpirescarvalho17@gmail.com> Co-authored-by: Pedro S. Lopez <pslamoros@hotmail.com> Co-authored-by: Pedro S. Lopez <pedroslopez@me.com>
This commit is contained in:
6
index.d.ts
vendored
6
index.d.ts
vendored
@@ -600,6 +600,12 @@ declare namespace WAWebJS {
|
||||
sendSeen?: boolean
|
||||
/** Media to be sent */
|
||||
media?: MessageMedia
|
||||
/** Sticker name, if sendMediaAsSticker is true */
|
||||
stickerName?: string
|
||||
/** Sticker author, if sendMediaAsSticker is true */
|
||||
stickerAuthor?: string
|
||||
/** Sticker categories, if sendMediaAsSticker is true */
|
||||
stickerCategories?: string[]
|
||||
}
|
||||
|
||||
/** Media attached to a message */
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
"fluent-ffmpeg": "^2.1.2",
|
||||
"jsqr": "^1.3.1",
|
||||
"mime": "^2.4.5",
|
||||
"node-webpmux":"^2.0.0",
|
||||
"puppeteer": "^5.2.1",
|
||||
"sharp": "^0.26.3"
|
||||
},
|
||||
|
||||
@@ -437,6 +437,9 @@ class Client extends EventEmitter {
|
||||
* @property {string} [quotedMessageId] - Id of the message that is being quoted (or replied to)
|
||||
* @property {Contact[]} [mentions] - Contacts that are being mentioned in the message
|
||||
* @property {boolean} [sendSeen=true] - Mark the conversation as seen after sending the message
|
||||
* @property {string} [stickerAuthor=undefined] - Sets the author of the sticker, (if sendMediaAsSticker is true).
|
||||
* @property {string} [stickerName=undefined] - Sets the name of the sticker, (if sendMediaAsSticker is true).
|
||||
* @property {string[]} [stickerCategories=undefined] - Sets the categories of the sticker, (if sendMediaAsSticker is true). Provide emoji char array, can be null.
|
||||
* @property {MessageMedia} [media] - Media to be sent
|
||||
*/
|
||||
|
||||
@@ -481,7 +484,12 @@ class Client extends EventEmitter {
|
||||
}
|
||||
|
||||
if (internalOptions.sendMediaAsSticker && internalOptions.attachment) {
|
||||
internalOptions.attachment = await Util.formatToWebpSticker(internalOptions.attachment);
|
||||
internalOptions.attachment =
|
||||
await Util.formatToWebpSticker(internalOptions.attachment, {
|
||||
name: options.stickerName,
|
||||
author: options.stickerAuthor,
|
||||
categories: options.stickerCategories
|
||||
});
|
||||
}
|
||||
|
||||
const newMessage = await this.pupPage.evaluate(async (chatId, message, options, sendSeen) => {
|
||||
|
||||
@@ -5,6 +5,7 @@ const path = require('path');
|
||||
const Crypto = require('crypto');
|
||||
const { tmpdir } = require('os');
|
||||
const ffmpeg = require('fluent-ffmpeg');
|
||||
const webp = require('node-webpmux');
|
||||
const fs = require('fs').promises;
|
||||
|
||||
const has = (o, k) => Object.prototype.hasOwnProperty.call(o, k);
|
||||
@@ -18,6 +19,16 @@ class Util {
|
||||
throw new Error(`The ${this.constructor.name} class may not be instantiated.`);
|
||||
}
|
||||
|
||||
static generateHash(length) {
|
||||
var result = '';
|
||||
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
var charactersLength = characters.length;
|
||||
for ( var i = 0; i < length; i++ ) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets default properties on an object that aren't already specified.
|
||||
* @param {Object} def Default properties
|
||||
@@ -135,16 +146,49 @@ class Util {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sticker metadata.
|
||||
* @typedef {Object} StickerMetadata
|
||||
* @property {string} [name]
|
||||
* @property {string} [author]
|
||||
* @property {string[]} [categories]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Formats a media to webp
|
||||
* @param {MessageMedia} media
|
||||
* @param {StickerMetadata} metadata
|
||||
*
|
||||
* @returns {Promise<MessageMedia>} media in webp format
|
||||
*/
|
||||
static async formatToWebpSticker(media) {
|
||||
if (media.mimetype.includes('image')) return this.formatImageToWebpSticker(media);
|
||||
else if (media.mimetype.includes('video')) return this.formatVideoToWebpSticker(media);
|
||||
else throw new Error('Invalid media format');
|
||||
static async formatToWebpSticker(media, metadata) {
|
||||
let webpMedia;
|
||||
|
||||
if (media.mimetype.includes('image'))
|
||||
webpMedia = await this.formatImageToWebpSticker(media);
|
||||
else if (media.mimetype.includes('video'))
|
||||
webpMedia = await this.formatVideoToWebpSticker(media);
|
||||
else
|
||||
throw new Error('Invalid media format');
|
||||
|
||||
if (metadata.name || metadata.author) {
|
||||
const img = new webp.Image();
|
||||
const hash = this.generateHash(32);
|
||||
const stickerPackId = hash;
|
||||
const packname = metadata.name;
|
||||
const author = metadata.author;
|
||||
const categories = metadata.categories || [''];
|
||||
const json = { 'sticker-pack-id': stickerPackId, 'sticker-pack-name': packname, 'sticker-pack-publisher': author, 'emojis': categories };
|
||||
let exifAttr = Buffer.from([0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00]);
|
||||
let jsonBuffer = Buffer.from(JSON.stringify(json), 'utf8');
|
||||
let exif = Buffer.concat([exifAttr, jsonBuffer]);
|
||||
exif.writeUIntLE(jsonBuffer.length, 14, 4);
|
||||
await img.loadBuffer(Buffer.from(webpMedia.data, 'base64'));
|
||||
img.exif = exif;
|
||||
webpMedia.data = (await img.saveBuffer()).toString('base64');
|
||||
}
|
||||
|
||||
return webpMedia;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,4 +200,4 @@ class Util {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Util;
|
||||
module.exports = Util;
|
||||
|
||||
Reference in New Issue
Block a user