diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 4b08152..ca9fd4b 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -4,44 +4,44 @@ name: Node.js Package on: - release: - types: [created] + release: + types: [created] jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - with: - node-version: 14 - - run: npm ci - - run: npm test + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 14 + - run: npm ci + - run: npm test - publish-npm: - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - with: - node-version: 14 - registry-url: https://registry.npmjs.org/ - - run: npm ci - - run: npm publish - env: - NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} + publish-npm: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 14 + registry-url: https://registry.npmjs.org/ + - run: npm ci + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} - publish-gpr: - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - with: - node-version: 14 - registry-url: https://npm.pkg.github.com/ - - run: npm ci - - run: npm publish - env: - NODE_AUTH_TOKEN: ${{secrets.GH_TOKEN}} + publish-gpr: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 14 + registry-url: https://npm.pkg.github.com/ + - run: npm ci + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{secrets.GH_TOKEN}} diff --git a/.gitignore b/.gitignore index 4ae68c0..63629cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,107 +1,9 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# Next.js build output -.next +# JetBrains +.idea -# Nuxt.js build / generate output -.nuxt +# Compilation dist +types -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and *not* Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# JetBrains -.idea +# Node +node_modules diff --git a/.npmignore b/.npmignore index ba1bce0..40f872f 100644 --- a/.npmignore +++ b/.npmignore @@ -1,2 +1,3 @@ .github .idea +src diff --git a/README.md b/README.md index cb7ad24..1f23eef 100644 --- a/README.md +++ b/README.md @@ -15,11 +15,28 @@ These operations took a long time to process. Be patient and avoid doing this of ```js -const fetchedGuildMessages = await require('discord-fetch-messages').fetchGuildMessages(client, id); +const fetcher = new Fetcher(client); -const fetchedChannelMessages = await require('discord-fetch-messages').fetchChannelMessages(client, id); +fetcher.on('fetchChannel', async channel => { + await message.channel.send(`Fetching <#${channel.id}>.`); +}); + +await fetcher.fetchGuild(guildID); +await fetcher.fetchChannel(channel); ``` -Note : +## + +## Event list : + +| Event Name | Description | Arguments | +| -------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | +| `fetchChannel` | Emitter when fetching a Channel. | `channel`: The channel fetched. | +| `fetchGuild` | Emitted when fetching a Guild. | `guild`: The guild fetched. | +| `fetch` | Emitted after fetched a bulk a of messages, can fetch 0 to 100 messages. | `length`: The number of messages fetched.
`messages`: The messages fetched, as a Collection. | + +You can also use a `fetching` boolean property that is set to true when fetching a bulk of message, then to false. +> Note : +> > Node.js > 14 is required. diff --git a/index.js b/index.js new file mode 100644 index 0000000..f843a90 --- /dev/null +++ b/index.js @@ -0,0 +1 @@ +module.exports = require('./dist/index.js'); diff --git a/package-lock.json b/package-lock.json index 4d3d436..9f9246d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,10 +7,13 @@ "": { "name": "discord-fetch-messages", "version": "1.1.2", + "dependencies": { + "discord.js": "^12.5.1" + }, "devDependencies": { - "discord.js": "^12.5.0", - "prettier": "^2.2.0", - "typescript": "^4.1.2" + "@types/node": "^14.14.22", + "prettier": "^2.2.1", + "typescript": "^4.1.3" }, "engines": { "discord.js": ">=12.0.0", @@ -20,14 +23,12 @@ "node_modules/@discordjs/collection": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz", - "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ==", - "dev": true + "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ==" }, "node_modules/@discordjs/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz", "integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==", - "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -37,11 +38,16 @@ "node": ">= 6" } }, + "node_modules/@types/node": { + "version": "14.14.22", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.22.tgz", + "integrity": "sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==", + "dev": true + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, "dependencies": { "event-target-shim": "^5.0.0" }, @@ -52,14 +58,12 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -71,16 +75,14 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/discord.js": { - "version": "12.5.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.5.0.tgz", - "integrity": "sha512-MXZcnBIosHEOX26ipWEcZdUrTyfTbb4sDYYp0Go5N05PyI78LR8Ds7yAfMu0zUDmxFHYLSYX0pCdiO2pd4CP6w==", - "dev": true, + "version": "12.5.1", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.5.1.tgz", + "integrity": "sha512-VwZkVaUAIOB9mKdca0I5MefPMTQJTNg0qdgi1huF3iwsFwJ0L5s/Y69AQe+iPmjuV6j9rtKoG0Ta0n9vgEIL6w==", "dependencies": { "@discordjs/collection": "^0.1.6", "@discordjs/form-data": "^3.0.1", @@ -99,27 +101,24 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true, "engines": { "node": ">=6" } }, "node_modules/mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", - "dev": true, + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", + "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", - "dev": true, + "version": "2.1.28", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", + "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", "dependencies": { - "mime-db": "1.44.0" + "mime-db": "1.45.0" }, "engines": { "node": ">= 0.6" @@ -129,15 +128,14 @@ "version": "2.6.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "dev": true, "engines": { "node": "4.x || >=6.0.0" } }, "node_modules/prettier": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.0.tgz", - "integrity": "sha512-yYerpkvseM4iKD/BXLYUkQV5aKt4tQPqaGW6EsZjzyu0r7sVZZNPJW4Y8MyKmicp6t42XUPcBVA+H6sB3gqndw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -147,15 +145,14 @@ } }, "node_modules/prism-media": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.2.tgz", - "integrity": "sha512-I+nkWY212lJ500jLe4tN9tWO7nRiBAVdMv76P9kffZjYhw20raMlW1HSSvS+MLXC9MmbNZCazMrAr+5jEEgTuw==", - "dev": true, + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.3.tgz", + "integrity": "sha512-fSrR66n0l6roW9Rx4rSLMyTPTjRTiXy5RVqDOurACQ6si1rKHHKDU5gwBJoCsIV0R3o9gi+K50akl/qyw1C74A==", "peerDependencies": { - "@discordjs/opus": "^0.1.0", - "ffmpeg-static": "^2.4.0 || ^3.0.0", - "node-opus": "^0.3.1", - "opusscript": "^0.0.6" + "@discordjs/opus": "^0.3.3", + "ffmpeg-static": "^4.2.7 || ^3.0.0 || ^2.4.0", + "node-opus": "^0.3.3", + "opusscript": "^0.0.7" }, "peerDependenciesMeta": { "@discordjs/opus": { @@ -175,19 +172,17 @@ "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "node_modules/tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" }, "node_modules/typescript": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz", - "integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", + "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -198,10 +193,9 @@ } }, "node_modules/ws": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz", - "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==", - "dev": true, + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", + "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==", "engines": { "node": ">=8.3.0" }, @@ -218,5 +212,126 @@ } } } + }, + "dependencies": { + "@discordjs/collection": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz", + "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ==" + }, + "@discordjs/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "@types/node": { + "version": "14.14.22", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.22.tgz", + "integrity": "sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==", + "dev": true + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "discord.js": { + "version": "12.5.1", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.5.1.tgz", + "integrity": "sha512-VwZkVaUAIOB9mKdca0I5MefPMTQJTNg0qdgi1huF3iwsFwJ0L5s/Y69AQe+iPmjuV6j9rtKoG0Ta0n9vgEIL6w==", + "requires": { + "@discordjs/collection": "^0.1.6", + "@discordjs/form-data": "^3.0.1", + "abort-controller": "^3.0.0", + "node-fetch": "^2.6.1", + "prism-media": "^1.2.2", + "setimmediate": "^1.0.5", + "tweetnacl": "^1.0.3", + "ws": "^7.3.1" + } + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "mime-db": { + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", + "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==" + }, + "mime-types": { + "version": "2.1.28", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", + "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", + "requires": { + "mime-db": "1.45.0" + } + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, + "prism-media": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.3.tgz", + "integrity": "sha512-fSrR66n0l6roW9Rx4rSLMyTPTjRTiXy5RVqDOurACQ6si1rKHHKDU5gwBJoCsIV0R3o9gi+K50akl/qyw1C74A==", + "requires": {} + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "typescript": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", + "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "dev": true + }, + "ws": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", + "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==", + "requires": {} + } } } diff --git a/package.json b/package.json index 643c8b2..9460c3a 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,12 @@ { "description": "A npm package for fetching messages from a Discord Guild or a Discord Channel.", "devDependencies": { - "discord.js": "^12.5.0", - "prettier": "^2.2.0", - "typescript": "^4.1.2" + "@types/node": "^14.14.22", + "prettier": "^2.2.1", + "typescript": "^4.1.3" + }, + "dependencies": { + "discord.js": "^12.5.1" }, "engineStrict": true, "engines": { @@ -16,7 +19,7 @@ "discord-bot", "fetch" ], - "main": "main.js", + "main": "index.js", "name": "discord-fetch-messages", "prettier": { "arrowParens": "avoid", @@ -28,14 +31,16 @@ "trailingComma": "es5", "useTabs": true }, - "types": "./types/main.d.ts", + "types": "types", "readme": "https://github.com/Ayfri/discord-fetch/blob/main/README.md", "repository": { "type": "git", "url": "https://github.com/Ayfri/discord-fetch" }, "scripts": { - "prettier": "prettier --write main.js package.json README.md" + "build": "npm run prettier && tsc", + "prepare": "npm run build", + "prettier": "prettier . --write" }, "version": "1.1.2" } diff --git a/src/Fetcher.ts b/src/Fetcher.ts new file mode 100644 index 0000000..e333d5e --- /dev/null +++ b/src/Fetcher.ts @@ -0,0 +1,82 @@ +import { Client, Message, Collection, Snowflake, TextChannel, Guild } from 'discord.js'; +import { EventEmitter } from 'events'; + +/** + * The main class used to fetch things. + */ +export class Fetcher extends EventEmitter { + /** + * A simple property set to `true` when the Fetcher is fetching a bulk of messages, then set to false. + */ + public fetching: boolean; + + /** + * Creates a new Fetcher. + * + * @param client - Needs the client to fetch things. + */ + public constructor(public readonly client: Client) { + super(); + this.fetching = false; + } + + /** + * Fetch the entire list of messages from a channel, can be long and makes you have rateLimits. + * + * @param channelID - The channel, can be an ID or a Channel. + * @returns The messages fetched. + */ + public async fetchChannel(channelID: Snowflake | TextChannel): Promise> { + const channel = channelID instanceof TextChannel ? channelID : await this.client.channels.fetch(channelID); + let messages = new Collection(); + + if (channel.isText()) { + this.emit('fetchChannel', channel); + this.fetching = true; + let channelMessages = await channel.messages.fetch({ + limit: 100, + }); + this.emit('fetch', channelMessages.size, channelMessages); + + while (channelMessages.size > 0) { + messages = messages.concat(channelMessages); + channelMessages = await channel.messages.fetch({ + limit: 100, + before: channelMessages.last()!.id, + }); + this.emit('fetch', channelMessages.size, channelMessages); + } + + this.fetching = false; + } + return messages; + } + + /** + * Fetch an entire guild, fetching every TextChannels one by one because there is no other way. + * + * @remarks + * Can be really long and you should prefer using events than waiting for it to finish. + * + * @param guildID - The guild to fetch, can be an ID or a Guild. + * @returns The messages fetched. + */ + public async fetchGuild(guildID: Snowflake | Guild): Promise> { + const guild = guildID instanceof Guild ? guildID : await this.client.guilds.fetch(guildID); + let messages = new Collection(); + if (guild) { + this.fetching = true; + const channels = guild.channels.cache.filter(c => c.isText()) as Collection; + this.emit('fetchGuild', guild); + + for (const channel of channels.array()) { + const channelMessages = await this.fetchChannel(channel); + messages = messages.concat(channelMessages); + } + + this.fetching = false; + } + + return messages; + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..c4e3dd8 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,2 @@ +export { fetchChannelMessages, fetchGuildMessages } from './main.js'; +export { Fetcher } from './Fetcher'; diff --git a/main.js b/src/main.js similarity index 64% rename from main.js rename to src/main.js index c0130f9..3e8cf16 100644 --- a/main.js +++ b/src/main.js @@ -1,8 +1,12 @@ +const { deprecate } = require('util'); + /** * Fetch all the messages from a Discord TextChannel. + * * @param {module:"discord.js".Client} client - Your Discord.js Client. * @param {module:"discord.js".TextChannel | module:"discord.js".NewsChannel} channel - The ID of the Discord TextChannel. * @returns {Promise} - All the messages fetched. + * @deprecated Use {@link Fetcher} class instead. */ async function fetchChannelMessages(client, channel) { const total = []; @@ -38,9 +42,10 @@ async function fetchChannelMessages(client, channel) { * @param {module:"discord.js".Client} client - Your Discord.js Client. * @param {string} guildID - The ID of the Guild to be fetch. * @returns {Promise} - All the messages fetched. + * @deprecated Use {@link Fetcher} class instead. */ async function fetchGuildMessages(client, guildID) { - const m = []; + const total = []; const channels = client.guilds.cache.get(guildID).channels.cache.filter(c => c.isText()); console.log( `Getting the messages from these channels : ${channels @@ -49,22 +54,25 @@ async function fetchGuildMessages(client, guildID) { .join('\n')}` ); - for (const channel of channels.array()) { - console.log(`Getting messages from : #${channel.name}.`); - const messages = await fetchChannelMessages(client, channel); + for (const textChannel of channels.array()) { + console.log(`Getting messages from : #${textChannel.name}.`); + const messages = await fetchChannelMessages(client, textChannel); - if (!m.find(c => c.id === channel.id)) - m.push({ - id: channel.id, + if (!total.find(channel => channel.id === textChannel.id)) + total.push({ + id: textChannel.id, messages: [], }); - m.find(c => c.id === channel.id).messages.push(...messages.map(m => m.cleanContent)); + total.find(channel => channel.id === textChannel.id).messages.push(...messages.map(m => m.cleanContent)); } - console.log(`Finished fetching messages, messages count: ${m.length}`); - return m; + console.log(`Finished fetching messages, messages count: ${total.length}`); + return total; } +deprecate(fetchChannelMessages, 'fetchChannelMessages() is deprecated. Use Fetcher class instead.'); +deprecate(fetchGuildMessages, 'fetchGuildMessages() is deprecated. Use Fetcher class instead.'); + module.exports = { fetchGuildMessages, fetchChannelMessages, diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..7e7ee71 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "alwaysStrict": true, + "allowJs": true, + "declaration": true, + "declarationDir": "types", + "lib": ["ESNext"], + "module": "commonjs", + "moduleResolution": "node", + "noImplicitAny": true, + "outDir": "dist", + "pretty": true, + "skipLibCheck": true, + "strict": true, + "target": "esNext" + }, + "exclude": ["node_modules"], + "files": ["src/main.js", "src/index.ts", "src/Fetcher.ts"] +} diff --git a/types/main.d.ts b/types/main.d.ts deleted file mode 100644 index 2ed3b78..0000000 --- a/types/main.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import * as Discord from 'discord.js'; - -declare module 'discord-fetch-messages' { - /** - * Fetch all the messages from a Discord Guild. - * @param {module:"discord.js".Client} client - Your Discord.js Client. - * @param {string} guildID - The ID of the Guild to be fetch. - * @returns {Promise} - All the messages fetched. - */ - export function fetchGuildMessages(client: Discord.Client, guildID: Discord.Snowflake): Promise; - /** - * Fetch all the messages from a Discord TextChannel. - * @param {module:"discord.js".Client} client - Your Discord.js Client. - * @param {module:"discord.js".TextChannel | module:"discord.js".NewsChannel} channel - The ID of the Discord TextChannel. - * @returns {Promise} - All the messages fetched. - */ - export function fetchChannelMessages(client: Discord.Client, channel: Discord.Channel): Promise; -}