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 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":"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"}
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":"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"}
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;AAmED;;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,CAkF3B"}
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
- * Download a file from Slack, handling cross-origin redirects that strip the Authorization header.
28
- * Slack's file URLs often redirect to a CDN, and fetch() strips auth headers on cross-origin redirects.
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
- // First try: manual redirect to preserve auth through redirect chain
32
- const resp = await fetch(url, {
33
- headers: { Authorization: `Bearer ${token}` },
34
- redirect: "manual",
35
- });
36
- console.log(`[slack-files] initial response: status=${resp.status}, content-type=${resp.headers.get("content-type")}, location=${resp.headers.get("location")?.substring(0, 80) ?? "none"}`);
37
- // If redirect, follow it manually with auth header
38
- if (resp.status >= 300 && resp.status < 400) {
39
- const location = resp.headers.get("location");
40
- if (location) {
41
- console.log(`[slack-files] following redirect to: ${location.substring(0, 80)}...`);
42
- const resp2 = await fetch(location, {
43
- headers: { Authorization: `Bearer ${token}` },
44
- });
45
- console.log(`[slack-files] redirect response: status=${resp2.status}, content-type=${resp2.headers.get("content-type")}`);
46
- const buf = Buffer.from(await resp2.arrayBuffer());
47
- return { ok: resp2.ok, status: resp2.status, contentType: resp2.headers.get("content-type"), buffer: buf };
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
- // No redirect or non-redirect response
51
- if (resp.ok || resp.status === 200) {
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
- return { ok: true, status: resp.status, contentType: resp.headers.get("content-type"), buffer: buf };
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
- // If first approach failed (got HTML), try with token as query parameter
56
- console.log(`[slack-files] Bearer auth failed (status=${resp.status}), trying token as query param`);
57
- const urlWithToken = new URL(url);
58
- urlWithToken.searchParams.set("t", token);
59
- const resp3 = await fetch(urlWithToken.toString());
60
- console.log(`[slack-files] query param response: status=${resp3.status}, content-type=${resp3.headers.get("content-type")}`);
61
- const buf = Buffer.from(await resp3.arrayBuffer());
62
- return { ok: resp3.ok, status: resp3.status, contentType: resp3.headers.get("content-type"), buffer: buf };
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 { ok, status, contentType, buffer: buf } = await fetchSlackFile(url, token);
90
- if (!ok) {
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, content-type=${contentType}`);
97
- console.log(`[slack-files] first 16 bytes: ${hexDump}`);
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 downloading file ${file.id}:`, err);
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":"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"}
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,SAAS,iBAAiB,CAAC,GAAW;IACpC,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;IACjC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,WAAW,CAAC;IACjG,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,YAAY,CAAC;IAC/E,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,WAAW,CAAC;IAC9E,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;WACvE,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC,KAAK,IAAI;QAAE,OAAO,YAAY,CAAC;IACrG,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,MAAM,CAAC,GAAW;IACzB,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClD,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACxF,CAAC;AAED,iFAAiF;AACjF,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG;QAAE,OAAO,KAAK,CAAC,CAAC,+BAA+B;IACnE,IAAI,MAAM,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9B,OAAO,iBAAiB,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,cAAc,CAC3B,GAAW,EACX,KAAa,EACb,MAAiB,EACjB,MAAe;IAEf,+CAA+C;IAC/C,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;IACvE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC5B,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;YAC7C,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,CAAC,MAAM,kBAAkB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,cAAc,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC;QAE9K,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC9C,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;gBACjE,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;oBAClC,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;iBAC9C,CAAC,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;gBACnD,OAAO,CAAC,GAAG,CAAC,2CAA2C,KAAK,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,YAAY,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACnH,IAAI,cAAc,CAAC,GAAG,CAAC;oBAAE,OAAO,GAAG,CAAC;YACtC,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACnB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,wCAAwC,GAAG,CAAC,MAAM,YAAY,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACzF,IAAI,cAAc,CAAC,GAAG,CAAC;gBAAE,OAAO,GAAG,CAAC;QACtC,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;IACvD,CAAC;IAED,qCAAqC;IACrC,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC5D,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC;QAClD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,YAAY,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjG,IAAI,cAAc,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;IACvD,CAAC;IAED,iDAAiD;IACjD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,mDAAmD,MAAM,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,oBAAoB,IAAI,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC;YAC3E,OAAO,CAAC,GAAG,CAAC,mDAAmD,IAAI,CAAC,IAAI,EAAE,oBAAoB,EAAE,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;YACpH,OAAO,CAAC,GAAG,CAAC,0CAA0C,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;YAElG,6DAA6D;YAC7D,MAAM,SAAS,GAAG,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,CAAU,CAAC;YAEjF,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;gBAC5B,MAAM,QAAQ,GAAI,IAAI,CAAC,IAAsD,EAAE,CAAC,GAAG,CAAC,CAAC;gBACrF,IAAI,QAAQ,EAAE,CAAC;oBACb,OAAO,CAAC,GAAG,CAAC,yBAAyB,GAAG,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC5E,CAAC;YACH,CAAC;YAED,IAAI,QAAQ,IAAI,QAAQ,KAAK,GAAG,EAAE,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;gBAC/D,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;oBACjC,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;iBAC9C,CAAC,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;gBAClD,OAAO,CAAC,GAAG,CAAC,4CAA4C,IAAI,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,YAAY,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACnH,IAAI,cAAc,CAAC,GAAG,CAAC;oBAAE,OAAO,GAAG,CAAC;YACtC,CAAC;YAED,qEAAqE;YACrE,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;gBAC5B,MAAM,QAAQ,GAAI,IAAI,CAAC,IAAsD,EAAE,CAAC,GAAG,CAAC,CAAC;gBACrF,IAAI,QAAQ,EAAE,CAAC;oBACb,OAAO,CAAC,GAAG,CAAC,0BAA0B,GAAG,qBAAqB,CAAC,CAAC;oBAChE,IAAI,CAAC;wBACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;4BACjC,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;yBAC9C,CAAC,CAAC;wBACH,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;wBAClD,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,mBAAmB,IAAI,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,YAAY,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;wBAChH,IAAI,cAAc,CAAC,GAAG,CAAC;4BAAE,OAAO,GAAG,CAAC;oBACtC,CAAC;oBAAC,OAAO,QAAQ,EAAE,CAAC;wBAClB,OAAO,CAAC,IAAI,CAAC,mBAAmB,GAAG,SAAS,EAAE,QAAQ,CAAC,CAAC;oBAC1D,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,yDAAyD;IACzD,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;IAC/C,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAC;QAC1E,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE;gBAChC,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;aAC9C,CAAC,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,YAAY,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACjG,IAAI,cAAc,CAAC,GAAG,CAAC;gBAAE,OAAO,GAAG,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,iDAAiD,GAAG,EAAE,CAAC,CAAC;IACrE,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAiB,EACjB,KAQE;IAEF,MAAM,KAAK,GAAI,MAAwC,CAAC,KAAK,CAAC;IAC9D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QAC1D,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,6BAA6B,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAE7F,MAAM,OAAO,GAAqB,EAAE,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,qCAAqC,IAAI,CAAC,EAAE,UAAU,IAAI,CAAC,IAAI,cAAc,IAAI,CAAC,QAAQ,cAAc,IAAI,UAAU,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/I,OAAO,CAAC,GAAG,CAAC,iDAAiD,IAAI,CAAC,oBAAoB,iBAAiB,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAE3H,IAAI,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,OAAO,CAAC,GAAG,CAAC,4CAA4C,IAAI,EAAE,CAAC,CAAC;YAChE,SAAS;QACX,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,oBAAoB,IAAI,IAAI,CAAC,WAAW,CAAC;QAC1D,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,IAAI,CAAC,0CAA0C,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YAClE,SAAS;QACX,CAAC;QAED,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,GAAG;gBAAE,SAAS;YAEnB,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YAClF,MAAM,cAAc,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,4BAA4B,GAAG,CAAC,MAAM,gBAAgB,OAAO,aAAa,cAAc,EAAE,CAAC,CAAC;YAExG,uBAAuB;YACvB,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC7C,OAAO,CAAC,GAAG,CAAC,wCAAwC,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,cAAc,QAAQ,CAAC,QAAQ,WAAW,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;gBAErK,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC;qBAChC,MAAM,CAAC,mBAAmB,EAAE,mBAAmB,EAAE;oBAChD,GAAG,EAAE,QAAQ;oBACb,kBAAkB,EAAE,IAAI;iBACzB,CAAC;qBACD,GAAG,EAAE;qBACL,QAAQ,EAAE,CAAC;gBAEd,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAC1C,OAAO,CAAC,GAAG,CAAC,6BAA6B,GAAG,CAAC,MAAM,MAAM,UAAU,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAM,QAAQ,CAAC,CAAC;gBAEhH,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC;YACxD,CAAC;YAAC,OAAO,QAAQ,EAAE,CAAC;gBAClB,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,QAAQ,CAAC,CAAC;gBACvD,IAAI,cAAc,IAAI,eAAe,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;oBAC1D,OAAO,CAAC,IAAI,CAAC;wBACX,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBAC9B,SAAS,EAAE,cAA6C;qBACzD,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,uCAAuC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,yCAAyC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACvE,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eniac-slack",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "type": "module",
5
5
  "bin": "./dist/cli.js",
6
6
  "scripts": {
@@ -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) : [];
@@ -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
@@ -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
- * Download a file from Slack, handling cross-origin redirects that strip the Authorization header.
33
- * Slack's file URLs often redirect to a CDN, and fetch() strips auth headers on cross-origin redirects.
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(url: string, token: string): Promise<{ ok: boolean; status: number; contentType: string | null; buffer: Buffer }> {
36
- // First try: manual redirect to preserve auth through redirect chain
37
- const resp = await fetch(url, {
38
- headers: { Authorization: `Bearer ${token}` },
39
- redirect: "manual",
40
- });
41
-
42
- console.log(`[slack-files] initial response: status=${resp.status}, content-type=${resp.headers.get("content-type")}, location=${resp.headers.get("location")?.substring(0, 80) ?? "none"}`);
43
-
44
- // If redirect, follow it manually with auth header
45
- if (resp.status >= 300 && resp.status < 400) {
46
- const location = resp.headers.get("location");
47
- if (location) {
48
- console.log(`[slack-files] following redirect to: ${location.substring(0, 80)}...`);
49
- const resp2 = await fetch(location, {
50
- headers: { Authorization: `Bearer ${token}` },
51
- });
52
- console.log(`[slack-files] redirect response: status=${resp2.status}, content-type=${resp2.headers.get("content-type")}`);
53
- const buf = Buffer.from(await resp2.arrayBuffer());
54
- return { ok: resp2.ok, status: resp2.status, contentType: resp2.headers.get("content-type"), buffer: buf };
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
- // No redirect or non-redirect response
59
- if (resp.ok || resp.status === 200) {
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
- return { ok: true, status: resp.status, contentType: resp.headers.get("content-type"), buffer: buf };
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
- // If first approach failed (got HTML), try with token as query parameter
65
- console.log(`[slack-files] Bearer auth failed (status=${resp.status}), trying token as query param`);
66
- const urlWithToken = new URL(url);
67
- urlWithToken.searchParams.set("t", token);
68
- const resp3 = await fetch(urlWithToken.toString());
69
- console.log(`[slack-files] query param response: status=${resp3.status}, content-type=${resp3.headers.get("content-type")}`);
70
- const buf = Buffer.from(await resp3.arrayBuffer());
71
- return { ok: resp3.ok, status: resp3.status, contentType: resp3.headers.get("content-type"), buffer: buf };
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 { ok, status, contentType, buffer: buf } = await fetchSlackFile(url, token);
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, content-type=${contentType}`);
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 (handles format detection internally)
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 downloading file ${file.id}:`, err);
238
+ console.error(`[slack-files] error processing file ${file.id}:`, err);
165
239
  }
166
240
  }
167
241