eniac-slack 0.1.16 → 0.1.18
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/CHANGELOG.md +10 -0
- package/dist/handlers/mention.js.map +1 -1
- package/dist/handlers/thread.js.map +1 -1
- package/dist/utils/slack-files.d.ts.map +1 -1
- package/dist/utils/slack-files.js +131 -52
- package/dist/utils/slack-files.js.map +1 -1
- package/package.json +1 -1
- package/src/handlers/mention.ts +1 -1
- package/src/handlers/thread.ts +1 -1
- package/src/utils/slack-files.ts +131 -57
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.18] - 2026-03-12
|
|
4
|
+
|
|
5
|
+
- fix(slack): 이미지 다운로드 검증 강화 - magic bytes 확인 (#27)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## [0.1.17] - 2026-03-12
|
|
9
|
+
|
|
10
|
+
- fix(slack): 다중 다운로드 방식 + files.info + thumbnail fallback (#26)
|
|
11
|
+
|
|
12
|
+
|
|
3
13
|
## [0.1.16] - 2026-03-12
|
|
4
14
|
|
|
5
15
|
- fix(slack): Slack 파일 다운로드 인증 실패 - redirect 수동 처리 (#25)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mention.js","sourceRoot":"","sources":["../../src/handlers/mention.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAmB,MAAM,mBAAmB,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACzG,OAAO,EAAE,cAAc,EAAE,eAAe,EAAoB,MAAM,oBAAoB,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAuB,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAa7B,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAA8B,CAAC;AAElE,IAAI,gBAAgB,GAAG,CAAC,CAAC;AAEzB,MAAM,UAAU,qBAAqB,CACnC,SAAiB;IAEjB,OAAO,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,SAAiB;IACxD,mBAAmB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACxC,CAAC;AAED,IAAI,YAAoB,CAAC;AAEzB,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,YAAY,GAAG,GAAG,CAAC;AACrB,CAAC;AAED,SAAS,eAAe;IACtB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAiE;IAEjE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC/C,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,IAAI,SAAS,CAAC;IAC7C,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,CAAC,CAAC,CAAE,
|
|
1
|
+
{"version":3,"file":"mention.js","sourceRoot":"","sources":["../../src/handlers/mention.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread.js","sourceRoot":"","sources":["../../src/handlers/thread.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAA6D;IAE7D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAExC,uEAAuE;IACvE,+EAA+E;IAC/E,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;IAChD,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACvE,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC;IACxC,MAAM,QAAQ,GAAG,WAAW,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,MAAM,KAAK,GAAG,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,MAAM,MAAM,GAAG,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,mCAAmC,OAAO,eAAe,QAAQ,IAAI,MAAM,YAAY,KAAK,IAAI,MAAM,UAAU,MAAM,IAAI,MAAM,EAAE,CAAC,CAAC;IAEhJ,sBAAsB;IACtB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IAED,sCAAsC;IACtC,IAAI,KAAK,IAAI,MAAM,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,CAAC,CAAC,CAAE,
|
|
1
|
+
{"version":3,"file":"thread.js","sourceRoot":"","sources":["../../src/handlers/thread.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack-files.d.ts","sourceRoot":"","sources":["../../src/utils/slack-files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,YAAY,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;CACpE;
|
|
1
|
+
{"version":3,"file":"slack-files.d.ts","sourceRoot":"","sources":["../../src/utils/slack-files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,YAAY,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;CACpE;AA4JD;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,KAAK,CAAC;IACX,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC,GACD,OAAO,CAAC,cAAc,EAAE,CAAC,CAmE3B"}
|
|
@@ -6,9 +6,6 @@ const SUPPORTED_TYPES = new Set([
|
|
|
6
6
|
"image/webp",
|
|
7
7
|
]);
|
|
8
8
|
const MAX_IMAGE_DIMENSION = 1568; // Claude API recommended max
|
|
9
|
-
/**
|
|
10
|
-
* Detect actual image format from magic bytes.
|
|
11
|
-
*/
|
|
12
9
|
function detectImageFormat(buf) {
|
|
13
10
|
if (buf.length < 12)
|
|
14
11
|
return null;
|
|
@@ -23,43 +20,137 @@ function detectImageFormat(buf) {
|
|
|
23
20
|
return "image/webp";
|
|
24
21
|
return null;
|
|
25
22
|
}
|
|
23
|
+
function isHtml(buf) {
|
|
24
|
+
const head = buf.subarray(0, 50).toString("utf8");
|
|
25
|
+
return head.includes("<!DOCTYPE") || head.includes("<html") || head.includes("<HTML");
|
|
26
|
+
}
|
|
27
|
+
/** Check if buffer looks like actual image data (magic bytes or minimum size) */
|
|
28
|
+
function looksLikeImage(buf) {
|
|
29
|
+
if (buf.length < 100)
|
|
30
|
+
return false; // Too small to be a real image
|
|
31
|
+
if (isHtml(buf))
|
|
32
|
+
return false;
|
|
33
|
+
return detectImageFormat(buf) !== null;
|
|
34
|
+
}
|
|
26
35
|
/**
|
|
27
|
-
*
|
|
28
|
-
* Slack's file URLs
|
|
36
|
+
* Try multiple methods to download a file from Slack.
|
|
37
|
+
* Slack's file URLs may require different auth approaches depending on workspace settings.
|
|
29
38
|
*/
|
|
30
|
-
async function fetchSlackFile(url, token) {
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
async function fetchSlackFile(url, token, client, fileId) {
|
|
40
|
+
// Method 1: Bearer header with manual redirect
|
|
41
|
+
console.log(`[slack-files] method 1: Bearer header + manual redirect`);
|
|
42
|
+
try {
|
|
43
|
+
const resp = await fetch(url, {
|
|
44
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
45
|
+
redirect: "manual",
|
|
46
|
+
});
|
|
47
|
+
console.log(`[slack-files] status=${resp.status}, content-type=${resp.headers.get("content-type")}, location=${resp.headers.get("location")?.substring(0, 100) ?? "none"}`);
|
|
48
|
+
if (resp.status >= 300 && resp.status < 400) {
|
|
49
|
+
const location = resp.headers.get("location");
|
|
50
|
+
if (location) {
|
|
51
|
+
console.log(`[slack-files] following redirect with Bearer...`);
|
|
52
|
+
const resp2 = await fetch(location, {
|
|
53
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
54
|
+
});
|
|
55
|
+
const buf = Buffer.from(await resp2.arrayBuffer());
|
|
56
|
+
console.log(`[slack-files] redirect result: status=${resp2.status}, bytes=${buf.length}, isHtml=${isHtml(buf)}`);
|
|
57
|
+
if (looksLikeImage(buf))
|
|
58
|
+
return buf;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if (resp.ok) {
|
|
62
|
+
const buf = Buffer.from(await resp.arrayBuffer());
|
|
63
|
+
console.log(`[slack-files] direct result: bytes=${buf.length}, isHtml=${isHtml(buf)}`);
|
|
64
|
+
if (looksLikeImage(buf))
|
|
65
|
+
return buf;
|
|
48
66
|
}
|
|
49
67
|
}
|
|
50
|
-
|
|
51
|
-
|
|
68
|
+
catch (err) {
|
|
69
|
+
console.warn(`[slack-files] method 1 error:`, err);
|
|
70
|
+
}
|
|
71
|
+
// Method 2: Token as query parameter
|
|
72
|
+
console.log(`[slack-files] method 2: token as query param`);
|
|
73
|
+
try {
|
|
74
|
+
const urlWithToken = new URL(url);
|
|
75
|
+
urlWithToken.searchParams.set("t", token);
|
|
76
|
+
const resp = await fetch(urlWithToken.toString());
|
|
52
77
|
const buf = Buffer.from(await resp.arrayBuffer());
|
|
53
|
-
|
|
78
|
+
console.log(`[slack-files] status=${resp.status}, bytes=${buf.length}, isHtml=${isHtml(buf)}`);
|
|
79
|
+
if (looksLikeImage(buf))
|
|
80
|
+
return buf;
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
console.warn(`[slack-files] method 2 error:`, err);
|
|
54
84
|
}
|
|
55
|
-
//
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
85
|
+
// Method 3: Use files.info API to get fresh URLs
|
|
86
|
+
if (fileId) {
|
|
87
|
+
console.log(`[slack-files] method 3: files.info API for file ${fileId}`);
|
|
88
|
+
try {
|
|
89
|
+
const info = await client.files.info({ file: fileId });
|
|
90
|
+
const freshUrl = info.file?.url_private_download ?? info.file?.url_private;
|
|
91
|
+
console.log(`[slack-files] files.info url_private_download=${info.file?.url_private_download?.substring(0, 80)}`);
|
|
92
|
+
console.log(`[slack-files] files.info url_private=${info.file?.url_private?.substring(0, 80)}`);
|
|
93
|
+
// Try thumb URLs as fallback (these might use different CDN)
|
|
94
|
+
const thumbKeys = ["thumb_1024", "thumb_720", "thumb_480", "thumb_360"];
|
|
95
|
+
for (const key of thumbKeys) {
|
|
96
|
+
const thumbUrl = info.file?.[key];
|
|
97
|
+
if (thumbUrl) {
|
|
98
|
+
console.log(`[slack-files] found ${key}: ${thumbUrl.substring(0, 80)}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (freshUrl && freshUrl !== url) {
|
|
102
|
+
console.log(`[slack-files] trying fresh URL with Bearer...`);
|
|
103
|
+
const resp = await fetch(freshUrl, {
|
|
104
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
105
|
+
});
|
|
106
|
+
const buf = Buffer.from(await resp.arrayBuffer());
|
|
107
|
+
console.log(`[slack-files] fresh URL result: status=${resp.status}, bytes=${buf.length}, isHtml=${isHtml(buf)}`);
|
|
108
|
+
if (looksLikeImage(buf))
|
|
109
|
+
return buf;
|
|
110
|
+
}
|
|
111
|
+
// Try thumbnail URLs (often hosted on Slack CDN with different auth)
|
|
112
|
+
for (const key of thumbKeys) {
|
|
113
|
+
const thumbUrl = info.file?.[key];
|
|
114
|
+
if (thumbUrl) {
|
|
115
|
+
console.log(`[slack-files] trying ${key} URL with Bearer...`);
|
|
116
|
+
try {
|
|
117
|
+
const resp = await fetch(thumbUrl, {
|
|
118
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
119
|
+
});
|
|
120
|
+
const buf = Buffer.from(await resp.arrayBuffer());
|
|
121
|
+
console.log(`[slack-files] ${key} result: status=${resp.status}, bytes=${buf.length}, isHtml=${isHtml(buf)}`);
|
|
122
|
+
if (looksLikeImage(buf))
|
|
123
|
+
return buf;
|
|
124
|
+
}
|
|
125
|
+
catch (thumbErr) {
|
|
126
|
+
console.warn(`[slack-files] ${key} error:`, thumbErr);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
console.warn(`[slack-files] method 3 error:`, err);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Method 4: Try url_private (view URL, not download URL)
|
|
136
|
+
const viewUrl = url.replace("/download/", "/");
|
|
137
|
+
if (viewUrl !== url) {
|
|
138
|
+
console.log(`[slack-files] method 4: url_private (view URL) with Bearer`);
|
|
139
|
+
try {
|
|
140
|
+
const resp = await fetch(viewUrl, {
|
|
141
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
142
|
+
});
|
|
143
|
+
const buf = Buffer.from(await resp.arrayBuffer());
|
|
144
|
+
console.log(`[slack-files] status=${resp.status}, bytes=${buf.length}, isHtml=${isHtml(buf)}`);
|
|
145
|
+
if (looksLikeImage(buf))
|
|
146
|
+
return buf;
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
console.warn(`[slack-files] method 4 error:`, err);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
console.warn(`[slack-files] all download methods failed for ${url}`);
|
|
153
|
+
return null;
|
|
63
154
|
}
|
|
64
155
|
/**
|
|
65
156
|
* Download image files from a Slack message's `files` array.
|
|
@@ -75,6 +166,7 @@ export async function downloadSlackImages(client, files) {
|
|
|
75
166
|
for (const file of files) {
|
|
76
167
|
const mime = file.mimetype;
|
|
77
168
|
console.log(`[slack-files] processing file: id=${file.id}, name=${file.name}, filetype=${file.filetype}, mimetype=${mime}, size=${file.size}`);
|
|
169
|
+
console.log(`[slack-files] file URLs: url_private_download=${file.url_private_download}, url_private=${file.url_private}`);
|
|
78
170
|
if (!mime || !SUPPORTED_TYPES.has(mime)) {
|
|
79
171
|
console.log(`[slack-files] skipping unsupported mime: ${mime}`);
|
|
80
172
|
continue;
|
|
@@ -84,26 +176,14 @@ export async function downloadSlackImages(client, files) {
|
|
|
84
176
|
console.warn(`[slack-files] no download URL for file ${file.id}`);
|
|
85
177
|
continue;
|
|
86
178
|
}
|
|
87
|
-
console.log(`[slack-files] download URL: ${url}`);
|
|
88
179
|
try {
|
|
89
|
-
const
|
|
90
|
-
if (!
|
|
91
|
-
console.warn(`[slack-files] download failed: status=${status}`);
|
|
180
|
+
const buf = await fetchSlackFile(url, token, client, file.id);
|
|
181
|
+
if (!buf)
|
|
92
182
|
continue;
|
|
93
|
-
}
|
|
94
183
|
const hexDump = buf.subarray(0, 16).toString("hex").match(/../g)?.join(" ") ?? "";
|
|
95
184
|
const detectedFormat = detectImageFormat(buf);
|
|
96
|
-
console.log(`[slack-files] downloaded ${buf.length} bytes,
|
|
97
|
-
|
|
98
|
-
console.log(`[slack-files] declared mime=${mime}, detected format=${detectedFormat}`);
|
|
99
|
-
// If the data looks like HTML (Slack error/login page), log and skip
|
|
100
|
-
const head = buf.subarray(0, 50).toString("utf8");
|
|
101
|
-
if (head.includes("<!DOCTYPE") || head.includes("<html")) {
|
|
102
|
-
const preview = buf.subarray(0, 300).toString("utf8");
|
|
103
|
-
console.warn(`[slack-files] downloaded data is HTML, not an image! Preview: ${preview}`);
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
// Normalize with sharp (handles format detection internally)
|
|
185
|
+
console.log(`[slack-files] downloaded ${buf.length} bytes, hex: ${hexDump}, format: ${detectedFormat}`);
|
|
186
|
+
// Normalize with sharp
|
|
107
187
|
try {
|
|
108
188
|
const metadata = await sharp(buf).metadata();
|
|
109
189
|
console.log(`[slack-files] sharp metadata: format=${metadata.format}, ${metadata.width}x${metadata.height}, channels=${metadata.channels}, space=${metadata.space}`);
|
|
@@ -121,7 +201,6 @@ export async function downloadSlackImages(client, files) {
|
|
|
121
201
|
catch (sharpErr) {
|
|
122
202
|
console.error(`[slack-files] sharp failed:`, sharpErr);
|
|
123
203
|
if (detectedFormat && SUPPORTED_TYPES.has(detectedFormat)) {
|
|
124
|
-
console.log(`[slack-files] fallback: raw buffer with ${detectedFormat}`);
|
|
125
204
|
results.push({
|
|
126
205
|
base64: buf.toString("base64"),
|
|
127
206
|
mediaType: detectedFormat,
|
|
@@ -130,7 +209,7 @@ export async function downloadSlackImages(client, files) {
|
|
|
130
209
|
}
|
|
131
210
|
}
|
|
132
211
|
catch (err) {
|
|
133
|
-
console.error(`[slack-files] error
|
|
212
|
+
console.error(`[slack-files] error processing file ${file.id}:`, err);
|
|
134
213
|
}
|
|
135
214
|
}
|
|
136
215
|
console.log(`[slack-files] total images processed: ${results.length}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack-files.js","sourceRoot":"","sources":["../../src/utils/slack-files.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,YAAY;IACZ,WAAW;IACX,WAAW;IACX,YAAY;CACb,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,IAAI,CAAC,CAAC,6BAA6B;AAE/D
|
|
1
|
+
{"version":3,"file":"slack-files.js","sourceRoot":"","sources":["../../src/utils/slack-files.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/handlers/mention.ts
CHANGED
|
@@ -59,7 +59,7 @@ export async function handleMention(
|
|
|
59
59
|
const { event, client } = args;
|
|
60
60
|
const { text, channel, ts, thread_ts } = event;
|
|
61
61
|
const authorUserId = event.user ?? "unknown";
|
|
62
|
-
const files = "files" in event ? (event as unknown as { files?: Array<{ url_private_download?: string; url_private?: string; mimetype?: string }> }).files : undefined;
|
|
62
|
+
const files = "files" in event ? (event as unknown as { files?: Array<{ url_private_download?: string; url_private?: string; mimetype?: string; name?: string; filetype?: string; size?: number; id?: string }> }).files : undefined;
|
|
63
63
|
|
|
64
64
|
// Download any image attachments
|
|
65
65
|
const images = files?.length ? await downloadSlackImages(client, files) : [];
|
package/src/handlers/thread.ts
CHANGED
|
@@ -39,7 +39,7 @@ export async function handleThreadMessage(
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
const text = "text" in event ? event.text : undefined;
|
|
42
|
-
const files = "files" in event ? (event as unknown as { files?: Array<{ url_private_download?: string; url_private?: string; mimetype?: string }> }).files : undefined;
|
|
42
|
+
const files = "files" in event ? (event as unknown as { files?: Array<{ url_private_download?: string; url_private?: string; mimetype?: string; name?: string; filetype?: string; size?: number; id?: string }> }).files : undefined;
|
|
43
43
|
const channel = event.channel;
|
|
44
44
|
|
|
45
45
|
// Only respond if we have an active session for this thread
|
package/src/utils/slack-files.ts
CHANGED
|
@@ -15,9 +15,6 @@ const SUPPORTED_TYPES = new Set([
|
|
|
15
15
|
|
|
16
16
|
const MAX_IMAGE_DIMENSION = 1568; // Claude API recommended max
|
|
17
17
|
|
|
18
|
-
/**
|
|
19
|
-
* Detect actual image format from magic bytes.
|
|
20
|
-
*/
|
|
21
18
|
function detectImageFormat(buf: Buffer): string | null {
|
|
22
19
|
if (buf.length < 12) return null;
|
|
23
20
|
if (buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47) return "image/png";
|
|
@@ -28,47 +25,139 @@ function detectImageFormat(buf: Buffer): string | null {
|
|
|
28
25
|
return null;
|
|
29
26
|
}
|
|
30
27
|
|
|
28
|
+
function isHtml(buf: Buffer): boolean {
|
|
29
|
+
const head = buf.subarray(0, 50).toString("utf8");
|
|
30
|
+
return head.includes("<!DOCTYPE") || head.includes("<html") || head.includes("<HTML");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Check if buffer looks like actual image data (magic bytes or minimum size) */
|
|
34
|
+
function looksLikeImage(buf: Buffer): boolean {
|
|
35
|
+
if (buf.length < 100) return false; // Too small to be a real image
|
|
36
|
+
if (isHtml(buf)) return false;
|
|
37
|
+
return detectImageFormat(buf) !== null;
|
|
38
|
+
}
|
|
39
|
+
|
|
31
40
|
/**
|
|
32
|
-
*
|
|
33
|
-
* Slack's file URLs
|
|
41
|
+
* Try multiple methods to download a file from Slack.
|
|
42
|
+
* Slack's file URLs may require different auth approaches depending on workspace settings.
|
|
34
43
|
*/
|
|
35
|
-
async function fetchSlackFile(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
console.log(`[slack-files]
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
44
|
+
async function fetchSlackFile(
|
|
45
|
+
url: string,
|
|
46
|
+
token: string,
|
|
47
|
+
client: WebClient,
|
|
48
|
+
fileId?: string,
|
|
49
|
+
): Promise<Buffer | null> {
|
|
50
|
+
// Method 1: Bearer header with manual redirect
|
|
51
|
+
console.log(`[slack-files] method 1: Bearer header + manual redirect`);
|
|
52
|
+
try {
|
|
53
|
+
const resp = await fetch(url, {
|
|
54
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
55
|
+
redirect: "manual",
|
|
56
|
+
});
|
|
57
|
+
console.log(`[slack-files] status=${resp.status}, content-type=${resp.headers.get("content-type")}, location=${resp.headers.get("location")?.substring(0, 100) ?? "none"}`);
|
|
58
|
+
|
|
59
|
+
if (resp.status >= 300 && resp.status < 400) {
|
|
60
|
+
const location = resp.headers.get("location");
|
|
61
|
+
if (location) {
|
|
62
|
+
console.log(`[slack-files] following redirect with Bearer...`);
|
|
63
|
+
const resp2 = await fetch(location, {
|
|
64
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
65
|
+
});
|
|
66
|
+
const buf = Buffer.from(await resp2.arrayBuffer());
|
|
67
|
+
console.log(`[slack-files] redirect result: status=${resp2.status}, bytes=${buf.length}, isHtml=${isHtml(buf)}`);
|
|
68
|
+
if (looksLikeImage(buf)) return buf;
|
|
69
|
+
}
|
|
70
|
+
} else if (resp.ok) {
|
|
71
|
+
const buf = Buffer.from(await resp.arrayBuffer());
|
|
72
|
+
console.log(`[slack-files] direct result: bytes=${buf.length}, isHtml=${isHtml(buf)}`);
|
|
73
|
+
if (looksLikeImage(buf)) return buf;
|
|
55
74
|
}
|
|
75
|
+
} catch (err) {
|
|
76
|
+
console.warn(`[slack-files] method 1 error:`, err);
|
|
56
77
|
}
|
|
57
78
|
|
|
58
|
-
//
|
|
59
|
-
|
|
79
|
+
// Method 2: Token as query parameter
|
|
80
|
+
console.log(`[slack-files] method 2: token as query param`);
|
|
81
|
+
try {
|
|
82
|
+
const urlWithToken = new URL(url);
|
|
83
|
+
urlWithToken.searchParams.set("t", token);
|
|
84
|
+
const resp = await fetch(urlWithToken.toString());
|
|
60
85
|
const buf = Buffer.from(await resp.arrayBuffer());
|
|
61
|
-
|
|
86
|
+
console.log(`[slack-files] status=${resp.status}, bytes=${buf.length}, isHtml=${isHtml(buf)}`);
|
|
87
|
+
if (looksLikeImage(buf)) return buf;
|
|
88
|
+
} catch (err) {
|
|
89
|
+
console.warn(`[slack-files] method 2 error:`, err);
|
|
62
90
|
}
|
|
63
91
|
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
92
|
+
// Method 3: Use files.info API to get fresh URLs
|
|
93
|
+
if (fileId) {
|
|
94
|
+
console.log(`[slack-files] method 3: files.info API for file ${fileId}`);
|
|
95
|
+
try {
|
|
96
|
+
const info = await client.files.info({ file: fileId });
|
|
97
|
+
const freshUrl = info.file?.url_private_download ?? info.file?.url_private;
|
|
98
|
+
console.log(`[slack-files] files.info url_private_download=${info.file?.url_private_download?.substring(0, 80)}`);
|
|
99
|
+
console.log(`[slack-files] files.info url_private=${info.file?.url_private?.substring(0, 80)}`);
|
|
100
|
+
|
|
101
|
+
// Try thumb URLs as fallback (these might use different CDN)
|
|
102
|
+
const thumbKeys = ["thumb_1024", "thumb_720", "thumb_480", "thumb_360"] as const;
|
|
103
|
+
type FileInfo = NonNullable<typeof info.file>;
|
|
104
|
+
for (const key of thumbKeys) {
|
|
105
|
+
const thumbUrl = (info.file as FileInfo & Record<string, string | undefined>)?.[key];
|
|
106
|
+
if (thumbUrl) {
|
|
107
|
+
console.log(`[slack-files] found ${key}: ${thumbUrl.substring(0, 80)}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (freshUrl && freshUrl !== url) {
|
|
112
|
+
console.log(`[slack-files] trying fresh URL with Bearer...`);
|
|
113
|
+
const resp = await fetch(freshUrl, {
|
|
114
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
115
|
+
});
|
|
116
|
+
const buf = Buffer.from(await resp.arrayBuffer());
|
|
117
|
+
console.log(`[slack-files] fresh URL result: status=${resp.status}, bytes=${buf.length}, isHtml=${isHtml(buf)}`);
|
|
118
|
+
if (looksLikeImage(buf)) return buf;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Try thumbnail URLs (often hosted on Slack CDN with different auth)
|
|
122
|
+
for (const key of thumbKeys) {
|
|
123
|
+
const thumbUrl = (info.file as FileInfo & Record<string, string | undefined>)?.[key];
|
|
124
|
+
if (thumbUrl) {
|
|
125
|
+
console.log(`[slack-files] trying ${key} URL with Bearer...`);
|
|
126
|
+
try {
|
|
127
|
+
const resp = await fetch(thumbUrl, {
|
|
128
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
129
|
+
});
|
|
130
|
+
const buf = Buffer.from(await resp.arrayBuffer());
|
|
131
|
+
console.log(`[slack-files] ${key} result: status=${resp.status}, bytes=${buf.length}, isHtml=${isHtml(buf)}`);
|
|
132
|
+
if (looksLikeImage(buf)) return buf;
|
|
133
|
+
} catch (thumbErr) {
|
|
134
|
+
console.warn(`[slack-files] ${key} error:`, thumbErr);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
} catch (err) {
|
|
139
|
+
console.warn(`[slack-files] method 3 error:`, err);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Method 4: Try url_private (view URL, not download URL)
|
|
144
|
+
const viewUrl = url.replace("/download/", "/");
|
|
145
|
+
if (viewUrl !== url) {
|
|
146
|
+
console.log(`[slack-files] method 4: url_private (view URL) with Bearer`);
|
|
147
|
+
try {
|
|
148
|
+
const resp = await fetch(viewUrl, {
|
|
149
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
150
|
+
});
|
|
151
|
+
const buf = Buffer.from(await resp.arrayBuffer());
|
|
152
|
+
console.log(`[slack-files] status=${resp.status}, bytes=${buf.length}, isHtml=${isHtml(buf)}`);
|
|
153
|
+
if (looksLikeImage(buf)) return buf;
|
|
154
|
+
} catch (err) {
|
|
155
|
+
console.warn(`[slack-files] method 4 error:`, err);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
console.warn(`[slack-files] all download methods failed for ${url}`);
|
|
160
|
+
return null;
|
|
72
161
|
}
|
|
73
162
|
|
|
74
163
|
/**
|
|
@@ -98,6 +187,7 @@ export async function downloadSlackImages(
|
|
|
98
187
|
for (const file of files) {
|
|
99
188
|
const mime = file.mimetype;
|
|
100
189
|
console.log(`[slack-files] processing file: id=${file.id}, name=${file.name}, filetype=${file.filetype}, mimetype=${mime}, size=${file.size}`);
|
|
190
|
+
console.log(`[slack-files] file URLs: url_private_download=${file.url_private_download}, url_private=${file.url_private}`);
|
|
101
191
|
|
|
102
192
|
if (!mime || !SUPPORTED_TYPES.has(mime)) {
|
|
103
193
|
console.log(`[slack-files] skipping unsupported mime: ${mime}`);
|
|
@@ -109,31 +199,16 @@ export async function downloadSlackImages(
|
|
|
109
199
|
console.warn(`[slack-files] no download URL for file ${file.id}`);
|
|
110
200
|
continue;
|
|
111
201
|
}
|
|
112
|
-
console.log(`[slack-files] download URL: ${url}`);
|
|
113
202
|
|
|
114
203
|
try {
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
if (!ok) {
|
|
118
|
-
console.warn(`[slack-files] download failed: status=${status}`);
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
204
|
+
const buf = await fetchSlackFile(url, token, client, file.id);
|
|
205
|
+
if (!buf) continue;
|
|
121
206
|
|
|
122
207
|
const hexDump = buf.subarray(0, 16).toString("hex").match(/../g)?.join(" ") ?? "";
|
|
123
208
|
const detectedFormat = detectImageFormat(buf);
|
|
124
|
-
console.log(`[slack-files] downloaded ${buf.length} bytes,
|
|
125
|
-
console.log(`[slack-files] first 16 bytes: ${hexDump}`);
|
|
126
|
-
console.log(`[slack-files] declared mime=${mime}, detected format=${detectedFormat}`);
|
|
127
|
-
|
|
128
|
-
// If the data looks like HTML (Slack error/login page), log and skip
|
|
129
|
-
const head = buf.subarray(0, 50).toString("utf8");
|
|
130
|
-
if (head.includes("<!DOCTYPE") || head.includes("<html")) {
|
|
131
|
-
const preview = buf.subarray(0, 300).toString("utf8");
|
|
132
|
-
console.warn(`[slack-files] downloaded data is HTML, not an image! Preview: ${preview}`);
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
209
|
+
console.log(`[slack-files] downloaded ${buf.length} bytes, hex: ${hexDump}, format: ${detectedFormat}`);
|
|
135
210
|
|
|
136
|
-
// Normalize with sharp
|
|
211
|
+
// Normalize with sharp
|
|
137
212
|
try {
|
|
138
213
|
const metadata = await sharp(buf).metadata();
|
|
139
214
|
console.log(`[slack-files] sharp metadata: format=${metadata.format}, ${metadata.width}x${metadata.height}, channels=${metadata.channels}, space=${metadata.space}`);
|
|
@@ -153,7 +228,6 @@ export async function downloadSlackImages(
|
|
|
153
228
|
} catch (sharpErr) {
|
|
154
229
|
console.error(`[slack-files] sharp failed:`, sharpErr);
|
|
155
230
|
if (detectedFormat && SUPPORTED_TYPES.has(detectedFormat)) {
|
|
156
|
-
console.log(`[slack-files] fallback: raw buffer with ${detectedFormat}`);
|
|
157
231
|
results.push({
|
|
158
232
|
base64: buf.toString("base64"),
|
|
159
233
|
mediaType: detectedFormat as SlackImageFile["mediaType"],
|
|
@@ -161,7 +235,7 @@ export async function downloadSlackImages(
|
|
|
161
235
|
}
|
|
162
236
|
}
|
|
163
237
|
} catch (err) {
|
|
164
|
-
console.error(`[slack-files] error
|
|
238
|
+
console.error(`[slack-files] error processing file ${file.id}:`, err);
|
|
165
239
|
}
|
|
166
240
|
}
|
|
167
241
|
|