This commit is contained in:
Ross Shannon 2026-01-30 17:05:38 +05:30 committed by GitHub
commit 4f383b6f1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 62 additions and 1 deletions

View File

@ -194,6 +194,7 @@
"long": "5.3.2", "long": "5.3.2",
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"node-edge-tts": "^1.2.9", "node-edge-tts": "^1.2.9",
"node-emoji": "^2.2.0",
"osc-progress": "^0.3.0", "osc-progress": "^0.3.0",
"pdfjs-dist": "^5.4.530", "pdfjs-dist": "^5.4.530",
"playwright-core": "1.58.0", "playwright-core": "1.58.0",

46
pnpm-lock.yaml generated
View File

@ -133,6 +133,9 @@ importers:
node-edge-tts: node-edge-tts:
specifier: ^1.2.9 specifier: ^1.2.9
version: 1.2.9 version: 1.2.9
node-emoji:
specifier: ^2.2.0
version: 2.2.0
osc-progress: osc-progress:
specifier: ^0.3.0 specifier: ^0.3.0
version: 0.3.0 version: 0.3.0
@ -2382,6 +2385,10 @@ packages:
'@sinclair/typebox@0.34.47': '@sinclair/typebox@0.34.47':
resolution: {integrity: sha512-ZGIBQ+XDvO5JQku9wmwtabcVTHJsgSWAHYtVuM9pBNNR5E88v6Jcj/llpmsjivig5X8A8HHOb4/mbEKPS5EvAw==} resolution: {integrity: sha512-ZGIBQ+XDvO5JQku9wmwtabcVTHJsgSWAHYtVuM9pBNNR5E88v6Jcj/llpmsjivig5X8A8HHOb4/mbEKPS5EvAw==}
'@sindresorhus/is@4.6.0':
resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==}
engines: {node: '>=10'}
'@slack/bolt@4.6.0': '@slack/bolt@4.6.0':
resolution: {integrity: sha512-xPgfUs2+OXSugz54Ky07pA890+Qydk22SYToi8uGpXeHSt1JWwFJkRyd/9Vlg5I1AdfdpGXExDpwnbuN9Q/2dQ==} resolution: {integrity: sha512-xPgfUs2+OXSugz54Ky07pA890+Qydk22SYToi8uGpXeHSt1JWwFJkRyd/9Vlg5I1AdfdpGXExDpwnbuN9Q/2dQ==}
engines: {node: '>=18', npm: '>=8.6.0'} engines: {node: '>=18', npm: '>=8.6.0'}
@ -3190,6 +3197,10 @@ packages:
resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
char-regex@1.0.2:
resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==}
engines: {node: '>=10'}
chmodrp@1.0.2: chmodrp@1.0.2:
resolution: {integrity: sha512-TdngOlFV1FLTzU0o1w8MB6/BFywhtLC0SzRTGJU7T9lmdjlCWeMRt1iVo0Ki+ldwNk0BqNiKoc8xpLZEQ8mY1w==} resolution: {integrity: sha512-TdngOlFV1FLTzU0o1w8MB6/BFywhtLC0SzRTGJU7T9lmdjlCWeMRt1iVo0Ki+ldwNk0BqNiKoc8xpLZEQ8mY1w==}
@ -3459,6 +3470,9 @@ packages:
emoji-regex@9.2.2: emoji-regex@9.2.2:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
emojilib@2.4.0:
resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==}
encodeurl@2.0.0: encodeurl@2.0.0:
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
@ -4419,6 +4433,10 @@ packages:
resolution: {integrity: sha512-fvfW1dUgJdZAdTniC6MzLTMwnNUFKGKaUdRJ1OsveOYlfnPUETBU973CG89565txvbBowCQ4Czdeu3qSX8bNOg==} resolution: {integrity: sha512-fvfW1dUgJdZAdTniC6MzLTMwnNUFKGKaUdRJ1OsveOYlfnPUETBU973CG89565txvbBowCQ4Czdeu3qSX8bNOg==}
hasBin: true hasBin: true
node-emoji@2.2.0:
resolution: {integrity: sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==}
engines: {node: '>=18'}
node-fetch@2.7.0: node-fetch@2.7.0:
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
engines: {node: 4.x || >=6.0.0} engines: {node: 4.x || >=6.0.0}
@ -5043,6 +5061,10 @@ packages:
sisteransi@1.0.5: sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
skin-tone@2.0.0:
resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==}
engines: {node: '>=8'}
sleep-promise@9.1.0: sleep-promise@9.1.0:
resolution: {integrity: sha512-UHYzVpz9Xn8b+jikYSD6bqvf754xL2uBUzDFwiU6NcdZeifPr6UfgU43xpkPu67VMS88+TI2PSI7Eohgqf2fKA==} resolution: {integrity: sha512-UHYzVpz9Xn8b+jikYSD6bqvf754xL2uBUzDFwiU6NcdZeifPr6UfgU43xpkPu67VMS88+TI2PSI7Eohgqf2fKA==}
@ -5194,6 +5216,7 @@ packages:
tar@7.5.4: tar@7.5.4:
resolution: {integrity: sha512-AN04xbWGrSTDmVwlI4/GTlIIwMFk/XEv7uL8aa57zuvRy6s4hdBed+lVq2fAZ89XDa7Us3ANXcE3Tvqvja1kTA==} resolution: {integrity: sha512-AN04xbWGrSTDmVwlI4/GTlIIwMFk/XEv7uL8aa57zuvRy6s4hdBed+lVq2fAZ89XDa7Us3ANXcE3Tvqvja1kTA==}
engines: {node: '>=18'} engines: {node: '>=18'}
deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exhorbitant rates) by contacting i@izs.me
thenify-all@1.6.0: thenify-all@1.6.0:
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
@ -5323,6 +5346,10 @@ packages:
resolution: {integrity: sha512-Heho1hJD81YChi+uS2RkSjcVO+EQLmLSyUlHyp7Y/wFbxQaGb4WXVKD073JytrjXJVkSZVzoE2MCSOKugFGtOQ==} resolution: {integrity: sha512-Heho1hJD81YChi+uS2RkSjcVO+EQLmLSyUlHyp7Y/wFbxQaGb4WXVKD073JytrjXJVkSZVzoE2MCSOKugFGtOQ==}
engines: {node: '>=20.18.1'} engines: {node: '>=20.18.1'}
unicode-emoji-modifier-base@1.0.0:
resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==}
engines: {node: '>=4'}
unicode-properties@1.4.1: unicode-properties@1.4.1:
resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==} resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==}
@ -7918,6 +7945,8 @@ snapshots:
'@sinclair/typebox@0.34.47': {} '@sinclair/typebox@0.34.47': {}
'@sindresorhus/is@4.6.0': {}
'@slack/bolt@4.6.0(@types/express@5.0.6)': '@slack/bolt@4.6.0(@types/express@5.0.6)':
dependencies: dependencies:
'@slack/logger': 4.0.0 '@slack/logger': 4.0.0
@ -9063,6 +9092,8 @@ snapshots:
chalk@5.6.2: {} chalk@5.6.2: {}
char-regex@1.0.2: {}
chmodrp@1.0.2: chmodrp@1.0.2:
optional: true optional: true
@ -9328,6 +9359,8 @@ snapshots:
emoji-regex@9.2.2: {} emoji-regex@9.2.2: {}
emojilib@2.4.0: {}
encodeurl@2.0.0: {} encodeurl@2.0.0: {}
entities@4.5.0: {} entities@4.5.0: {}
@ -10404,6 +10437,13 @@ snapshots:
- supports-color - supports-color
- utf-8-validate - utf-8-validate
node-emoji@2.2.0:
dependencies:
'@sindresorhus/is': 4.6.0
char-regex: 1.0.2
emojilib: 2.4.0
skin-tone: 2.0.0
node-fetch@2.7.0: node-fetch@2.7.0:
dependencies: dependencies:
whatwg-url: 5.0.0 whatwg-url: 5.0.0
@ -11245,6 +11285,10 @@ snapshots:
sisteransi@1.0.5: {} sisteransi@1.0.5: {}
skin-tone@2.0.0:
dependencies:
unicode-emoji-modifier-base: 1.0.0
sleep-promise@9.1.0: sleep-promise@9.1.0:
optional: true optional: true
@ -11506,6 +11550,8 @@ snapshots:
undici@7.19.0: {} undici@7.19.0: {}
unicode-emoji-modifier-base@1.0.0: {}
unicode-properties@1.4.1: unicode-properties@1.4.1:
dependencies: dependencies:
base64-js: 1.5.1 base64-js: 1.5.1

