APRK01 commited on
Commit
0e63da1
Β·
1 Parent(s): 3f63be0

feat: integrate github releases proxy storage for drops >25MB

Browse files
Files changed (3) hide show
  1. package-lock.json +235 -1
  2. package.json +3 -1
  3. src/systems/drops.js +87 -5
package-lock.json CHANGED
@@ -8,9 +8,11 @@
8
  "name": "wsb-bot",
9
  "version": "1.0.0",
10
  "dependencies": {
 
11
  "better-sqlite3": "^11.7.0",
12
  "discord.js": "^14.16.0",
13
- "dotenv": "^16.4.0"
 
14
  }
15
  },
16
  "node_modules/@discordjs/builders": {
@@ -143,6 +145,162 @@
143
  "url": "https://github.com/discordjs/discord.js?sponsor"
144
  }
145
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  "node_modules/@sapphire/async-queue": {
147
  "version": "1.5.5",
148
  "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.5.tgz",
@@ -224,6 +382,12 @@
224
  ],
225
  "license": "MIT"
226
  },
 
 
 
 
 
 
227
  "node_modules/better-sqlite3": {
228
  "version": "11.10.0",
229
  "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.10.0.tgz",
@@ -384,6 +548,22 @@
384
  "node": ">=6"
385
  }
386
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
  "node_modules/fast-deep-equal": {
388
  "version": "3.1.3",
389
  "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -440,6 +620,12 @@
440
  "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
441
  "license": "ISC"
442
  },
 
 
 
 
 
 
443
  "node_modules/lodash": {
444
  "version": "4.17.23",
445
  "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
@@ -503,6 +689,26 @@
503
  "node": ">=10"
504
  }
505
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
  "node_modules/once": {
507
  "version": "1.4.0",
508
  "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -701,6 +907,12 @@
701
  "node": ">=6"
702
  }
703
  },
 
 
 
 
 
 
704
  "node_modules/ts-mixer": {
705
  "version": "6.0.4",
706
  "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz",
@@ -740,12 +952,34 @@
740
  "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
741
  "license": "MIT"
742
  },
 
 
 
 
 
 
743
  "node_modules/util-deprecate": {
744
  "version": "1.0.2",
745
  "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
746
  "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
747
  "license": "MIT"
748
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
749
  "node_modules/wrappy": {
750
  "version": "1.0.2",
751
  "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
 
8
  "name": "wsb-bot",
9
  "version": "1.0.0",
10
  "dependencies": {
11
+ "@octokit/rest": "^22.0.1",
12
  "better-sqlite3": "^11.7.0",
13
  "discord.js": "^14.16.0",
14
+ "dotenv": "^16.4.0",
15
+ "node-fetch": "^2.7.0"
16
  }
17
  },
18
  "node_modules/@discordjs/builders": {
 
145
  "url": "https://github.com/discordjs/discord.js?sponsor"
146
  }
147
  },
