Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for sticker Name and author #527

Merged
merged 55 commits into from
May 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
9687b72
Added Sticker author and sticker name support
PurpShell Jan 29, 2021
0282c3b
Docs: stickerName and stickerAuthor in MessageOpts
PurpShell Jan 29, 2021
c37e82d
Merge pull request #1 from PurpShell/PurpShell-sticker-patch-1
PurpShell Jan 29, 2021
3d1d3df
Hotfix_Sticker_Feature
PurpShell Jan 29, 2021
6a0aef3
Update global.html
PurpShell Jan 29, 2021
8a7c213
updated
PurpShell Jan 29, 2021
7ec48ad
fixed comma
PurpShell Jan 29, 2021
369ec19
Fixed duplicate code
PurpShell Feb 2, 2021
afd7e63
Fixing eslint
PurpShell Feb 2, 2021
54b14b7
Fixing eslint again
PurpShell Feb 2, 2021
c0bc83b
eslint....
PurpShell Feb 2, 2021
d52e0a5
fixing problem with eslint.
PurpShell Feb 2, 2021
46836a7
Merge branch 'master' into master
PurpShell Feb 2, 2021
fe3648d
move sticker exif data filling to Utils.formatToWebpSticker() function
mpirescarvalho Feb 2, 2021
f421cd7
Merge pull request #2 from mpirescarvalho/refactor
PurpShell Feb 2, 2021
30ded90
Update Client.js
PurpShell Feb 2, 2021
a1b244b
Added temporary stuff
PurpShell Feb 2, 2021
86c8a4e
eslint
PurpShell Feb 2, 2021
ff784ed
Update Util.js
PurpShell Feb 2, 2021
3735e8d
eslint bad :D
PurpShell Feb 2, 2021
638add0
eslint
PurpShell Feb 2, 2021
b2363b4
polish work with files
mpirescarvalho Feb 2, 2021
ccbf129
Merge pull request #3 from mpirescarvalho/refactor
PurpShell Feb 2, 2021
8b9b058
fix error and TODOs
mpirescarvalho Feb 3, 2021
8283f8f
Merge pull request #4 from mpirescarvalho/sticker-name
PurpShell Feb 3, 2021
6ae511c
clean up code to match with repo code style
mpirescarvalho Feb 5, 2021
ca3dee7
update typescript params
mpirescarvalho Feb 5, 2021
7a1471f
Merge pull request #5 from mpirescarvalho/refactor
PurpShell Feb 7, 2021
3380bc7
Merge branch 'master' into master
pedroslopez Feb 11, 2021
c2270d1
Merge branch 'master' into master
pedroslopez Feb 11, 2021
56c665c
Update src/util/Util.js
PurpShell Feb 12, 2021
2558af1
Update Util.js
PurpShell Feb 12, 2021
09ff743
Merge branch 'master' into master
PurpShell Feb 27, 2021
25e5808
:heavy_minus_sign: webp-converter :heavy_plus_sign: node-webpmux
PurpShell Apr 15, 2021
8111e27
Update Util.js
PurpShell Apr 15, 2021
b4d4c88
:sparkles: Use node-webpmux
PurpShell Apr 15, 2021
538cfde
:heavy_minus_sign: node-webpmux :heavy_plus_sign: node-webpmux-commonjs
PurpShell Apr 15, 2021
a5765d2
:pencil2: Fixed require mode
PurpShell Apr 15, 2021
1ba5678
:heavy_plus_sign:node-webpmux :heavy_minus_sign: node-webpmux-commonjs
PurpShell Apr 18, 2021
129267c
:arrow_up: Node-webpmux update changes
PurpShell Apr 18, 2021
49c8164
:rotating_light: removing try/catch
PurpShell Apr 18, 2021
7e0ba24
:rotating_light: complier warnings
PurpShell Apr 18, 2021
eaf669e
:monocle_face: stupid mistakes
PurpShell Apr 18, 2021
742726b
:arrow_up: Upgrade required version
PurpShell Apr 18, 2021
27d6151
:bug: creating a buffer the right way
PurpShell Apr 18, 2021
2640bf5
:bug: linting and simplification
PurpShell Apr 18, 2021
b926df6
:bug: unsimplification
PurpShell Apr 18, 2021
cd175a9
:rotating_light: eslint loves singlequotes
PurpShell Apr 19, 2021
1d3cb79
Merge branch 'master' into master
PurpShell Apr 21, 2021
9031290
:sparkles: Added emojis / categories in metadata
PurpShell May 25, 2021
2e776b5
:label: TypeScript Declarations
PurpShell May 25, 2021
9f38298
:sparkles: Sticker Categories in sendMessage
PurpShell May 25, 2021
eb3d2f0
:label: Improved TS declarations
PurpShell May 25, 2021
33a99c5
fix stickerCategories type
pedroslopez May 31, 2021
da610c2
fix: don't set name/author if not defined
pedroslopez May 31, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
10 changes: 9 additions & 1 deletion src/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/

Expand Down Expand Up @@ -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) => {
Expand Down
54 changes: 49 additions & 5 deletions src/util/Util.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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;
}

/**
Expand All @@ -156,4 +200,4 @@ class Util {
}
}

module.exports = Util;
module.exports = Util;