swan-api 1.1.0 → 1.1.2

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.
Files changed (3) hide show
  1. package/Socket.js +4 -1
  2. package/Sticker.js +32 -11
  3. package/package.json +1 -1
package/Socket.js CHANGED
@@ -83,10 +83,13 @@ export default class Socket extends EventEmitter {
83
83
  if (connection == "close"){
84
84
  const shouldReconnect = lastDisconnect?.error?.output?.statusCode
85
85
  !== DisconnectReason.loggedOut;
86
- if (shouldReconnect)
86
+ if (shouldReconnect){
87
+ this.socket.ev.removeAllListeners()
87
88
  await this.connect()
89
+ }
88
90
  } else if (connection == 'open'){
89
91
  socketReady = true
92
+ this.groupMetadata = this.socket.groupMetadata;
90
93
  this.userId = this.socket.user.id;
91
94
  this.emit('ready');
92
95
  }
package/Sticker.js CHANGED
@@ -1,7 +1,11 @@
1
1
  import sharp from "sharp";
2
+ import { fileTypeFromBuffer } from "file-type";
3
+
4
+ // imports for animated sticker only
2
5
  import ffmpegPath from "ffmpeg-static";
3
6
  import { execa } from "execa";
4
- import { fileTypeFromBuffer } from "file-type";
7
+ import {tmpdir} from 'node:os'
8
+ import fs from 'node:fs/promises'
5
9
 
6
10
  export default async function Sticker(buffer, opts = {}) {
7
11
  const author = opts.stickerAuthor ? opts.stickerAuthor : "";
@@ -13,7 +17,8 @@ export default async function Sticker(buffer, opts = {}) {
13
17
  if (!info)
14
18
  throw Error("Unknown file type");
15
19
 
16
- if (info.mime.startsWith("video/"))
20
+ const isAnimated = info.mime.startsWith("video/");
21
+ if (isAnimated)
17
22
  buffer = await convertVideo(buffer);
18
23
  else if (!info.mime.startsWith("image/"))
19
24
  throw Error(`Unsupported media type: ${info.mime}`);
@@ -21,7 +26,7 @@ export default async function Sticker(buffer, opts = {}) {
21
26
  const fit = type === "full" ? "contain" :
22
27
  type === "fill" ? "fill" : "cover"; // crop, circle, rounded
23
28
 
24
- let image = sharp(buffer).resize(512, 512, {fit,
29
+ let image = sharp(buffer, {animated: isAnimated}).resize(512, 512, {fit,
25
30
  background: { r: 0, g: 0, b: 0, alpha: 0 }}).ensureAlpha();
26
31
 
27
32
  if (type === "circle")
@@ -39,22 +44,38 @@ export default async function Sticker(buffer, opts = {}) {
39
44
  rx="64" ry="64" fill="white"/></svg>`),
40
45
  }]);
41
46
 
42
- const webp = await image.webp({ quality }).toBuffer();
47
+ const webp = await image.webp({ quality, loop:0 }).toBuffer();
43
48
  return addExif(webp, author, pack)
44
49
  }
45
50
 
46
51
  // for animated stickers
47
52
  async function convertVideo(buffer) {
48
- const { stdout } = await execa(ffmpegPath, [
49
- "-i", "pipe:0", "-vcodec", "libwebp", "-vf",
50
- "scale=512:512:force_original_aspect_ratio=decrease",
51
- "-loop", "0", "-an", "-f", "webp", "pipe:1"
52
- ], { input: buffer, encoding: null });
53
+ const inFile = `${tmpdir()}/tmp-input.webp`
54
+ const outFile = `${tmpdir()}/tmp-output.webp`
55
+
56
+ try {
57
+ await fs.writeFile(inFile, buffer);
58
+
59
+ const { stdout } = await execa(ffmpegPath, [
60
+ "-y", "-i", inFile, "-t", "10", "-vcodec", "libwebp", "-vf",
61
+ "scale=512:512:force_original_aspect_ratio=decrease,fps=15",
62
+ "-loop", "0", "-an", "-compression_level", "6", "-f", "webp", outFile
63
+ ], { timeout: 30000 });
64
+
65
+
66
+ const result = await fs.readFile(outFile);
67
+ if (!result.length)
68
+ throw new Error("ffmpeg produced an empty file");
69
+
70
+ return result;
71
+ } finally {
72
+ await fs.unlink(inFile).catch(() => {});
73
+ await fs.unlink(outFile).catch(() => {});
74
+ }
53
75
 
54
- return stdout;
55
76
  }
56
77
 
57
- // Add metadata
78
+ // Add metadata: Sticker Author and Pack
58
79
  function addExif(webp, author, pack) {
59
80
  const json = Buffer.from(JSON.stringify({
60
81
  "sticker-pack-id": "com.swan.sticker",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swan-api",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Simple WhatsApp API for Node",
5
5
  "keywords": [
6
6
  "whatsapp",