148
+ "node_modules/@octokit/auth-token": {
149
+ "version": "6.0.0",
150
+ "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz",
151
+ "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==",
152
+ "license": "MIT",
153
+ "engines": {
154
+ "node": ">= 20"
155
+ }
156
+ },
157
+ "node_modules/@octokit/core": {
158
+ "version": "7.0.6",
159
+ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz",
160
+ "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==",
161
+ "license": "MIT",
162
+ "peer": true,
163
+ "dependencies": {
164
+ "@octokit/auth-token": "^6.0.0",
165
+ "@octokit/graphql": "^9.0.3",
166
+ "@octokit/request": "^10.0.6",
167
+ "@octokit/request-error": "^7.0.2",
168
+ "@octokit/types": "^16.0.0",
169
+ "before-after-hook": "^4.0.0",
170
+ "universal-user-agent": "^7.0.0"
171
+ },
172
+ "engines": {
173
+ "node": ">= 20"
174
+ }
175
+ },
176
+ "node_modules/@octokit/endpoint": {
177
+ "version": "11.0.3",
178
+ "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz",
179
+ "integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==",
180
+ "license": "MIT",
181
+ "dependencies": {
182
+ "@octokit/types": "^16.0.0",
183
+ "universal-user-agent": "^7.0.2"
184
+ },
185
+ "engines": {
186
+ "node": ">= 20"
187
+ }
188
+ },
189
+ "node_modules/@octokit/graphql": {
190
+ "version": "9.0.3",
191
+ "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz",
192
+ "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==",
193
+ "license": "MIT",
194
+ "dependencies": {
195
+ "@octokit/request": "^10.0.6",
196
+ "@octokit/types": "^16.0.0",
197
+ "universal-user-agent": "^7.0.0"
198
+ },
199
+ "engines": {
200
+ "node": ">= 20"
201
+ }
202
+ },
203
+ "node_modules/@octokit/openapi-types": {
204
+ "version": "27.0.0",
205
+ "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz",
206
+ "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==",
207
+ "license": "MIT"
208
+ },
209
+ "node_modules/@octokit/plugin-paginate-rest": {
210
+ "version": "14.0.0",
211
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz",
212
+ "integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==",
213
+ "license": "MIT",
214
+ "dependencies": {
215
+ "@octokit/types": "^16.0.0"
216
+ },
217
+ "engines": {
218
+ "node": ">= 20"
219
+ },
220
+ "peerDependencies": {
221
+ "@octokit/core": ">=6"
222
+ }
223
+ },
224
+ "node_modules/@octokit/plugin-request-log": {
225
+ "version": "6.0.0",
226
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-6.0.0.tgz",
227
+ "integrity": "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==",
228
+ "license": "MIT",
229
+ "engines": {
230
+ "node": ">= 20"
231
+ },
232
+ "peerDependencies": {
233
+ "@octokit/core": ">=6"
234
+ }
235
+ },
236
+ "node_modules/@octokit/plugin-rest-endpoint-methods": {
237
+ "version": "17.0.0",
238
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz",
239
+ "integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==",
240
+ "license": "MIT",
241
+ "dependencies": {
242
+ "@octokit/types": "^16.0.0"
243
+ },
244
+ "engines": {
245
+ "node": ">= 20"
246
+ },
247
+ "peerDependencies": {
248
+ "@octokit/core": ">=6"
249
+ }
250
+ },
251
+ "node_modules/@octokit/request": {
252
+ "version": "10.0.8",
253
+ "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.8.tgz",
254
+ "integrity": "sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw==",
255
+ "license": "MIT",
256
+ "dependencies": {
257
+ "@octokit/endpoint": "^11.0.3",
258
+ "@octokit/request-error": "^7.0.2",
259
+ "@octokit/types": "^16.0.0",
260
+ "fast-content-type-parse": "^3.0.0",
261
+ "json-with-bigint": "^3.5.3",
262
+ "universal-user-agent": "^7.0.2"
263
+ },
264
+ "engines": {
265
+ "node": ">= 20"
266
+ }
267
+ },
268
+ "node_modules/@octokit/request-error": {
269
+ "version": "7.1.0",
270
+ "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz",
271
+ "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==",
272
+ "license": "MIT",
273
+ "dependencies": {
274
+ "@octokit/types": "^16.0.0"
275
+ },
276
+ "engines": {
277
+ "node": ">= 20"
278
+ }
279
+ },
280
+ "node_modules/@octokit/rest": {
281
+ "version": "22.0.1",
282
+ "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-22.0.1.tgz",
283
+ "integrity": "sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw==",
284
+ "license": "MIT",
285
+ "dependencies": {
286
+ "@octokit/core": "^7.0.6",
287
+ "@octokit/plugin-paginate-rest": "^14.0.0",
288
+ "@octokit/plugin-request-log": "^6.0.0",
289
+ "@octokit/plugin-rest-endpoint-methods": "^17.0.0"
290
+ },
291
+ "engines": {
292
+ "node": ">= 20"
293
+ }
294
+ },
295
+ "node_modules/@octokit/types": {
296
+ "version": "16.0.0",
297
+ "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz",
298
+ "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==",
299
+ "license": "MIT",
300
+ "dependencies": {
301
+ "@octokit/openapi-types": "^27.0.0"
302
+ }
303
+ },
304
  "node_modules/@sapphire/async-queue": {
305
  "version": "1.5.5",
306
  "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.5.tgz",
 
382
  ],
383
  "license": "MIT"
384
  },
385
+ "node_modules/before-after-hook": {
386
+ "version": "4.0.0",
387
+ "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz",
388
+ "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==",
389
+ "license": "Apache-2.0"
390
+ },
391
  "node_modules/better-sqlite3": {
392
  "version": "11.10.0",
393
  "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.10.0.tgz",
 
548
  "node": ">=6"
549
  }
550
  },
551
+ "node_modules/fast-content-type-parse": {
552
+ "version": "3.0.0",
553
+ "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz",
554
+ "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==",
555
+ "funding": [
556
+ {
557
+ "type": "github",
558
+ "url": "https://github.com/sponsors/fastify"
559
+ },
560
+ {
561
+ "type": "opencollective",
562
+ "url": "https://opencollective.com/fastify"
563
+ }
564
+ ],
565
+ "license": "MIT"
566
+ },
567
  "node_modules/fast-deep-equal": {
568
  "version": "3.1.3",
569
  "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
 
620
  "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
621
  "license": "ISC"
622
  },
