@ryuu-reinzz/haruka-lib 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/main/index.js +1 -1
- package/main/socket.js +2 -5
- package/main/sticker-engine/image-to-webp.js +57 -0
- package/main/sticker-engine/index.js +6 -0
- package/main/sticker-engine/main-sticker.js +48 -0
- package/main/sticker-engine/video-to-webp.js +68 -0
- package/package.json +2 -5
- package/main/sticker-engine/java-script/Sticker.d.ts +0 -130
- package/main/sticker-engine/java-script/Sticker.js +0 -188
- package/main/sticker-engine/java-script/Types.d.ts +0 -43
- package/main/sticker-engine/java-script/Types.js +0 -1
- package/main/sticker-engine/java-script/Utils.d.ts +0 -9
- package/main/sticker-engine/java-script/Utils.js +0 -11
- package/main/sticker-engine/java-script/extractMetadata.d.ts +0 -6
- package/main/sticker-engine/java-script/extractMetadata.js +0 -12
- package/main/sticker-engine/java-script/index.d.ts +0 -8
- package/main/sticker-engine/java-script/index.js +0 -8
- package/main/sticker-engine/java-script/internal/Metadata/Exif.d.ts +0 -9
- package/main/sticker-engine/java-script/internal/Metadata/Exif.js +0 -35
- package/main/sticker-engine/java-script/internal/Metadata/RawMetadata.d.ts +0 -8
- package/main/sticker-engine/java-script/internal/Metadata/RawMetadata.js +0 -9
- package/main/sticker-engine/java-script/internal/Metadata/StickerMetadata.d.ts +0 -18
- package/main/sticker-engine/java-script/internal/Metadata/StickerMetadata.js +0 -49
- package/main/sticker-engine/java-script/internal/Metadata/StickerTypes.d.ts +0 -7
- package/main/sticker-engine/java-script/internal/Metadata/StickerTypes.js +0 -8
- package/main/sticker-engine/java-script/internal/convert.d.ts +0 -3
- package/main/sticker-engine/java-script/internal/convert.js +0 -69
- package/main/sticker-engine/java-script/internal/crop.d.ts +0 -2
- package/main/sticker-engine/java-script/internal/crop.js +0 -30
- package/main/sticker-engine/java-script/internal/imagesToWebp.d.ts +0 -2
- package/main/sticker-engine/java-script/internal/imagesToWebp.js +0 -17
- package/main/sticker-engine/java-script/internal/videoToGif.d.ts +0 -3
- package/main/sticker-engine/java-script/internal/videoToGif.js +0 -16
- package/main/sticker-engine/type-script/Sticker.ts +0 -206
- package/main/sticker-engine/type-script/Types.ts +0 -189
- package/main/sticker-engine/type-script/Utils.ts +0 -12
- package/main/sticker-engine/type-script/extractMetadata.ts +0 -13
- package/main/sticker-engine/type-script/index.ts +0 -9
- package/main/sticker-engine/type-script/internal/Metadata/Exif.ts +0 -39
- package/main/sticker-engine/type-script/internal/Metadata/RawMetadata.ts +0 -15
- package/main/sticker-engine/type-script/internal/Metadata/StickerMetadata.ts +0 -60
- package/main/sticker-engine/type-script/internal/Metadata/StickerTypes.ts +0 -7
- package/main/sticker-engine/type-script/internal/convert.ts +0 -87
- package/main/sticker-engine/type-script/internal/crop.ts +0 -32
- package/main/sticker-engine/type-script/internal/imagesToWebp.ts +0 -19
- package/main/sticker-engine/type-script/internal/node-webpmux.d.ts +0 -8
- package/main/sticker-engine/type-script/internal/videoToGif.ts +0 -18
- package/tsconfig.json +0 -13
package/main/index.js
CHANGED
package/main/socket.js
CHANGED
|
@@ -4,7 +4,7 @@ import fs from "fs";
|
|
|
4
4
|
import path from "path";
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import { dirname } from 'path';
|
|
7
|
-
import Sticker from './sticker-engine/
|
|
7
|
+
import Sticker from './sticker-engine/index.js';
|
|
8
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
9
|
const __dirname = dirname(__filename);
|
|
10
10
|
|
|
@@ -137,10 +137,7 @@ Object.assign(socket, {
|
|
|
137
137
|
|
|
138
138
|
const sticker = new Sticker(stickerPath, {
|
|
139
139
|
pack: options.packname || "Made By",
|
|
140
|
-
author: options.author || "漏 饾檷廷饾櫘饾櫔饾櫔 饾檷廷饾櫄饾櫈饾櫍饾櫙饾櫙"
|
|
141
|
-
type: options.type || 'full',
|
|
142
|
-
categories: options.categories || ['馃椏'],
|
|
143
|
-
quality: options.quality || 80
|
|
140
|
+
author: options.author || "漏 饾檷廷饾櫘饾櫔饾櫔 饾檷廷饾櫄饾櫈饾櫍饾櫙饾櫙"
|
|
144
141
|
})
|
|
145
142
|
|
|
146
143
|
const buffer = await sticker.build()
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import fs from 'fs-extra'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import webp from 'node-webpmux'
|
|
4
|
+
import ffmpeg from 'fluent-ffmpeg'
|
|
5
|
+
import Crypto from 'crypto'
|
|
6
|
+
import { tmpdir } from 'os'
|
|
7
|
+
|
|
8
|
+
async function imageToWebp(media) {
|
|
9
|
+
const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`);
|
|
10
|
+
const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.jpg`);
|
|
11
|
+
fs.writeFile(tmpFileIn, media);
|
|
12
|
+
|
|
13
|
+
await new Promise((resolve, reject) => {
|
|
14
|
+
ff(tmpFileIn)
|
|
15
|
+
.on('error', reject)
|
|
16
|
+
.on('end', () => resolve(true))
|
|
17
|
+
.addOutputOptions([
|
|
18
|
+
'-vcodec',
|
|
19
|
+
'libwebp',
|
|
20
|
+
'-vf',
|
|
21
|
+
"scale='min(320,iw)':min'(320,ih)':force_original_aspect_ratio=decrease,fps=15, pad=320:320:-1:-1:color=white@0.0, split [a][b]; [a] palettegen=reserve_transparent=on:transparency_color=ffffff [p]; [b][p] paletteuse"
|
|
22
|
+
])
|
|
23
|
+
.toFormat('webp')
|
|
24
|
+
.save(tmpFileOut);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const buff = fs.readFile(tmpFileOut);
|
|
28
|
+
fs.unlink(tmpFileOut);
|
|
29
|
+
fs.unlink(tmpFileIn);
|
|
30
|
+
return buff;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function stickerImg(media, metadata) {
|
|
34
|
+
const wMedia = await imageToWebp(media);
|
|
35
|
+
const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`);
|
|
36
|
+
const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`);
|
|
37
|
+
fs.writeFile(tmpFileIn, wMedia);
|
|
38
|
+
|
|
39
|
+
if (metadata.packname || metadata.author) {
|
|
40
|
+
const img = new webp.Image();
|
|
41
|
+
const json = {
|
|
42
|
+
'sticker-pack-id': 'https://github.com/DikaArdnt/Hisoka-Morou',
|
|
43
|
+
'sticker-pack-name': metadata.packname,
|
|
44
|
+
'sticker-pack-publisher': metadata.author,
|
|
45
|
+
'emojis': metadata.categories ?? ['']
|
|
46
|
+
};
|
|
47
|
+
const 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]);
|
|
48
|
+
const jsonBuff = Buffer.from(JSON.stringify(json), 'utf-8');
|
|
49
|
+
const exif = Buffer.concat([exifAttr, jsonBuff]);
|
|
50
|
+
exif.writeUIntLE(jsonBuff.length, 14, 4);
|
|
51
|
+
await img.load(tmpFileIn);
|
|
52
|
+
fs.unlink(tmpFileIn);
|
|
53
|
+
img.exif = exif;
|
|
54
|
+
await img.save(tmpFileOut);
|
|
55
|
+
return tmpFileOut;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import fs from 'fs-extra'
|
|
2
|
+
import ffmpeg from 'fluent-ffmpeg'
|
|
3
|
+
import { stickerVid } from './video-to-webp.js'
|
|
4
|
+
import { stickerImg } from './image-to-webp.js'
|
|
5
|
+
|
|
6
|
+
class Sticker {
|
|
7
|
+
constructor(media, options = {}) {
|
|
8
|
+
this.media = media
|
|
9
|
+
this.pack = options.pack || 'Made By'
|
|
10
|
+
this.author = options.author || 'Unknown'
|
|
11
|
+
this.categories = options.categories ?? ['']
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async toStickerImg() {
|
|
15
|
+
const out = await stickerImg(this.media, {
|
|
16
|
+
packname: this.pack,
|
|
17
|
+
author: this.author,
|
|
18
|
+
categories: this.categories
|
|
19
|
+
})
|
|
20
|
+
return fs.readFile(out)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async toStickerVid() {
|
|
24
|
+
const out = await stickerVid(this.media, {
|
|
25
|
+
packname: this.pack,
|
|
26
|
+
author: this.author,
|
|
27
|
+
categories: this.categories
|
|
28
|
+
})
|
|
29
|
+
return fs.readFile(out)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async build() {
|
|
33
|
+
const isVideo = await new Promise(resolve => {
|
|
34
|
+
ffmpeg.ffprobe(this.media, (err, meta) => {
|
|
35
|
+
if (err) return resolve(false)
|
|
36
|
+
resolve(meta.streams.some(s => s.codec_type === 'video'))
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
if (isVideo) {
|
|
41
|
+
return await this.toStickerVid()
|
|
42
|
+
} else {
|
|
43
|
+
return await this.toStickerImg()
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default Sticker
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import fs from 'fs-extra'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import webp from 'node-webpmux'
|
|
4
|
+
import ffmpeg from 'fluent-ffmpeg'
|
|
5
|
+
import Crypto from 'crypto'
|
|
6
|
+
import { tmpdir } from 'os'
|
|
7
|
+
|
|
8
|
+
async function videoToWebp(media) {
|
|
9
|
+
const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`);
|
|
10
|
+
const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.mp4`);
|
|
11
|
+
fs.writeFile(tmpFileIn, media);
|
|
12
|
+
|
|
13
|
+
await new Promise((resolve, reject) => {
|
|
14
|
+
ff(tmpFileIn)
|
|
15
|
+
.on('error', reject)
|
|
16
|
+
.on('end', () => resolve(true))
|
|
17
|
+
.addOutputOptions([
|
|
18
|
+
'-vcodec',
|
|
19
|
+
'libwebp',
|
|
20
|
+
'-vf',
|
|
21
|
+
"scale='min(320,iw)':min'(320,ih)':force_original_aspect_ratio=decrease,fps=15, pad=320:320:-1:-1:color=white@0.0, split [a][b]; [a] palettegen=reserve_transparent=on:transparency_color=ffffff [p]; [b][p] paletteuse",
|
|
22
|
+
'-loop',
|
|
23
|
+
'0',
|
|
24
|
+
'-ss',
|
|
25
|
+
'00:00:00',
|
|
26
|
+
'-t',
|
|
27
|
+
'00:00:05',
|
|
28
|
+
'-preset',
|
|
29
|
+
'default',
|
|
30
|
+
'-an',
|
|
31
|
+
'-vsync',
|
|
32
|
+
'0'
|
|
33
|
+
])
|
|
34
|
+
.toFormat('webp')
|
|
35
|
+
.save(tmpFileOut);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const buff = fs.readFile(tmpFileOut);
|
|
39
|
+
fs.unlink(tmpFileOut);
|
|
40
|
+
fs.unlink(tmpFileIn);
|
|
41
|
+
return buff;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export async function stickerVid(media, metadata) {
|
|
45
|
+
const wMedia = await videoToWebp(media);
|
|
46
|
+
const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`);
|
|
47
|
+
const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`);
|
|
48
|
+
fs.writeFile(tmpFileIn, wMedia);
|
|
49
|
+
|
|
50
|
+
if (metadata.packname || metadata.author) {
|
|
51
|
+
const img = new webp.Image();
|
|
52
|
+
const json = {
|
|
53
|
+
'sticker-pack-id': 'https://github.com/DikaArdnt/Hisoka-Morou',
|
|
54
|
+
'sticker-pack-name': metadata.packname,
|
|
55
|
+
'sticker-pack-publisher': metadata.author,
|
|
56
|
+
'emojis': metadata.categories ?? ['']
|
|
57
|
+
};
|
|
58
|
+
const 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]);
|
|
59
|
+
const jsonBuff = Buffer.from(JSON.stringify(json), 'utf-8');
|
|
60
|
+
const exif = Buffer.concat([exifAttr, jsonBuff]);
|
|
61
|
+
exif.writeUIntLE(jsonBuff.length, 14, 4);
|
|
62
|
+
await img.load(tmpFileIn);
|
|
63
|
+
fs.unlink(tmpFileIn);
|
|
64
|
+
img.exif = exif;
|
|
65
|
+
await img.save(tmpFileOut);
|
|
66
|
+
return tmpFileOut;
|
|
67
|
+
}
|
|
68
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ryuu-reinzz/haruka-lib",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Library extra for bot WhatsApp",
|
|
5
5
|
"main": "main/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -22,10 +22,7 @@
|
|
|
22
22
|
"fs-extra": "^11.2.0",
|
|
23
23
|
"node-fetch": "^3.3.2",
|
|
24
24
|
"node-webpmux": "^3.2.1",
|
|
25
|
+
"node-fetch": "^2.6.1",
|
|
25
26
|
"sharp": "^0.34.1"
|
|
26
|
-
},
|
|
27
|
-
"devDependencies": {
|
|
28
|
-
"@types/node": "^25.0.3",
|
|
29
|
-
"typescript": "^5.9.3"
|
|
30
27
|
}
|
|
31
28
|
}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { IStickerOptions } from './Types';
|
|
2
|
-
import { StickerTypes } from './internal/Metadata/StickerTypes';
|
|
3
|
-
import { Categories } from '.';
|
|
4
|
-
import { Color } from 'sharp';
|
|
5
|
-
/**
|
|
6
|
-
* Sticker class
|
|
7
|
-
*/
|
|
8
|
-
export declare class Sticker {
|
|
9
|
-
private data;
|
|
10
|
-
metadata: Partial<IStickerOptions>;
|
|
11
|
-
/**
|
|
12
|
-
* Sticker Constructor
|
|
13
|
-
* @param {string|Buffer} [data] - File path, url or Buffer of the image/video to be converted
|
|
14
|
-
* @param {IStickerOptions} [options] - Sticker options
|
|
15
|
-
*/
|
|
16
|
-
constructor(data: string | Buffer, metadata?: Partial<IStickerOptions>);
|
|
17
|
-
private _parse;
|
|
18
|
-
private _getMimeType;
|
|
19
|
-
/**
|
|
20
|
-
* Builds the sticker
|
|
21
|
-
* @returns {Promise<Buffer>} A promise that resolves to the sticker buffer
|
|
22
|
-
* @example
|
|
23
|
-
* const sticker = new Sticker('./image.png')
|
|
24
|
-
* const buffer = sticker.build()
|
|
25
|
-
*/
|
|
26
|
-
build: () => Promise<Buffer>;
|
|
27
|
-
/**
|
|
28
|
-
* Alias for `.build()`
|
|
29
|
-
* @param {string} [type] - How you want your sticker to look like
|
|
30
|
-
* @returns {Promise<Buffer>} A promise that resolves to the sticker buffer
|
|
31
|
-
* @example
|
|
32
|
-
* const sticker = new Sticker('./image.png')
|
|
33
|
-
* const buffer = sticker.build()
|
|
34
|
-
*/
|
|
35
|
-
toBuffer: () => Promise<Buffer>;
|
|
36
|
-
get defaultFilename(): string;
|
|
37
|
-
/**
|
|
38
|
-
* Saves the sticker to a file
|
|
39
|
-
* @param [filename] - Filename to save the sticker to
|
|
40
|
-
* @returns filename
|
|
41
|
-
* @example
|
|
42
|
-
* const sticker = new Sticker('./image.png')
|
|
43
|
-
* sticker.toFile('./image.webp')
|
|
44
|
-
*/
|
|
45
|
-
toFile: (filename?: string) => Promise<string>;
|
|
46
|
-
/**
|
|
47
|
-
* Set the sticker pack title
|
|
48
|
-
* @param pack - Sticker Pack Title
|
|
49
|
-
* @returns {this}
|
|
50
|
-
* @example
|
|
51
|
-
* const sticker = new Sticker('./image.png')
|
|
52
|
-
* sticker.setPack('My Sticker Pack')
|
|
53
|
-
* sticker.build()
|
|
54
|
-
*/
|
|
55
|
-
setPack: (pack: string) => this;
|
|
56
|
-
/**
|
|
57
|
-
* Set the sticker pack author
|
|
58
|
-
* @param author - Sticker Pack Author
|
|
59
|
-
* @returns
|
|
60
|
-
*/
|
|
61
|
-
setAuthor: (author: string) => this;
|
|
62
|
-
/**
|
|
63
|
-
* Set the sticker pack ID
|
|
64
|
-
* @param id - Sticker Pack ID
|
|
65
|
-
* @returns {this}
|
|
66
|
-
* @example
|
|
67
|
-
* const sticker = new Sticker('./image.png')
|
|
68
|
-
* sticker.setID('my-sticker-pack')
|
|
69
|
-
* sticker.build()
|
|
70
|
-
*/
|
|
71
|
-
setID: (id: string) => this;
|
|
72
|
-
/**
|
|
73
|
-
* Set the sticker category
|
|
74
|
-
* @param categories - Sticker Category
|
|
75
|
-
* @returns {this}
|
|
76
|
-
* @example
|
|
77
|
-
* const sticker = new Sticker('./image.png')
|
|
78
|
-
* sticker.setCategories(['🌹'])
|
|
79
|
-
*/
|
|
80
|
-
setCategories: (categories: Categories[]) => this;
|
|
81
|
-
/**
|
|
82
|
-
* Set the sticker type
|
|
83
|
-
* @param {StickerTypes|string}[type] - Sticker Type
|
|
84
|
-
* @returns {this}
|
|
85
|
-
*/
|
|
86
|
-
setType: (type: StickerTypes | string) => this;
|
|
87
|
-
/**
|
|
88
|
-
* Set the sticker quality
|
|
89
|
-
* @param {number}[quality] - Sticker Quality
|
|
90
|
-
* @returns {this}
|
|
91
|
-
*/
|
|
92
|
-
setQuality: (quality: number) => this;
|
|
93
|
-
/**
|
|
94
|
-
* Set the background color for `full` images
|
|
95
|
-
* @param {Color}[background] - Background color
|
|
96
|
-
* @returns {this}
|
|
97
|
-
*/
|
|
98
|
-
setBackground: (background: Color) => this;
|
|
99
|
-
/**
|
|
100
|
-
* @deprecated
|
|
101
|
-
* Use the `Sticker.build()` method instead
|
|
102
|
-
*/
|
|
103
|
-
get: () => Promise<Buffer>;
|
|
104
|
-
/**
|
|
105
|
-
* Get BaileysMD-compatible message object
|
|
106
|
-
* @returns {{ sticker: Buffer }}
|
|
107
|
-
* @example
|
|
108
|
-
* import { create } from '@adiwajshing/baileys-md'
|
|
109
|
-
* const conn = create()
|
|
110
|
-
* ...
|
|
111
|
-
* const sticker = new Sticker('./image.png', { pack: 'My Sticker Pack', author: 'Me' })
|
|
112
|
-
* const message = await sticker.toMessage()
|
|
113
|
-
* conn.sendMessage(jid, message)
|
|
114
|
-
*/
|
|
115
|
-
toMessage: () => Promise<{
|
|
116
|
-
sticker: Buffer;
|
|
117
|
-
}>;
|
|
118
|
-
/**
|
|
119
|
-
* Extracts metadata from a WebP image.
|
|
120
|
-
* @param {Buffer}image - The image buffer to extract metadata from
|
|
121
|
-
*/
|
|
122
|
-
static extractMetadata: (image: Buffer) => Promise<Partial<import("./Types").IRawMetadata>>;
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
*
|
|
126
|
-
* @param {string|Buffer} data - File path, url or Buffer of the image/video to be converted
|
|
127
|
-
* @param {IStickerOptions} [options] - Sticker options
|
|
128
|
-
* @returns {Promise<Buffer>} A promise that resolves to the sticker buffer
|
|
129
|
-
*/
|
|
130
|
-
export declare const createSticker: (...args: ConstructorParameters<typeof Sticker>) => Promise<Buffer>;
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import fs from 'fs-extra';
|
|
2
|
-
import axios from 'axios';
|
|
3
|
-
import Utils, { defaultBg } from './Utils.js';
|
|
4
|
-
import pkg from 'file-type';
|
|
5
|
-
import convert from './internal/convert.js';
|
|
6
|
-
import Exif from './internal/Metadata/Exif.js';
|
|
7
|
-
import { StickerTypes } from './internal/Metadata/StickerTypes.js';
|
|
8
|
-
import { extractMetadata } from './extractMetadata.js';
|
|
9
|
-
/**
|
|
10
|
-
* Sticker class
|
|
11
|
-
*/
|
|
12
|
-
const { fromBuffer } = pkg;
|
|
13
|
-
export class Sticker {
|
|
14
|
-
/**
|
|
15
|
-
* Sticker Constructor
|
|
16
|
-
* @param {string|Buffer} [data] - File path, url or Buffer of the image/video to be converted
|
|
17
|
-
* @param {IStickerOptions} [options] - Sticker options
|
|
18
|
-
*/
|
|
19
|
-
constructor(data, metadata = {}) {
|
|
20
|
-
this.data = data;
|
|
21
|
-
this.metadata = metadata;
|
|
22
|
-
this._parse = async () => Buffer.isBuffer(this.data)
|
|
23
|
-
? this.data
|
|
24
|
-
: this.data.trim().startsWith('<svg')
|
|
25
|
-
? Buffer.from(this.data)
|
|
26
|
-
: (async () => fs.existsSync(this.data)
|
|
27
|
-
? fs.readFile(this.data)
|
|
28
|
-
: axios.get(this.data, { responseType: 'arraybuffer' }).then(({ data }) => data))();
|
|
29
|
-
this._getMimeType = async (data) => {
|
|
30
|
-
const type = await fromBuffer(data);
|
|
31
|
-
if (!type) {
|
|
32
|
-
if (typeof this.data === 'string')
|
|
33
|
-
return 'image/svg+xml';
|
|
34
|
-
throw new Error('Invalid file type');
|
|
35
|
-
}
|
|
36
|
-
return type.mime;
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* Builds the sticker
|
|
40
|
-
* @returns {Promise<Buffer>} A promise that resolves to the sticker buffer
|
|
41
|
-
* @example
|
|
42
|
-
* const sticker = new Sticker('./image.png')
|
|
43
|
-
* const buffer = sticker.build()
|
|
44
|
-
*/
|
|
45
|
-
this.build = async () => {
|
|
46
|
-
const data = await this._parse();
|
|
47
|
-
const mime = await this._getMimeType(data);
|
|
48
|
-
return new Exif(this.metadata).add(await convert(data, mime, this.metadata));
|
|
49
|
-
};
|
|
50
|
-
/**
|
|
51
|
-
* Alias for `.build()`
|
|
52
|
-
* @param {string} [type] - How you want your sticker to look like
|
|
53
|
-
* @returns {Promise<Buffer>} A promise that resolves to the sticker buffer
|
|
54
|
-
* @example
|
|
55
|
-
* const sticker = new Sticker('./image.png')
|
|
56
|
-
* const buffer = sticker.build()
|
|
57
|
-
*/
|
|
58
|
-
this.toBuffer = this.build;
|
|
59
|
-
/**
|
|
60
|
-
* Saves the sticker to a file
|
|
61
|
-
* @param [filename] - Filename to save the sticker to
|
|
62
|
-
* @returns filename
|
|
63
|
-
* @example
|
|
64
|
-
* const sticker = new Sticker('./image.png')
|
|
65
|
-
* sticker.toFile('./image.webp')
|
|
66
|
-
*/
|
|
67
|
-
this.toFile = async (filename = this.defaultFilename) => {
|
|
68
|
-
await fs.writeFile(filename, await this.build());
|
|
69
|
-
return filename;
|
|
70
|
-
};
|
|
71
|
-
/**
|
|
72
|
-
* Set the sticker pack title
|
|
73
|
-
* @param pack - Sticker Pack Title
|
|
74
|
-
* @returns {this}
|
|
75
|
-
* @example
|
|
76
|
-
* const sticker = new Sticker('./image.png')
|
|
77
|
-
* sticker.setPack('My Sticker Pack')
|
|
78
|
-
* sticker.build()
|
|
79
|
-
*/
|
|
80
|
-
this.setPack = (pack) => {
|
|
81
|
-
this.metadata.pack = pack;
|
|
82
|
-
return this;
|
|
83
|
-
};
|
|
84
|
-
/**
|
|
85
|
-
* Set the sticker pack author
|
|
86
|
-
* @param author - Sticker Pack Author
|
|
87
|
-
* @returns
|
|
88
|
-
*/
|
|
89
|
-
this.setAuthor = (author) => {
|
|
90
|
-
this.metadata.author = author;
|
|
91
|
-
return this;
|
|
92
|
-
};
|
|
93
|
-
/**
|
|
94
|
-
* Set the sticker pack ID
|
|
95
|
-
* @param id - Sticker Pack ID
|
|
96
|
-
* @returns {this}
|
|
97
|
-
* @example
|
|
98
|
-
* const sticker = new Sticker('./image.png')
|
|
99
|
-
* sticker.setID('my-sticker-pack')
|
|
100
|
-
* sticker.build()
|
|
101
|
-
*/
|
|
102
|
-
this.setID = (id) => {
|
|
103
|
-
this.metadata.id = id;
|
|
104
|
-
return this;
|
|
105
|
-
};
|
|
106
|
-
/**
|
|
107
|
-
* Set the sticker category
|
|
108
|
-
* @param categories - Sticker Category
|
|
109
|
-
* @returns {this}
|
|
110
|
-
* @example
|
|
111
|
-
* const sticker = new Sticker('./image.png')
|
|
112
|
-
* sticker.setCategories(['🌹'])
|
|
113
|
-
*/
|
|
114
|
-
this.setCategories = (categories) => {
|
|
115
|
-
this.metadata.categories = categories;
|
|
116
|
-
return this;
|
|
117
|
-
};
|
|
118
|
-
/**
|
|
119
|
-
* Set the sticker type
|
|
120
|
-
* @param {StickerTypes|string}[type] - Sticker Type
|
|
121
|
-
* @returns {this}
|
|
122
|
-
*/
|
|
123
|
-
this.setType = (type) => {
|
|
124
|
-
this.metadata.type = type;
|
|
125
|
-
return this;
|
|
126
|
-
};
|
|
127
|
-
/**
|
|
128
|
-
* Set the sticker quality
|
|
129
|
-
* @param {number}[quality] - Sticker Quality
|
|
130
|
-
* @returns {this}
|
|
131
|
-
*/
|
|
132
|
-
this.setQuality = (quality) => {
|
|
133
|
-
this.metadata.quality = quality;
|
|
134
|
-
return this;
|
|
135
|
-
};
|
|
136
|
-
/**
|
|
137
|
-
* Set the background color for `full` images
|
|
138
|
-
* @param {Color}[background] - Background color
|
|
139
|
-
* @returns {this}
|
|
140
|
-
*/
|
|
141
|
-
this.setBackground = (background) => {
|
|
142
|
-
this.metadata.background = background;
|
|
143
|
-
return this;
|
|
144
|
-
};
|
|
145
|
-
/**
|
|
146
|
-
* @deprecated
|
|
147
|
-
* Use the `Sticker.build()` method instead
|
|
148
|
-
*/
|
|
149
|
-
this.get = this.build;
|
|
150
|
-
/**
|
|
151
|
-
* Get BaileysMD-compatible message object
|
|
152
|
-
* @returns {{ sticker: Buffer }}
|
|
153
|
-
* @example
|
|
154
|
-
* import { create } from '@adiwajshing/baileys-md'
|
|
155
|
-
* const conn = create()
|
|
156
|
-
* ...
|
|
157
|
-
* const sticker = new Sticker('./image.png', { pack: 'My Sticker Pack', author: 'Me' })
|
|
158
|
-
* const message = await sticker.toMessage()
|
|
159
|
-
* conn.sendMessage(jid, message)
|
|
160
|
-
*/
|
|
161
|
-
this.toMessage = async () => ({ sticker: await this.build() });
|
|
162
|
-
this.metadata.author = this.metadata.author ?? '';
|
|
163
|
-
this.metadata.pack = this.metadata.pack ?? '';
|
|
164
|
-
this.metadata.id = this.metadata.id ?? Utils.generateStickerID();
|
|
165
|
-
this.metadata.quality = this.metadata.quality ?? 100;
|
|
166
|
-
this.metadata.type = Object.values(StickerTypes).includes(this.metadata.type)
|
|
167
|
-
? this.metadata.type
|
|
168
|
-
: StickerTypes.DEFAULT;
|
|
169
|
-
this.metadata.background = this.metadata.background ?? defaultBg;
|
|
170
|
-
}
|
|
171
|
-
get defaultFilename() {
|
|
172
|
-
return `./${this.metadata.pack}-${this.metadata.author}.webp`;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Extracts metadata from a WebP image.
|
|
177
|
-
* @param {Buffer}image - The image buffer to extract metadata from
|
|
178
|
-
*/
|
|
179
|
-
Sticker.extractMetadata = extractMetadata;
|
|
180
|
-
/**
|
|
181
|
-
*
|
|
182
|
-
* @param {string|Buffer} data - File path, url or Buffer of the image/video to be converted
|
|
183
|
-
* @param {IStickerOptions} [options] - Sticker options
|
|
184
|
-
* @returns {Promise<Buffer>} A promise that resolves to the sticker buffer
|
|
185
|
-
*/
|
|
186
|
-
export const createSticker = async (...args) => {
|
|
187
|
-
return new Sticker(...args).build();
|
|
188
|
-
};
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import sharp, { Color } from 'sharp';
|
|
2
|
-
import { StickerTypes } from './internal/Metadata/StickerTypes';
|
|
3
|
-
/** Sticker metadata config */
|
|
4
|
-
export interface IStickerConfig {
|
|
5
|
-
/** Sticker Pack title*/
|
|
6
|
-
pack?: string;
|
|
7
|
-
/** Sticker Pack Author*/
|
|
8
|
-
author?: string;
|
|
9
|
-
/** Sticker Pack ID*/
|
|
10
|
-
id?: string;
|
|
11
|
-
/** Sticker Category*/
|
|
12
|
-
categories?: Categories[];
|
|
13
|
-
}
|
|
14
|
-
export interface IStickerOptions extends IStickerConfig {
|
|
15
|
-
/** How you want your sticker to look like
|
|
16
|
-
* Can be crop or full. Defaults to 'default' (no changes)
|
|
17
|
-
*/
|
|
18
|
-
type?: StickerTypes | string;
|
|
19
|
-
/**
|
|
20
|
-
* Quality of the output webp image. Must be an integer from 0 to 100 (defaults to 100
|
|
21
|
-
*/
|
|
22
|
-
quality?: sharp.WebpOptions['quality'];
|
|
23
|
-
/**
|
|
24
|
-
* Background Color of the sticker (only for type full)
|
|
25
|
-
*/
|
|
26
|
-
background?: Color;
|
|
27
|
-
}
|
|
28
|
-
export interface IRawMetadata {
|
|
29
|
-
emojis: string[];
|
|
30
|
-
'sticker-pack-id': string;
|
|
31
|
-
'sticker-pack-name': string;
|
|
32
|
-
'sticker-pack-publisher': string;
|
|
33
|
-
}
|
|
34
|
-
export type Metadata = IStickerConfig | IStickerOptions;
|
|
35
|
-
type Love = '❤' | '😍' | '😘' | '💕' | '😻' | '💑' | '👩❤👩' | '👨❤👨' | '💏' | '👩❤💋👩' | '👨❤💋👨' | '🧡' | '💛' | '💚' | '💙' | '💜' | '🖤' | '💔' | '❣' | '💞' | '💓' | '💗' | '💖' | '💘' | '💝' | '💟' | '♥' | '💌' | '💋' | '👩❤️💋👩' | '👨❤️💋👨' | '👩❤️👨' | '👩❤️👩' | '👨❤️👨' | '👩❤️💋👨' | '👬' | '👭' | '👫' | '🥰' | '😚' | '😙' | '👄' | '🌹' | '😽' | '❣️' | '❤️';
|
|
36
|
-
type Happy = '😀' | '😃' | '😄' | '😁' | '😆' | '😅' | '😂' | '🤣' | '🙂' | '😛' | '😝' | '😜' | '🤪' | '🤗' | '😺' | '😸' | '😹' | '☺' | '😌' | '😉' | '🤗' | '😊';
|
|
37
|
-
type Sad = '☹' | '😣' | '😖' | '😫' | '😩' | '😢' | '😭' | '😞' | '😔' | '😟' | '😕' | '😤' | '😠' | '😥' | '😰' | '😨' | '😿' | '😾' | '😓' | '🙍♂' | '🙍♀' | '💔' | '🙁' | '🥺' | '🤕' | '☔️' | '⛈' | '🌩' | '🌧';
|
|
38
|
-
type Angry = '😯' | '😦' | '😧' | '😮' | '😲' | '🙀' | '😱' | '🤯' | '😳' | '❗' | '❕' | '🤬' | '😡' | '😠' | '🙄' | '👿' | '😾' | '😤' | '💢' | '👺' | '🗯️' | '😒' | '🥵';
|
|
39
|
-
type Greet = '👋';
|
|
40
|
-
type Celebrate = '🎊' | '🎉' | '🎁' | '🎈' | '👯♂️' | '👯' | '👯♀️' | '💃' | '🕺' | '🔥' | '⭐️' | '✨' | '💫' | '🎇' | '🎆' | '🍻' | '🥂' | '🍾' | '🎂' | '🍰';
|
|
41
|
-
/** Sticker Category. Learn More: https://github.com/WhatsApp/stickers/wiki/Tag-your-stickers-with-Emojis*/
|
|
42
|
-
export type Categories = Love | Happy | Sad | Angry | Greet | Celebrate;
|
|
43
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import webp from 'node-webpmux';
|
|
2
|
-
/**
|
|
3
|
-
* Extracts metadata from a WebP image.
|
|
4
|
-
* @param {Buffer}image - The image buffer to extract metadata from
|
|
5
|
-
*/
|
|
6
|
-
const WebP = webp;
|
|
7
|
-
export const extractMetadata = async (image) => {
|
|
8
|
-
const img = new WebP();
|
|
9
|
-
await img.load(image);
|
|
10
|
-
const exif = img.exif?.toString('utf-8') ?? '{}';
|
|
11
|
-
return JSON.parse(exif.substring(exif.indexOf('{'), exif.lastIndexOf('}') + 1) ?? '{}');
|
|
12
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { Sticker } from './Sticker';
|
|
2
|
-
export * from './Sticker';
|
|
3
|
-
export * from './extractMetadata';
|
|
4
|
-
export * from './Types';
|
|
5
|
-
export { default as StickerMetadata } from './internal/Metadata/StickerMetadata';
|
|
6
|
-
export { default as Exif } from './internal/Metadata/Exif';
|
|
7
|
-
export * from './internal/Metadata/StickerTypes';
|
|
8
|
-
export default Sticker;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { Sticker } from './Sticker.js';
|
|
2
|
-
export * from './Sticker.js';
|
|
3
|
-
export * from './extractMetadata.js';
|
|
4
|
-
export * from './Types.js';
|
|
5
|
-
export { default as StickerMetadata } from './internal/Metadata/StickerMetadata.js';
|
|
6
|
-
export { default as Exif } from './internal/Metadata/Exif.js';
|
|
7
|
-
export * from './internal/Metadata/StickerTypes.js';
|
|
8
|
-
export default Sticker;
|