View File

@ -1,4 +1,5 @@
import type { WebClient } from "@slack/web-api"; import type { WebClient } from "@slack/web-api";
import { which as emojiWhich } from "node-emoji";
import { loadConfig } from "../config/config.js"; import { loadConfig } from "../config/config.js";
import { logVerbose } from "../globals.js"; import { logVerbose } from "../globals.js";
@ -47,11 +48,24 @@ function resolveToken(explicit?: string, accountId?: string) {
return token; return token;
} }
/**
* Normalize emoji for Slack reactions.
* Converts Unicode emojis to Slack shortcodes (👀 eyes).
* Strips colons from already-formatted shortcodes (:eyes: eyes).
*/
function normalizeEmoji(raw: string) { function normalizeEmoji(raw: string) {
const trimmed = raw.trim(); const trimmed = raw.trim();
if (!trimmed) { if (!trimmed) {
throw new Error("Emoji is required for Slack reactions"); throw new Error("Emoji is required for Slack reactions");
} }
// Try Unicode → shortcode conversion first
const shortcode = emojiWhich(trimmed);
if (shortcode) {
return shortcode;
}
// Fall back to stripping colons (for already-formatted shortcodes)
return trimmed.replace(/^:+|:+$/g, ""); return trimmed.replace(/^:+|:+$/g, "");
} }

View File

@ -107,7 +107,7 @@ describe("monitorSlackProvider tool results", () => {
expect(reactMock).toHaveBeenCalledWith({ expect(reactMock).toHaveBeenCalledWith({
channel: "C1", channel: "C1",
timestamp: "456", timestamp: "456",
name: "👀", name: "eyes",
}); });
}); });