623
+ "node_modules/json-with-bigint": {
624
+ "version": "3.5.7",
625
+ "resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.7.tgz",
626
+ "integrity": "sha512-7ei3MdAI5+fJPVnKlW77TKNKwQ5ppSzWvhPuSuINT/GYW9ZOC1eRKOuhV9yHG5aEsUPj9BBx5JIekkmoLHxZOw==",
627
+ "license": "MIT"
628
+ },
629
  "node_modules/lodash": {
630
  "version": "4.17.23",
631
  "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
 
689
  "node": ">=10"
690
  }
691
  },
692
+ "node_modules/node-fetch": {
693
+ "version": "2.7.0",
694
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
695
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
696
+ "license": "MIT",
697
+ "dependencies": {
698
+ "whatwg-url": "^5.0.0"
699
+ },
700
+ "engines": {
701
+ "node": "4.x || >=6.0.0"
702
+ },
703
+ "peerDependencies": {
704
+ "encoding": "^0.1.0"
705
+ },
706
+ "peerDependenciesMeta": {
707
+ "encoding": {
708
+ "optional": true
709
+ }
710
+ }
711
+ },
712
  "node_modules/once": {
713
  "version": "1.4.0",
714
  "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
 
907
  "node": ">=6"
908
  }
909
  },
910
+ "node_modules/tr46": {
911
+ "version": "0.0.3",
912
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
913
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
914
+ "license": "MIT"
915
+ },
916
  "node_modules/ts-mixer": {
917
  "version": "6.0.4",
918
  "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz",
 
952
  "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
953
  "license": "MIT"
954
  },
955
+ "node_modules/universal-user-agent": {
956
+ "version": "7.0.3",
957
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz",
958
+ "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==",
959
+ "license": "ISC"
960
+ },
961
  "node_modules/util-deprecate": {
962
  "version": "1.0.2",
963
  "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
964
  "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
965
  "license": "MIT"
966
  },
967
+ "node_modules/webidl-conversions": {
968
+ "version": "3.0.1",
969
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
970
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
971
+ "license": "BSD-2-Clause"
972
+ },
973
+ "node_modules/whatwg-url": {
974
+ "version": "5.0.0",
975
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
976
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
977
+ "license": "MIT",
978
+ "dependencies": {
979
+ "tr46": "~0.0.3",
980
+ "webidl-conversions": "^3.0.0"
981
+ }
982
+ },
983
  "node_modules/wrappy": {
984
  "version": "1.0.2",
985
  "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
package.json CHANGED
@@ -7,8 +7,10 @@
7
  "start": "node src/index.js"
8
  },
9
  "dependencies": {
 
10
  "better-sqlite3": "^11.7.0",
11
  "discord.js": "^14.16.0",
12
- "dotenv": "^16.4.0"
 
13
  }
14
  }
 
7
  "start": "node src/index.js"
8
  },
9
  "dependencies": {
10
+ "@octokit/rest": "^22.0.1",
11
  "better-sqlite3": "^11.7.0",
12
  "discord.js": "^14.16.0",
13
+ "dotenv": "^16.4.0",
14
+ "node-fetch": "^2.7.0"
15
  }
16
  }
src/systems/drops.js CHANGED
@@ -5,6 +5,8 @@ const {
5
  StringSelectMenuBuilder,
6
  AttachmentBuilder,
7
  } = require('discord.js');
 
 
8
  const { createEmbed } = require('../utils/embeds');
9
  const { Colors } = require('../config');
10
  const { stmts } = require('../database');
@@ -169,7 +171,7 @@ function buildDropEmbed(session) {
169
 
170
  lines.push('```');
171
  lines.push(`πŸ“ File: ${session.file.name}`);
172
- lines.push(`πŸ“Š Size: ${formatBytes(session.file.size)}`);
173
  lines.push(`πŸ”Ž Status: ${statusText}`);
174
  lines.push('```');
175
  lines.push('');
@@ -327,10 +329,90 @@ async function handleDropMessage(message) {
327
  image: imageUrl ? { url: imageUrl } : null
328
  });
329
 
330
- await channel.send({
331
- embeds: [dropEmbed],
332
- files: filesToUpload,
333
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
 
335
  // Log the drop for rate limiting
336
  stmts.logDrop.run(userId, session.title, channelId);
 
5
  StringSelectMenuBuilder,
6
  AttachmentBuilder,
7
  } = require('discord.js');
8
+ const { Octokit } = require('@octokit/rest');
9
+ const fetch = require('node-fetch');
10
  const { createEmbed } = require('../utils/embeds');
11
  const { Colors } = require('../config');
12
  const { stmts } = require('../database');
 
171
 
172
  lines.push('```');
173
  lines.push(`πŸ“ File: ${session.file.name}`);
174
+ lines.push(`πŸ“Š Size: ${session.file.size !== 'Unknown' ? formatBytes(session.file.size) : 'External File (Unknown Size)'}`);
175
  lines.push(`πŸ”Ž Status: ${statusText}`);
176
  lines.push('```');
177
  lines.push('');
 
329
  image: imageUrl ? { url: imageUrl } : null
330
  });
331
 
332
+ // We'll try to upload the files first. If it fails (e.g., file too large for server limits),
333
+ // we catch the error and fallback to sending just the URL and download button.
334
+ try {
335
+ await channel.send({
336
+ embeds: [dropEmbed],
337
+ files: filesToUpload,
338
+ });
339
+ } catch (uploadErr) {
340
+ console.warn('[Drop Upload Fallback]', uploadErr.message);
341
+
342
+ const processingMsg = await message.reply({ content: '⏳ *File is too large for Discord limits. Uploading to permanent GitHub proxy storage...*' });
343
+
344
+ try {
345
+ if (!process.env.GITHUB_TOKEN || !process.env.STORAGE_REPO) {
346
+ throw new Error('GitHub token or storage repo not configured in .env');
347
+ }
348
+
349
+ // Using GitHub Releases as unlimited CDN proxy storage
350
+ const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
351
+ const [owner, repo] = process.env.STORAGE_REPO.split('/');
352
+
353
+ // 1. Download the file from Discord's temporary DM CDN
354
+ const fileRes = await fetch(session.file.url);
355
+ const fileBuffer = await fileRes.buffer();
356
+
357
+ // 2. Create the release
358
+ const releaseTitle = `Drop: ${session.title.replace(/[^a-zA-Z0-9 -]/g, '')} - ${Date.now()}`;
359
+ const release = await octokit.rest.repos.createRelease({
360
+ owner,
361
+ repo,
362
+ tag_name: `drop-${Date.now()}`,
363
+ name: releaseTitle,
364
+ body: `Auto-generated drop upload for WSB.\n\nDescription: ${session.about}`
365
+ });
366
+
367
+ // 3. Upload the asset to the newly created release
368
+ const uploadRes = await octokit.rest.repos.uploadReleaseAsset({
369
+ owner,
370
+ repo,
371
+ release_id: release.data.id,
372
+ name: session.file.name,
373
+ data: fileBuffer,
374
+ headers: {
375
+ 'content-type': 'application/octet-stream',
376
+ 'content-length': fileBuffer.length
377
+ }
378
+ });
379
+
380
+ // Update Embed to point to the permanent GitHub file
381
+ const permanentUrl = uploadRes.data.browser_download_url;
382
+ const fallbackEmbed = buildDropEmbed(session);
383
+ const fallbackRow = new ActionRowBuilder().addComponents(
384
+ new ButtonBuilder()
385
+ .setLabel('πŸ“₯ Download Drop')
386
+ .setStyle(ButtonStyle.Link)
387
+ .setURL(permanentUrl)
388
+ );
389
+
390
+ await channel.send({
391
+ embeds: [fallbackEmbed],
392
+ components: [fallbackRow]
393
+ });
394
+
395
+ await processingMsg.edit({ content: 'βœ… *Successfully proxied massive file to GitHub permanent storage.*' });
396
+
397
+ } catch (githubErr) {
398
+ console.error('[GitHub Upload Error]', githubErr);
399
+ await processingMsg.edit({ content: '❌ *Failed to proxy storage to GitHub. Using external link fallback.*' });
400
+
401
+ // Extremely drastic fallback
402
+ const fallbackEmbed = buildDropEmbed(session);
403
+ const fallbackRow = new ActionRowBuilder().addComponents(
404
+ new ButtonBuilder()
405
+ .setLabel('πŸ“₯ Download (External Link)')
406
+ .setStyle(ButtonStyle.Link)
407
+ .setURL(session.file.url)
408
+ );
409
+ await channel.send({
410
+ content: '⚠️ *Note: This file was too large to attach securely and proxy storage failed. Using external link.*',
411
+ embeds: [fallbackEmbed],
412
+ components: [fallbackRow]
413
+ });
414
+ }
415
+ }
416
 
417
  // Log the drop for rate limiting
418
  stmts.logDrop.run(userId, session.title, channelId);