Merge branch 'master' into 220601_docker_wip
This commit is contained in:
commit
b48b93a6de
36 changed files with 242 additions and 178 deletions
2
.nvmrc
2
.nvmrc
|
@ -1 +1 @@
|
||||||
16.6
|
16
|
||||||
|
|
183
backend/package-lock.json
generated
183
backend/package-lock.json
generated
|
@ -13,8 +13,8 @@
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cross-env": "^5.2.0",
|
"cross-env": "^5.2.0",
|
||||||
"deep-diff": "^1.0.2",
|
"deep-diff": "^1.0.2",
|
||||||
"discord-api-types": "^0.31.0",
|
"discord-api-types": "^0.33.1",
|
||||||
"discord.js": "^13.6.0",
|
"discord.js": "^13.8.0",
|
||||||
"dotenv": "^4.0.0",
|
"dotenv": "^4.0.0",
|
||||||
"emoji-regex": "^8.0.0",
|
"emoji-regex": "^8.0.0",
|
||||||
"erlpack": "github:discord/erlpack",
|
"erlpack": "github:discord/erlpack",
|
||||||
|
@ -124,23 +124,25 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@discordjs/builders": {
|
"node_modules/@discordjs/builders": {
|
||||||
"version": "0.11.0",
|
"version": "0.14.0",
|
||||||
"license": "Apache-2.0",
|
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.14.0.tgz",
|
||||||
|
"integrity": "sha512-+fqLIqa9wN3R+kvlld8sgG0nt04BAZxdCDP4t2qZ9TJsquLWA+xMtT8Waibb3d4li4AQS+IOfjiHAznv/dhHgQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sindresorhus/is": "^4.2.0",
|
"@sapphire/shapeshift": "^3.1.0",
|
||||||
"discord-api-types": "^0.26.0",
|
"@sindresorhus/is": "^4.6.0",
|
||||||
"ts-mixer": "^6.0.0",
|
"discord-api-types": "^0.33.3",
|
||||||
"tslib": "^2.3.1",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"zod": "^3.11.6"
|
"ts-mixer": "^6.0.1",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.0.0",
|
"node": ">=16.9.0"
|
||||||
"npm": ">=7.0.0"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@discordjs/builders/node_modules/@sindresorhus/is": {
|
"node_modules/@discordjs/builders/node_modules/@sindresorhus/is": {
|
||||||
"version": "4.6.0",
|
"version": "4.6.0",
|
||||||
"license": "MIT",
|
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
|
||||||
|
"integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
},
|
},
|
||||||
|
@ -148,23 +150,17 @@
|
||||||
"url": "https://github.com/sindresorhus/is?sponsor=1"
|
"url": "https://github.com/sindresorhus/is?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@discordjs/builders/node_modules/discord-api-types": {
|
|
||||||
"version": "0.26.1",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@discordjs/builders/node_modules/tslib": {
|
"node_modules/@discordjs/builders/node_modules/tslib": {
|
||||||
"version": "2.3.1",
|
"version": "2.4.0",
|
||||||
"license": "0BSD"
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@discordjs/collection": {
|
"node_modules/@discordjs/collection": {
|
||||||
"version": "0.4.0",
|
"version": "0.7.0",
|
||||||
"license": "Apache-2.0",
|
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz",
|
||||||
|
"integrity": "sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.0.0",
|
"node": ">=16.9.0"
|
||||||
"npm": ">=7.0.0"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@nodelib/fs.scandir": {
|
"node_modules/@nodelib/fs.scandir": {
|
||||||
|
@ -207,6 +203,15 @@
|
||||||
"npm": ">=7.0.0"
|
"npm": ">=7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@sapphire/shapeshift": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-PkxFXd3QJ1qAPS05Dy2UkVGYPm/asF1Ugt2Xyzmv4DHzO3+G7l+873C4XFFcJ9M5Je+eCMC7SSifgPTSur5QuA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=v15.0.0",
|
||||||
|
"npm": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@silvia-odwyer/photon-node": {
|
"node_modules/@silvia-odwyer/photon-node": {
|
||||||
"version": "0.3.1",
|
"version": "0.3.1",
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
|
@ -344,8 +349,9 @@
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/node-fetch": {
|
"node_modules/@types/node-fetch": {
|
||||||
"version": "2.5.12",
|
"version": "2.6.1",
|
||||||
"license": "MIT",
|
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
"form-data": "^3.0.0"
|
"form-data": "^3.0.0"
|
||||||
|
@ -1693,35 +1699,30 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/discord-api-types": {
|
"node_modules/discord-api-types": {
|
||||||
"version": "0.31.0",
|
"version": "0.33.4",
|
||||||
"license": "MIT"
|
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.4.tgz",
|
||||||
|
"integrity": "sha512-Y6RMvXsHKiBgQhm/q5MgRieXc4Tzh5p/JuDyqreI48lmy+AQfO+g9Xhz0tuGBaN1FtsrLT7mD+lbFONPo5vdwA=="
|
||||||
},
|
},
|
||||||
"node_modules/discord.js": {
|
"node_modules/discord.js": {
|
||||||
"version": "13.6.0",
|
"version": "13.8.0",
|
||||||
"license": "Apache-2.0",
|
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.8.0.tgz",
|
||||||
|
"integrity": "sha512-EPAA/2VLycYN5wSzavqa4iJ6qj3UtQFtHw5TH/60Fj29ymfEsCQVn//o1mTpwDxzwb+rPIrWhkxKIGGnjfv0Iw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@discordjs/builders": "^0.11.0",
|
"@discordjs/builders": "^0.14.0",
|
||||||
"@discordjs/collection": "^0.4.0",
|
"@discordjs/collection": "^0.7.0",
|
||||||
"@sapphire/async-queue": "^1.1.9",
|
"@sapphire/async-queue": "^1.3.1",
|
||||||
"@types/node-fetch": "^2.5.12",
|
"@types/node-fetch": "^2.6.1",
|
||||||
"@types/ws": "^8.2.2",
|
"@types/ws": "^8.5.3",
|
||||||
"discord-api-types": "^0.26.0",
|
"discord-api-types": "^0.33.3",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.1",
|
||||||
"ws": "^8.4.0"
|
"ws": "^8.7.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.6.0",
|
"node": ">=16.6.0",
|
||||||
"npm": ">=7.0.0"
|
"npm": ">=7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/discord.js/node_modules/discord-api-types": {
|
|
||||||
"version": "0.26.1",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/discord.js/node_modules/form-data": {
|
"node_modules/discord.js/node_modules/form-data": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -1941,6 +1942,11 @@
|
||||||
"node": ">= 0.10.0"
|
"node": ">= 0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-deep-equal": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||||
|
},
|
||||||
"node_modules/fast-diff": {
|
"node_modules/fast-diff": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
@ -4506,7 +4512,8 @@
|
||||||
},
|
},
|
||||||
"node_modules/ts-mixer": {
|
"node_modules/ts-mixer": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"license": "MIT"
|
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-hvE+ZYXuINrx6Ei6D6hz+PTim0Uf++dYbK9FFifLNwQj+RwKquhQpn868yZsCtJYiclZF1u8l6WZxxKi+vv7Rg=="
|
||||||
},
|
},
|
||||||
"node_modules/tsc-watch": {
|
"node_modules/tsc-watch": {
|
||||||
"version": "5.0.2",
|
"version": "5.0.2",
|
||||||
|
@ -5106,8 +5113,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ws": {
|
"node_modules/ws": {
|
||||||
"version": "8.5.0",
|
"version": "8.7.0",
|
||||||
"license": "MIT",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz",
|
||||||
|
"integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
},
|
},
|
||||||
|
@ -5305,28 +5313,34 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@discordjs/builders": {
|
"@discordjs/builders": {
|
||||||
"version": "0.11.0",
|
"version": "0.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.14.0.tgz",
|
||||||
|
"integrity": "sha512-+fqLIqa9wN3R+kvlld8sgG0nt04BAZxdCDP4t2qZ9TJsquLWA+xMtT8Waibb3d4li4AQS+IOfjiHAznv/dhHgQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sindresorhus/is": "^4.2.0",
|
"@sapphire/shapeshift": "^3.1.0",
|
||||||
"discord-api-types": "^0.26.0",
|
"@sindresorhus/is": "^4.6.0",
|
||||||
"ts-mixer": "^6.0.0",
|
"discord-api-types": "^0.33.3",
|
||||||
"tslib": "^2.3.1",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"zod": "^3.11.6"
|
"ts-mixer": "^6.0.1",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sindresorhus/is": {
|
"@sindresorhus/is": {
|
||||||
"version": "4.6.0"
|
"version": "4.6.0",
|
||||||
},
|
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
|
||||||
"discord-api-types": {
|
"integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="
|
||||||
"version": "0.26.1"
|
|
||||||
},
|
},
|
||||||
"tslib": {
|
"tslib": {
|
||||||
"version": "2.3.1"
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@discordjs/collection": {
|
"@discordjs/collection": {
|
||||||
"version": "0.4.0"
|
"version": "0.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz",
|
||||||
|
"integrity": "sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA=="
|
||||||
},
|
},
|
||||||
"@nodelib/fs.scandir": {
|
"@nodelib/fs.scandir": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
|
@ -5351,6 +5365,11 @@
|
||||||
"@sapphire/async-queue": {
|
"@sapphire/async-queue": {
|
||||||
"version": "1.3.1"
|
"version": "1.3.1"
|
||||||
},
|
},
|
||||||
|
"@sapphire/shapeshift": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-PkxFXd3QJ1qAPS05Dy2UkVGYPm/asF1Ugt2Xyzmv4DHzO3+G7l+873C4XFFcJ9M5Je+eCMC7SSifgPTSur5QuA=="
|
||||||
|
},
|
||||||
"@silvia-odwyer/photon-node": {
|
"@silvia-odwyer/photon-node": {
|
||||||
"version": "0.3.1"
|
"version": "0.3.1"
|
||||||
},
|
},
|
||||||
|
@ -5462,7 +5481,9 @@
|
||||||
"version": "14.0.14"
|
"version": "14.0.14"
|
||||||
},
|
},
|
||||||
"@types/node-fetch": {
|
"@types/node-fetch": {
|
||||||
"version": "2.5.12",
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
"form-data": "^3.0.0"
|
"form-data": "^3.0.0"
|
||||||
|
@ -6346,25 +6367,26 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"discord-api-types": {
|
"discord-api-types": {
|
||||||
"version": "0.31.0"
|
"version": "0.33.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.4.tgz",
|
||||||
|
"integrity": "sha512-Y6RMvXsHKiBgQhm/q5MgRieXc4Tzh5p/JuDyqreI48lmy+AQfO+g9Xhz0tuGBaN1FtsrLT7mD+lbFONPo5vdwA=="
|
||||||
},
|
},
|
||||||
"discord.js": {
|
"discord.js": {
|
||||||
"version": "13.6.0",
|
"version": "13.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.8.0.tgz",
|
||||||
|
"integrity": "sha512-EPAA/2VLycYN5wSzavqa4iJ6qj3UtQFtHw5TH/60Fj29ymfEsCQVn//o1mTpwDxzwb+rPIrWhkxKIGGnjfv0Iw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@discordjs/builders": "^0.11.0",
|
"@discordjs/builders": "^0.14.0",
|
||||||
"@discordjs/collection": "^0.4.0",
|
"@discordjs/collection": "^0.7.0",
|
||||||
"@sapphire/async-queue": "^1.1.9",
|
"@sapphire/async-queue": "^1.3.1",
|
||||||
"@types/node-fetch": "^2.5.12",
|
"@types/node-fetch": "^2.6.1",
|
||||||
"@types/ws": "^8.2.2",
|
"@types/ws": "^8.5.3",
|
||||||
"discord-api-types": "^0.26.0",
|
"discord-api-types": "^0.33.3",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.1",
|
||||||
"ws": "^8.4.0"
|
"ws": "^8.7.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"discord-api-types": {
|
|
||||||
"version": "0.26.1"
|
|
||||||
},
|
|
||||||
"form-data": {
|
"form-data": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"requires": {
|
"requires": {
|
||||||
|
@ -6425,7 +6447,7 @@
|
||||||
},
|
},
|
||||||
"erlpack": {
|
"erlpack": {
|
||||||
"version": "git+ssh://git@github.com/discord/erlpack.git#3b793a333dd3f6a140b9168ea91e9fa9660753ce",
|
"version": "git+ssh://git@github.com/discord/erlpack.git#3b793a333dd3f6a140b9168ea91e9fa9660753ce",
|
||||||
"from": "erlpack@github:discord/erlpack.git",
|
"from": "erlpack@github:discord/erlpack",
|
||||||
"requires": {
|
"requires": {
|
||||||
"bindings": "^1.5.0",
|
"bindings": "^1.5.0",
|
||||||
"nan": "^2.15.0"
|
"nan": "^2.15.0"
|
||||||
|
@ -6513,6 +6535,11 @@
|
||||||
"vary": "~1.1.2"
|
"vary": "~1.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fast-deep-equal": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||||
|
},
|
||||||
"fast-diff": {
|
"fast-diff": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"dev": true
|
"dev": true
|
||||||
|
@ -8117,7 +8144,9 @@
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"ts-mixer": {
|
"ts-mixer": {
|
||||||
"version": "6.0.1"
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-hvE+ZYXuINrx6Ei6D6hz+PTim0Uf++dYbK9FFifLNwQj+RwKquhQpn868yZsCtJYiclZF1u8l6WZxxKi+vv7Rg=="
|
||||||
},
|
},
|
||||||
"tsc-watch": {
|
"tsc-watch": {
|
||||||
"version": "5.0.2",
|
"version": "5.0.2",
|
||||||
|
@ -8491,7 +8520,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ws": {
|
"ws": {
|
||||||
"version": "8.5.0",
|
"version": "8.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz",
|
||||||
|
"integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==",
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"xdg-basedir": {
|
"xdg-basedir": {
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cross-env": "^5.2.0",
|
"cross-env": "^5.2.0",
|
||||||
"deep-diff": "^1.0.2",
|
"deep-diff": "^1.0.2",
|
||||||
"discord-api-types": "^0.31.0",
|
"discord-api-types": "^0.33.1",
|
||||||
"discord.js": "^13.6.0",
|
"discord.js": "^13.8.0",
|
||||||
"dotenv": "^4.0.0",
|
"dotenv": "^4.0.0",
|
||||||
"emoji-regex": "^8.0.0",
|
"emoji-regex": "^8.0.0",
|
||||||
"erlpack": "github:discord/erlpack",
|
"erlpack": "github:discord/erlpack",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { GuildChannel, GuildMember, Snowflake, Util, User } from "discord.js";
|
import { GuildChannel, GuildMember, Snowflake, Util, User, GuildTextBasedChannel } from "discord.js";
|
||||||
import { baseCommandParameterTypeHelpers, baseTypeConverters, CommandContext, TypeConversionError } from "knub";
|
import { baseCommandParameterTypeHelpers, baseTypeConverters, CommandContext, TypeConversionError } from "knub";
|
||||||
import { createTypeHelper } from "knub-command-manager";
|
import { createTypeHelper } from "knub-command-manager";
|
||||||
import {
|
import {
|
||||||
|
@ -14,6 +14,8 @@ import {
|
||||||
import { isValidTimezone } from "./utils/isValidTimezone";
|
import { isValidTimezone } from "./utils/isValidTimezone";
|
||||||
import { MessageTarget, resolveMessageTarget } from "./utils/resolveMessageTarget";
|
import { MessageTarget, resolveMessageTarget } from "./utils/resolveMessageTarget";
|
||||||
import { inputPatternToRegExp } from "./validatorUtils";
|
import { inputPatternToRegExp } from "./validatorUtils";
|
||||||
|
import { getChannelId } from "knub/dist/utils";
|
||||||
|
import { disableCodeBlocks } from "knub/dist/helpers";
|
||||||
|
|
||||||
export const commandTypes = {
|
export const commandTypes = {
|
||||||
...baseTypeConverters,
|
...baseTypeConverters,
|
||||||
|
@ -100,6 +102,11 @@ export const commandTypes = {
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
guildTextBasedChannel(value: string, context: CommandContext<any>) {
|
||||||
|
// FIXME: Remove once Knub's types have been fixed
|
||||||
|
return baseTypeConverters.textChannel(value, context) as GuildTextBasedChannel;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const commandTypeHelpers = {
|
export const commandTypeHelpers = {
|
||||||
|
@ -113,4 +120,5 @@ export const commandTypeHelpers = {
|
||||||
anyId: createTypeHelper<Promise<Snowflake>>(commandTypes.anyId),
|
anyId: createTypeHelper<Promise<Snowflake>>(commandTypes.anyId),
|
||||||
regex: createTypeHelper<RegExp>(commandTypes.regex),
|
regex: createTypeHelper<RegExp>(commandTypes.regex),
|
||||||
timezone: createTypeHelper<string>(commandTypes.timezone),
|
timezone: createTypeHelper<string>(commandTypes.timezone),
|
||||||
|
guildTextBasedChannel: createTypeHelper<GuildTextBasedChannel>(commandTypes.guildTextBasedChannel),
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,7 +15,7 @@ export const NewAutoReactionsCmd = autoReactionsCmd({
|
||||||
usage: "!auto_reactions 629990160477585428 👍 👎",
|
usage: "!auto_reactions 629990160477585428 👍 👎",
|
||||||
|
|
||||||
signature: {
|
signature: {
|
||||||
channel: ct.channel(),
|
channel: ct.guildTextBasedChannel(),
|
||||||
reactions: ct.string({ rest: true }),
|
reactions: ct.string({ rest: true }),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ export const NewAutoReactionsCmd = autoReactionsCmd({
|
||||||
const finalReactions: string[] = [];
|
const finalReactions: string[] = [];
|
||||||
|
|
||||||
const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!;
|
const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!;
|
||||||
const missingPermissions = getMissingChannelPermissions(me, args.channel as GuildChannel, requiredPermissions);
|
const missingPermissions = getMissingChannelPermissions(me, args.channel, requiredPermissions);
|
||||||
if (missingPermissions) {
|
if (missingPermissions) {
|
||||||
sendErrorMessage(
|
sendErrorMessage(
|
||||||
pluginData,
|
pluginData,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { GuildChannel, Permissions } from "discord.js";
|
import { GuildChannel, GuildTextBasedChannel, Permissions } from "discord.js";
|
||||||
import { LogType } from "../../../data/LogType";
|
import { LogType } from "../../../data/LogType";
|
||||||
import { isDiscordAPIError } from "../../../utils";
|
import { isDiscordAPIError } from "../../../utils";
|
||||||
import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions";
|
import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions";
|
||||||
|
@ -16,13 +16,21 @@ export const AddReactionsEvt = autoReactionsEvt({
|
||||||
allowSelf: true,
|
allowSelf: true,
|
||||||
|
|
||||||
async listener({ pluginData, args: { message } }) {
|
async listener({ pluginData, args: { message } }) {
|
||||||
|
const channel = (await message.guild?.channels.fetch(message.channelId)) as
|
||||||
|
| GuildTextBasedChannel
|
||||||
|
| null
|
||||||
|
| undefined;
|
||||||
|
if (!channel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let autoReaction: AutoReaction | null = null;
|
let autoReaction: AutoReaction | null = null;
|
||||||
const lock = await pluginData.locks.acquire(`auto-reactions-${message.channel.id}`);
|
const lock = await pluginData.locks.acquire(`auto-reactions-${channel.id}`);
|
||||||
if (pluginData.state.cache.has(message.channel.id)) {
|
if (pluginData.state.cache.has(channel.id)) {
|
||||||
autoReaction = pluginData.state.cache.get(message.channel.id) ?? null;
|
autoReaction = pluginData.state.cache.get(channel.id) ?? null;
|
||||||
} else {
|
} else {
|
||||||
autoReaction = (await pluginData.state.autoReactions.getForChannel(message.channel.id)) ?? null;
|
autoReaction = (await pluginData.state.autoReactions.getForChannel(channel.id)) ?? null;
|
||||||
pluginData.state.cache.set(message.channel.id, autoReaction);
|
pluginData.state.cache.set(channel.id, autoReaction);
|
||||||
}
|
}
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
|
@ -32,17 +40,11 @@ export const AddReactionsEvt = autoReactionsEvt({
|
||||||
|
|
||||||
const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!;
|
const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!;
|
||||||
if (me) {
|
if (me) {
|
||||||
const missingPermissions = getMissingChannelPermissions(
|
const missingPermissions = getMissingChannelPermissions(me, channel, readChannelPermissions | p.ADD_REACTIONS);
|
||||||
me,
|
|
||||||
message.channel as GuildChannel,
|
|
||||||
readChannelPermissions | p.ADD_REACTIONS,
|
|
||||||
);
|
|
||||||
if (missingPermissions) {
|
if (missingPermissions) {
|
||||||
const logs = pluginData.getPlugin(LogsPlugin);
|
const logs = pluginData.getPlugin(LogsPlugin);
|
||||||
logs.logBotAlert({
|
logs.logBotAlert({
|
||||||
body: `Cannot apply auto-reactions in <#${message.channel.id}>. ${missingPermissionError(
|
body: `Cannot apply auto-reactions in <#${channel.id}>. ${missingPermissionError(missingPermissions)}`,
|
||||||
missingPermissions,
|
|
||||||
)}`,
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -56,11 +58,11 @@ export const AddReactionsEvt = autoReactionsEvt({
|
||||||
const logs = pluginData.getPlugin(LogsPlugin);
|
const logs = pluginData.getPlugin(LogsPlugin);
|
||||||
if (e.code === 10008) {
|
if (e.code === 10008) {
|
||||||
logs.logBotAlert({
|
logs.logBotAlert({
|
||||||
body: `Could not apply auto-reactions in <#${message.channel.id}> for message \`${message.id}\`. Make sure nothing is deleting the message before the reactions are applied.`,
|
body: `Could not apply auto-reactions in <#${channel.id}> for message \`${message.id}\`. Make sure nothing is deleting the message before the reactions are applied.`,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
logs.logBotAlert({
|
logs.logBotAlert({
|
||||||
body: `Could not apply auto-reactions in <#${message.channel.id}> for message \`${message.id}\`. Error code ${e.code}.`,
|
body: `Could not apply auto-reactions in <#${channel.id}> for message \`${message.id}\`. Error code ${e.code}.`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ export const AlertAction = automodAction({
|
||||||
const channel = pluginData.guild.channels.cache.get(actionConfig.channel as Snowflake);
|
const channel = pluginData.guild.channels.cache.get(actionConfig.channel as Snowflake);
|
||||||
const logs = pluginData.getPlugin(LogsPlugin);
|
const logs = pluginData.getPlugin(LogsPlugin);
|
||||||
|
|
||||||
if (channel && channel instanceof TextChannel) {
|
if (channel?.isText()) {
|
||||||
const text = actionConfig.text;
|
const text = actionConfig.text;
|
||||||
const theMessageLink =
|
const theMessageLink =
|
||||||
contexts[0].message && messageLink(pluginData.guild.id, contexts[0].message.channel_id, contexts[0].message.id);
|
contexts[0].message && messageLink(pluginData.guild.id, contexts[0].message.channel_id, contexts[0].message.id);
|
||||||
|
|
|
@ -36,7 +36,7 @@ export const ReplyAction = automodAction({
|
||||||
.filter((c) => c.message?.channel_id)
|
.filter((c) => c.message?.channel_id)
|
||||||
.filter((c) => {
|
.filter((c) => {
|
||||||
const channel = pluginData.guild.channels.cache.get(c.message!.channel_id as Snowflake);
|
const channel = pluginData.guild.channels.cache.get(c.message!.channel_id as Snowflake);
|
||||||
return channel instanceof TextChannel || channel instanceof ThreadChannel;
|
return channel?.isText();
|
||||||
});
|
});
|
||||||
|
|
||||||
const contextsByChannelId = contextsWithTextChannels.reduce((map: Map<string, AutomodContext[]>, context) => {
|
const contextsByChannelId = contextsWithTextChannels.reduce((map: Map<string, AutomodContext[]>, context) => {
|
||||||
|
|
|
@ -19,7 +19,7 @@ export function resolveActionContactMethods(
|
||||||
}
|
}
|
||||||
|
|
||||||
const channel = pluginData.guild.channels.cache.get(actionConfig.notifyChannel as Snowflake);
|
const channel = pluginData.guild.channels.cache.get(actionConfig.notifyChannel as Snowflake);
|
||||||
if (!(channel instanceof TextChannel || channel instanceof ThreadChannel)) {
|
if (!channel?.isText()) {
|
||||||
throw new RecoverablePluginError(ERRORS.INVALID_USER_NOTIFICATION_CHANNEL);
|
throw new RecoverablePluginError(ERRORS.INVALID_USER_NOTIFICATION_CHANNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { BaseGuildTextChannel, Snowflake, TextChannel, ThreadChannel } from "discord.js";
|
import { BaseGuildTextChannel, GuildTextBasedChannel, Snowflake, TextChannel, ThreadChannel } from "discord.js";
|
||||||
import { GuildPluginData } from "knub";
|
import { GuildPluginData } from "knub";
|
||||||
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
||||||
import { SavedMessage } from "../../../data/entities/SavedMessage";
|
import { SavedMessage } from "../../../data/entities/SavedMessage";
|
||||||
|
@ -22,9 +22,7 @@ export async function censorMessage(
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await resolveUser(pluginData.client, savedMessage.user_id);
|
const user = await resolveUser(pluginData.client, savedMessage.user_id);
|
||||||
const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake)! as
|
const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake)! as GuildTextBasedChannel;
|
||||||
| BaseGuildTextChannel
|
|
||||||
| ThreadChannel;
|
|
||||||
|
|
||||||
pluginData.getPlugin(LogsPlugin).logCensor({
|
pluginData.getPlugin(LogsPlugin).logCensor({
|
||||||
user,
|
user,
|
||||||
|
|
|
@ -20,17 +20,17 @@ export const ViewCounterCmd = typedGuildCommand<CountersPluginType>()({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
counterName: ct.string(),
|
counterName: ct.string(),
|
||||||
channel: ct.textChannel(),
|
channel: ct.guildTextBasedChannel(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
counterName: ct.string(),
|
counterName: ct.string(),
|
||||||
channel: ct.textChannel(),
|
channel: ct.guildTextBasedChannel(),
|
||||||
user: ct.resolvedUser(),
|
user: ct.resolvedUser(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
counterName: ct.string(),
|
counterName: ct.string(),
|
||||||
user: ct.resolvedUser(),
|
user: ct.resolvedUser(),
|
||||||
channel: ct.textChannel(),
|
channel: ct.guildTextBasedChannel(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ export const ViewCounterCmd = typedGuildCommand<CountersPluginType>()({
|
||||||
}
|
}
|
||||||
|
|
||||||
const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake);
|
const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake);
|
||||||
if (!potentialChannel || !(potentialChannel instanceof TextChannel)) {
|
if (!potentialChannel?.isText()) {
|
||||||
sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling");
|
sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
import { Message, MessageOptions, NewsChannel, TextChannel, WebhookClient } from "discord.js";
|
import {
|
||||||
|
Message,
|
||||||
|
MessageEditOptions,
|
||||||
|
NewsChannel,
|
||||||
|
TextChannel,
|
||||||
|
WebhookClient,
|
||||||
|
WebhookEditMessageOptions,
|
||||||
|
} from "discord.js";
|
||||||
import { GuildPluginData } from "knub";
|
import { GuildPluginData } from "knub";
|
||||||
import { InternalPosterPluginType } from "../types";
|
import { InternalPosterPluginType } from "../types";
|
||||||
import { isDiscordAPIError, noop } from "../../../utils";
|
import { isDiscordAPIError, noop } from "../../../utils";
|
||||||
|
@ -9,7 +16,7 @@ import { isDiscordAPIError, noop } from "../../../utils";
|
||||||
export async function editMessage(
|
export async function editMessage(
|
||||||
pluginData: GuildPluginData<InternalPosterPluginType>,
|
pluginData: GuildPluginData<InternalPosterPluginType>,
|
||||||
message: Message,
|
message: Message,
|
||||||
content: MessageOptions,
|
content: MessageEditOptions & WebhookEditMessageOptions,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!(message.channel instanceof TextChannel || message.channel instanceof NewsChannel)) {
|
if (!(message.channel instanceof TextChannel || message.channel instanceof NewsChannel)) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { GuildPluginData } from "knub";
|
import { GuildPluginData } from "knub";
|
||||||
import { InternalPosterPluginType } from "../types";
|
import { InternalPosterPluginType } from "../types";
|
||||||
import { NewsChannel, TextChannel, WebhookClient } from "discord.js";
|
import { WebhookClient } from "discord.js";
|
||||||
import { getOrCreateWebhookForChannel } from "./getOrCreateWebhookForChannel";
|
import { getOrCreateWebhookForChannel, WebhookableChannel } from "./getOrCreateWebhookForChannel";
|
||||||
|
|
||||||
export async function getOrCreateWebhookClientForChannel(
|
export async function getOrCreateWebhookClientForChannel(
|
||||||
pluginData: GuildPluginData<InternalPosterPluginType>,
|
pluginData: GuildPluginData<InternalPosterPluginType>,
|
||||||
channel: TextChannel | NewsChannel,
|
channel: WebhookableChannel,
|
||||||
): Promise<WebhookClient | null> {
|
): Promise<WebhookClient | null> {
|
||||||
if (!pluginData.state.webhookClientCache.has(channel.id)) {
|
if (!pluginData.state.webhookClientCache.has(channel.id)) {
|
||||||
const webhookInfo = await getOrCreateWebhookForChannel(pluginData, channel);
|
const webhookInfo = await getOrCreateWebhookForChannel(pluginData, channel);
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
import { GuildPluginData } from "knub";
|
import { GuildPluginData } from "knub";
|
||||||
import { InternalPosterPluginType } from "../types";
|
import { InternalPosterPluginType } from "../types";
|
||||||
import { NewsChannel, Permissions, TextChannel } from "discord.js";
|
import { AnyChannel, GuildChannel, MessageManager, NewsChannel, Permissions, TextChannel } from "discord.js";
|
||||||
import { isDiscordAPIError } from "../../../utils";
|
import { isDiscordAPIError } from "../../../utils";
|
||||||
|
|
||||||
type WebhookInfo = [id: string, token: string];
|
type WebhookInfo = [id: string, token: string];
|
||||||
|
|
||||||
|
export type WebhookableChannel = Extract<AnyChannel, { createWebhook: (...args: any[]) => any }>;
|
||||||
|
|
||||||
|
export function channelIsWebhookable(channel: AnyChannel): channel is WebhookableChannel {
|
||||||
|
return "createWebhook" in channel;
|
||||||
|
}
|
||||||
|
|
||||||
export async function getOrCreateWebhookForChannel(
|
export async function getOrCreateWebhookForChannel(
|
||||||
pluginData: GuildPluginData<InternalPosterPluginType>,
|
pluginData: GuildPluginData<InternalPosterPluginType>,
|
||||||
channel: TextChannel | NewsChannel,
|
channel: WebhookableChannel,
|
||||||
): Promise<WebhookInfo | null> {
|
): Promise<WebhookInfo | null> {
|
||||||
// tslint:disable-next-line:no-console FIXME: Here for debugging purposes
|
|
||||||
console.log(`getOrCreateWebhookForChannel(${channel.id})`);
|
|
||||||
|
|
||||||
// Database cache
|
// Database cache
|
||||||
const fromDb = await pluginData.state.webhooks.findByChannelId(channel.id);
|
const fromDb = await pluginData.state.webhooks.findByChannelId(channel.id);
|
||||||
if (fromDb) {
|
if (fromDb) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Message, MessageOptions, NewsChannel, TextChannel, WebhookClient } from "discord.js";
|
import { GuildTextBasedChannel, Message, MessageOptions, NewsChannel, TextChannel, WebhookClient } from "discord.js";
|
||||||
import { GuildPluginData } from "knub";
|
import { GuildPluginData } from "knub";
|
||||||
import { InternalPosterPluginType } from "../types";
|
import { InternalPosterPluginType } from "../types";
|
||||||
import { getOrCreateWebhookForChannel } from "./getOrCreateWebhookForChannel";
|
import { channelIsWebhookable, getOrCreateWebhookForChannel } from "./getOrCreateWebhookForChannel";
|
||||||
import { APIMessage } from "discord-api-types";
|
import { APIMessage } from "discord-api-types";
|
||||||
import { isDiscordAPIError } from "../../../utils";
|
import { isDiscordAPIError } from "../../../utils";
|
||||||
import { getOrCreateWebhookClientForChannel } from "./getOrCreateWebhookClientForChannel";
|
import { getOrCreateWebhookClientForChannel } from "./getOrCreateWebhookClientForChannel";
|
||||||
|
@ -12,7 +12,7 @@ export type InternalPosterMessageResult = {
|
||||||
};
|
};
|
||||||
|
|
||||||
async function sendDirectly(
|
async function sendDirectly(
|
||||||
channel: TextChannel | NewsChannel,
|
channel: GuildTextBasedChannel,
|
||||||
content: MessageOptions,
|
content: MessageOptions,
|
||||||
): Promise<InternalPosterMessageResult | null> {
|
): Promise<InternalPosterMessageResult | null> {
|
||||||
return channel.send(content).then((message) => ({
|
return channel.send(content).then((message) => ({
|
||||||
|
@ -26,17 +26,26 @@ async function sendDirectly(
|
||||||
*/
|
*/
|
||||||
export async function sendMessage(
|
export async function sendMessage(
|
||||||
pluginData: GuildPluginData<InternalPosterPluginType>,
|
pluginData: GuildPluginData<InternalPosterPluginType>,
|
||||||
channel: TextChannel | NewsChannel,
|
channel: GuildTextBasedChannel,
|
||||||
content: MessageOptions,
|
content: MessageOptions,
|
||||||
): Promise<InternalPosterMessageResult | null> {
|
): Promise<InternalPosterMessageResult | null> {
|
||||||
return pluginData.state.queue.add(async () => {
|
return pluginData.state.queue.add(async () => {
|
||||||
const webhookClient = await getOrCreateWebhookClientForChannel(pluginData, channel);
|
let webhookClient: WebhookClient | null = null;
|
||||||
|
let threadId: string | undefined;
|
||||||
|
if (channelIsWebhookable(channel)) {
|
||||||
|
webhookClient = await getOrCreateWebhookClientForChannel(pluginData, channel);
|
||||||
|
} else if (channel.isThread() && channelIsWebhookable(channel.parent!)) {
|
||||||
|
webhookClient = await getOrCreateWebhookClientForChannel(pluginData, channel.parent!);
|
||||||
|
threadId = channel.id;
|
||||||
|
}
|
||||||
|
|
||||||
if (!webhookClient) {
|
if (!webhookClient) {
|
||||||
return sendDirectly(channel, content);
|
return sendDirectly(channel, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
return webhookClient
|
return webhookClient
|
||||||
.send({
|
.send({
|
||||||
|
threadId,
|
||||||
...content,
|
...content,
|
||||||
...(pluginData.client.user && {
|
...(pluginData.client.user && {
|
||||||
username: pluginData.client.user.username,
|
username: pluginData.client.user.username,
|
||||||
|
@ -50,7 +59,7 @@ export async function sendMessage(
|
||||||
.catch(async (err) => {
|
.catch(async (err) => {
|
||||||
// Unknown Webhook
|
// Unknown Webhook
|
||||||
if (isDiscordAPIError(err) && err.code === 10015) {
|
if (isDiscordAPIError(err) && err.code === 10015) {
|
||||||
await pluginData.state.webhooks.delete(webhookClient.id);
|
await pluginData.state.webhooks.delete(webhookClient!.id);
|
||||||
pluginData.state.webhookClientCache.delete(channel.id);
|
pluginData.state.webhookClientCache.delete(channel.id);
|
||||||
|
|
||||||
// Fallback to regular message for this log message
|
// Fallback to regular message for this log message
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { LogsPluginType } from "../types";
|
||||||
import { LogType } from "../../../data/LogType";
|
import { LogType } from "../../../data/LogType";
|
||||||
import { log } from "../util/log";
|
import { log } from "../util/log";
|
||||||
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
||||||
import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js";
|
import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js";
|
||||||
import {
|
import {
|
||||||
channelToTemplateSafeChannel,
|
channelToTemplateSafeChannel,
|
||||||
savedMessageToTemplateSafeSavedMessage,
|
savedMessageToTemplateSafeSavedMessage,
|
||||||
|
@ -15,7 +15,7 @@ import { deactivateMentions, disableCodeBlocks } from "knub/dist/helpers";
|
||||||
|
|
||||||
interface LogCensorData {
|
interface LogCensorData {
|
||||||
user: User | UnknownUser;
|
user: User | UnknownUser;
|
||||||
channel: BaseGuildTextChannel | ThreadChannel;
|
channel: GuildTextBasedChannel;
|
||||||
reason: string;
|
reason: string;
|
||||||
message: SavedMessage;
|
message: SavedMessage;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { FORMAT_NO_TIMESTAMP, LogsPluginType } from "../types";
|
||||||
import { LogType } from "../../../data/LogType";
|
import { LogType } from "../../../data/LogType";
|
||||||
import { log } from "../util/log";
|
import { log } from "../util/log";
|
||||||
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
||||||
import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js";
|
import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js";
|
||||||
import {
|
import {
|
||||||
channelToTemplateSafeChannel,
|
channelToTemplateSafeChannel,
|
||||||
savedMessageToTemplateSafeSavedMessage,
|
savedMessageToTemplateSafeSavedMessage,
|
||||||
|
@ -16,7 +16,7 @@ import { UnknownUser, useMediaUrls } from "../../../utils";
|
||||||
|
|
||||||
interface LogMessageDeleteData {
|
interface LogMessageDeleteData {
|
||||||
user: User | UnknownUser;
|
user: User | UnknownUser;
|
||||||
channel: BaseGuildTextChannel | ThreadChannel;
|
channel: GuildTextBasedChannel;
|
||||||
message: SavedMessage;
|
message: SavedMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,12 @@ import { LogsPluginType } from "../types";
|
||||||
import { LogType } from "../../../data/LogType";
|
import { LogType } from "../../../data/LogType";
|
||||||
import { log } from "../util/log";
|
import { log } from "../util/log";
|
||||||
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
||||||
import { BaseGuildTextChannel, ThreadChannel } from "discord.js";
|
import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel } from "discord.js";
|
||||||
import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects";
|
import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects";
|
||||||
|
|
||||||
interface LogMessageDeleteBareData {
|
interface LogMessageDeleteBareData {
|
||||||
messageId: string;
|
messageId: string;
|
||||||
channel: BaseGuildTextChannel | ThreadChannel;
|
channel: GuildTextBasedChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function logMessageDeleteBare(pluginData: GuildPluginData<LogsPluginType>, data: LogMessageDeleteBareData) {
|
export function logMessageDeleteBare(pluginData: GuildPluginData<LogsPluginType>, data: LogMessageDeleteBareData) {
|
||||||
|
|
|
@ -3,13 +3,13 @@ import { LogsPluginType } from "../types";
|
||||||
import { LogType } from "../../../data/LogType";
|
import { LogType } from "../../../data/LogType";
|
||||||
import { log } from "../util/log";
|
import { log } from "../util/log";
|
||||||
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
||||||
import { BaseGuildTextChannel, ThreadChannel } from "discord.js";
|
import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel } from "discord.js";
|
||||||
import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects";
|
import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects";
|
||||||
|
|
||||||
interface LogMessageDeleteBulkData {
|
interface LogMessageDeleteBulkData {
|
||||||
count: number;
|
count: number;
|
||||||
authorIds: string[];
|
authorIds: string[];
|
||||||
channel: BaseGuildTextChannel | ThreadChannel;
|
channel: GuildTextBasedChannel;
|
||||||
archiveUrl: string;
|
archiveUrl: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { LogsPluginType } from "../types";
|
||||||
import { LogType } from "../../../data/LogType";
|
import { LogType } from "../../../data/LogType";
|
||||||
import { log } from "../util/log";
|
import { log } from "../util/log";
|
||||||
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
||||||
import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js";
|
import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js";
|
||||||
import {
|
import {
|
||||||
channelToTemplateSafeChannel,
|
channelToTemplateSafeChannel,
|
||||||
savedMessageToTemplateSafeSavedMessage,
|
savedMessageToTemplateSafeSavedMessage,
|
||||||
|
@ -14,7 +14,7 @@ import { UnknownUser } from "../../../utils";
|
||||||
|
|
||||||
interface LogMessageEditData {
|
interface LogMessageEditData {
|
||||||
user: User | UnknownUser;
|
user: User | UnknownUser;
|
||||||
channel: BaseGuildTextChannel | ThreadChannel;
|
channel: GuildTextBasedChannel;
|
||||||
before: SavedMessage;
|
before: SavedMessage;
|
||||||
after: SavedMessage;
|
after: SavedMessage;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,12 @@ import { LogsPluginType } from "../types";
|
||||||
import { LogType } from "../../../data/LogType";
|
import { LogType } from "../../../data/LogType";
|
||||||
import { log } from "../util/log";
|
import { log } from "../util/log";
|
||||||
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
||||||
import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js";
|
import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js";
|
||||||
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
||||||
|
|
||||||
interface LogPostedScheduledMessageData {
|
interface LogPostedScheduledMessageData {
|
||||||
author: User;
|
author: User;
|
||||||
channel: BaseGuildTextChannel | ThreadChannel;
|
channel: GuildTextBasedChannel;
|
||||||
messageId: string;
|
messageId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,12 @@ import { LogsPluginType } from "../types";
|
||||||
import { LogType } from "../../../data/LogType";
|
import { LogType } from "../../../data/LogType";
|
||||||
import { log } from "../util/log";
|
import { log } from "../util/log";
|
||||||
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
||||||
import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js";
|
import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js";
|
||||||
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
||||||
|
|
||||||
interface LogRepeatedMessageData {
|
interface LogRepeatedMessageData {
|
||||||
author: User;
|
author: User;
|
||||||
channel: BaseGuildTextChannel | ThreadChannel;
|
channel: GuildTextBasedChannel;
|
||||||
datetime: string;
|
datetime: string;
|
||||||
date: string;
|
date: string;
|
||||||
time: string;
|
time: string;
|
||||||
|
|
|
@ -3,12 +3,12 @@ import { LogsPluginType } from "../types";
|
||||||
import { LogType } from "../../../data/LogType";
|
import { LogType } from "../../../data/LogType";
|
||||||
import { log } from "../util/log";
|
import { log } from "../util/log";
|
||||||
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
||||||
import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js";
|
import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js";
|
||||||
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
||||||
|
|
||||||
interface LogScheduledMessageData {
|
interface LogScheduledMessageData {
|
||||||
author: User;
|
author: User;
|
||||||
channel: BaseGuildTextChannel | ThreadChannel;
|
channel: GuildTextBasedChannel;
|
||||||
datetime: string;
|
datetime: string;
|
||||||
date: string;
|
date: string;
|
||||||
time: string;
|
time: string;
|
||||||
|
|
|
@ -3,12 +3,12 @@ import { LogsPluginType } from "../types";
|
||||||
import { LogType } from "../../../data/LogType";
|
import { LogType } from "../../../data/LogType";
|
||||||
import { log } from "../util/log";
|
import { log } from "../util/log";
|
||||||
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
|
||||||
import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js";
|
import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js";
|
||||||
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
||||||
|
|
||||||
interface LogScheduledRepeatedMessageData {
|
interface LogScheduledRepeatedMessageData {
|
||||||
author: User;
|
author: User;
|
||||||
channel: BaseGuildTextChannel | ThreadChannel;
|
channel: GuildTextBasedChannel;
|
||||||
datetime: string;
|
datetime: string;
|
||||||
date: string;
|
date: string;
|
||||||
time: string;
|
time: string;
|
||||||
|
|
|
@ -83,7 +83,7 @@ export async function log<TLogType extends keyof ILogTypeData>(
|
||||||
|
|
||||||
logChannelLoop: for (const [channelId, opts] of Object.entries(logChannels)) {
|
logChannelLoop: for (const [channelId, opts] of Object.entries(logChannels)) {
|
||||||
const channel = pluginData.guild.channels.cache.get(channelId as Snowflake);
|
const channel = pluginData.guild.channels.cache.get(channelId as Snowflake);
|
||||||
if (!channel || !(channel instanceof TextChannel)) continue;
|
if (!channel?.isText()) continue;
|
||||||
if (pluginData.state.channelCooldowns.isOnCooldown(channelId)) continue;
|
if (pluginData.state.channelCooldowns.isOnCooldown(channelId)) continue;
|
||||||
if (opts.include?.length && !opts.include.includes(typeStr)) continue;
|
if (opts.include?.length && !opts.include.includes(typeStr)) continue;
|
||||||
if (opts.exclude && opts.exclude.includes(typeStr)) continue;
|
if (opts.exclude && opts.exclude.includes(typeStr)) continue;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { BaseGuildTextChannel, Snowflake, ThreadChannel } from "discord.js";
|
import { BaseGuildTextChannel, GuildTextBasedChannel, Snowflake, ThreadChannel } from "discord.js";
|
||||||
import { GuildPluginData } from "knub";
|
import { GuildPluginData } from "knub";
|
||||||
import { SavedMessage } from "../../../data/entities/SavedMessage";
|
import { SavedMessage } from "../../../data/entities/SavedMessage";
|
||||||
import { LogType } from "../../../data/LogType";
|
import { LogType } from "../../../data/LogType";
|
||||||
|
@ -12,9 +12,9 @@ export async function onMessageDeleteBulk(pluginData: GuildPluginData<LogsPlugin
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const channel = pluginData.guild.channels.cache.get(savedMessages[0].channel_id as Snowflake) as
|
const channel = pluginData.guild.channels.cache.get(
|
||||||
| BaseGuildTextChannel
|
savedMessages[0].channel_id as Snowflake,
|
||||||
| ThreadChannel;
|
) as GuildTextBasedChannel;
|
||||||
const archiveId = await pluginData.state.archives.createFromSavedMessages(savedMessages, pluginData.guild);
|
const archiveId = await pluginData.state.archives.createFromSavedMessages(savedMessages, pluginData.guild);
|
||||||
const archiveUrl = pluginData.state.archives.getUrl(getBaseUrl(pluginData), archiveId);
|
const archiveUrl = pluginData.state.archives.getUrl(getBaseUrl(pluginData), archiveId);
|
||||||
const authorIds = Array.from(new Set(savedMessages.map((item) => `\`${item.user_id}\``)));
|
const authorIds = Array.from(new Set(savedMessages.map((item) => `\`${item.user_id}\``)));
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { BaseGuildTextChannel, MessageEmbed, Snowflake, ThreadChannel } from "discord.js";
|
import { BaseGuildTextChannel, GuildTextBasedChannel, MessageEmbed, Snowflake, ThreadChannel } from "discord.js";
|
||||||
import { GuildPluginData } from "knub";
|
import { GuildPluginData } from "knub";
|
||||||
import cloneDeep from "lodash.clonedeep";
|
import cloneDeep from "lodash.clonedeep";
|
||||||
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
||||||
|
@ -49,9 +49,7 @@ export async function onMessageUpdate(
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await resolveUser(pluginData.client, savedMessage.user_id);
|
const user = await resolveUser(pluginData.client, savedMessage.user_id);
|
||||||
const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake)! as
|
const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake)! as GuildTextBasedChannel;
|
||||||
| BaseGuildTextChannel
|
|
||||||
| ThreadChannel;
|
|
||||||
|
|
||||||
logMessageEdit(pluginData, {
|
logMessageEdit(pluginData, {
|
||||||
user,
|
user,
|
||||||
|
|
|
@ -183,9 +183,10 @@ export async function muteUser(
|
||||||
}
|
}
|
||||||
|
|
||||||
const useChannel = existingMute ? config.message_on_update : config.message_on_mute;
|
const useChannel = existingMute ? config.message_on_update : config.message_on_mute;
|
||||||
const channel =
|
const channel = config.message_channel
|
||||||
config.message_channel && pluginData.guild.channels.cache.get(config.message_channel as Snowflake);
|
? pluginData.guild.channels.cache.get(config.message_channel as Snowflake)
|
||||||
if (useChannel && channel instanceof TextChannel) {
|
: null;
|
||||||
|
if (useChannel && channel?.isText()) {
|
||||||
contactMethods.push({ type: "channel", channel });
|
contactMethods.push({ type: "channel", channel });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Channel, Message, NewsChannel, TextChannel, ThreadChannel } from "discord.js";
|
import { Channel, GuildTextBasedChannel, Message, NewsChannel, TextChannel, ThreadChannel } from "discord.js";
|
||||||
import humanizeDuration from "humanize-duration";
|
import humanizeDuration from "humanize-duration";
|
||||||
import { GuildPluginData } from "knub";
|
import { GuildPluginData } from "knub";
|
||||||
import moment from "moment-timezone";
|
import moment from "moment-timezone";
|
||||||
|
@ -20,7 +20,7 @@ const MAX_REPEAT_UNTIL = moment.utc().add(100, "years");
|
||||||
export async function actualPostCmd(
|
export async function actualPostCmd(
|
||||||
pluginData: GuildPluginData<PostPluginType>,
|
pluginData: GuildPluginData<PostPluginType>,
|
||||||
msg: Message,
|
msg: Message,
|
||||||
targetChannel: Channel,
|
targetChannel: GuildTextBasedChannel,
|
||||||
content: StrictMessageContent,
|
content: StrictMessageContent,
|
||||||
opts: {
|
opts: {
|
||||||
"enable-mentions"?: boolean;
|
"enable-mentions"?: boolean;
|
||||||
|
@ -30,12 +30,8 @@ export async function actualPostCmd(
|
||||||
"repeat-times"?: number;
|
"repeat-times"?: number;
|
||||||
} = {},
|
} = {},
|
||||||
) {
|
) {
|
||||||
if (
|
if (!targetChannel.isText()) {
|
||||||
!(targetChannel instanceof TextChannel) &&
|
msg.channel.send(errorMessage("Specified channel is not a text-based channel"));
|
||||||
!(targetChannel instanceof NewsChannel) &&
|
|
||||||
!(targetChannel instanceof ThreadChannel)
|
|
||||||
) {
|
|
||||||
msg.channel.send(errorMessage("Specified channel is not a text channel, announcement channel, or thread"));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
import { Message, MessageAttachment, MessageOptions, NewsChannel, TextChannel, ThreadChannel } from "discord.js";
|
import {
|
||||||
|
GuildTextBasedChannel,
|
||||||
|
Message,
|
||||||
|
MessageAttachment,
|
||||||
|
MessageOptions,
|
||||||
|
NewsChannel,
|
||||||
|
TextChannel,
|
||||||
|
ThreadChannel,
|
||||||
|
} from "discord.js";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { GuildPluginData } from "knub";
|
import { GuildPluginData } from "knub";
|
||||||
import { downloadFile } from "../../../utils";
|
import { downloadFile } from "../../../utils";
|
||||||
|
@ -9,7 +17,7 @@ const fsp = fs.promises;
|
||||||
|
|
||||||
export async function postMessage(
|
export async function postMessage(
|
||||||
pluginData: GuildPluginData<PostPluginType>,
|
pluginData: GuildPluginData<PostPluginType>,
|
||||||
channel: TextChannel | NewsChannel | ThreadChannel,
|
channel: GuildTextBasedChannel,
|
||||||
content: MessageOptions,
|
content: MessageOptions,
|
||||||
attachments: MessageAttachment[] = [],
|
attachments: MessageAttachment[] = [],
|
||||||
enableMentions: boolean = false,
|
enableMentions: boolean = false,
|
||||||
|
|
|
@ -56,7 +56,7 @@ export const RemindersPlugin = zeppelinGuildPlugin<RemindersPluginType>()({
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeUnload(pluginData) {
|
beforeUnload(pluginData) {
|
||||||
pluginData.state.unregisterGuildEventListener();
|
pluginData.state.unregisterGuildEventListener?.();
|
||||||
pluginData.state.unloaded = true;
|
pluginData.state.unloaded = true;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -70,13 +70,13 @@ export async function getChannelInfoEmbed(
|
||||||
channelName = channel.name;
|
channelName = channel.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const createdAt = moment.utc(channel.createdAt, "x");
|
const createdAt = moment.utc(channel.createdAt!, "x");
|
||||||
const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin);
|
const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin);
|
||||||
const tzCreatedAt = requestMemberId
|
const tzCreatedAt = requestMemberId
|
||||||
? await timeAndDate.inMemberTz(requestMemberId, createdAt)
|
? await timeAndDate.inMemberTz(requestMemberId, createdAt)
|
||||||
: timeAndDate.inGuildTz(createdAt);
|
: timeAndDate.inGuildTz(createdAt);
|
||||||
const prettyCreatedAt = tzCreatedAt.format(timeAndDate.getDateFormat("pretty_datetime"));
|
const prettyCreatedAt = tzCreatedAt.format(timeAndDate.getDateFormat("pretty_datetime"));
|
||||||
const channelAge = humanizeDuration(Date.now() - channel.createdTimestamp, {
|
const channelAge = humanizeDuration(Date.now() - channel.createdTimestamp!, {
|
||||||
largest: 2,
|
largest: 2,
|
||||||
round: true,
|
round: true,
|
||||||
});
|
});
|
||||||
|
@ -134,8 +134,9 @@ export async function getChannelInfoEmbed(
|
||||||
const memberCount = thread.memberCount ?? thread.members.cache.size;
|
const memberCount = thread.memberCount ?? thread.members.cache.size;
|
||||||
const owner = await thread.fetchOwner().catch(() => null);
|
const owner = await thread.fetchOwner().catch(() => null);
|
||||||
const ownerMention = owner?.user ? verboseUserMention(owner.user) : "Unknown#0000";
|
const ownerMention = owner?.user ? verboseUserMention(owner.user) : "Unknown#0000";
|
||||||
const autoArchiveDuration = thread.autoArchiveDuration === "MAX" ? 10080 : thread.autoArchiveDuration; // TODO: Boost level check
|
const humanizedArchiveTime = `Archive duration: **${humanizeDuration(
|
||||||
const humanizedArchiveTime = `Archive duration: **${humanizeDuration((autoArchiveDuration ?? 0) * MINUTES)}**`;
|
(thread.autoArchiveDuration ?? 0) * MINUTES,
|
||||||
|
)}**`;
|
||||||
|
|
||||||
embed.fields.push({
|
embed.fields.push({
|
||||||
name: preEmbedPadding + "Thread information",
|
name: preEmbedPadding + "Thread information",
|
||||||
|
|
|
@ -6,8 +6,10 @@ import {
|
||||||
Guild,
|
Guild,
|
||||||
GuildAuditLogs,
|
GuildAuditLogs,
|
||||||
GuildAuditLogsEntry,
|
GuildAuditLogsEntry,
|
||||||
|
GuildBasedChannel,
|
||||||
GuildChannel,
|
GuildChannel,
|
||||||
GuildMember,
|
GuildMember,
|
||||||
|
GuildTextBasedChannel,
|
||||||
Invite,
|
Invite,
|
||||||
InviteGuild,
|
InviteGuild,
|
||||||
LimitedCollection,
|
LimitedCollection,
|
||||||
|
@ -1085,7 +1087,7 @@ export type CustomEmoji = {
|
||||||
id: string;
|
id: string;
|
||||||
} & Emoji;
|
} & Emoji;
|
||||||
|
|
||||||
export type UserNotificationMethod = { type: "dm" } | { type: "channel"; channel: TextChannel | ThreadChannel };
|
export type UserNotificationMethod = { type: "dm" } | { type: "channel"; channel: GuildTextBasedChannel };
|
||||||
|
|
||||||
export const disableUserNotificationStrings = ["no", "none", "off"];
|
export const disableUserNotificationStrings = ["no", "none", "off"];
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { GuildChannel, GuildMember } from "discord.js";
|
import { GuildMember, GuildTextBasedChannel } from "discord.js";
|
||||||
import { getMissingChannelPermissions } from "./getMissingChannelPermissions";
|
import { getMissingChannelPermissions } from "./getMissingChannelPermissions";
|
||||||
import { readChannelPermissions } from "./readChannelPermissions";
|
import { readChannelPermissions } from "./readChannelPermissions";
|
||||||
|
|
||||||
export function canReadChannel(channel: GuildChannel, member: GuildMember) {
|
export function canReadChannel(channel: GuildTextBasedChannel, member: GuildMember) {
|
||||||
// Not missing permissions required to read the channel = can read channel
|
// Not missing permissions required to read the channel = can read channel
|
||||||
return !getMissingChannelPermissions(member, channel, readChannelPermissions);
|
return !getMissingChannelPermissions(member, channel, readChannelPermissions);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { GuildChannel, GuildMember, ThreadChannel } from "discord.js";
|
import { GuildMember, GuildTextBasedChannel } from "discord.js";
|
||||||
import { getMissingPermissions } from "./getMissingPermissions";
|
import { getMissingPermissions } from "./getMissingPermissions";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,7 +7,7 @@ import { getMissingPermissions } from "./getMissingPermissions";
|
||||||
*/
|
*/
|
||||||
export function getMissingChannelPermissions(
|
export function getMissingChannelPermissions(
|
||||||
member: GuildMember,
|
member: GuildMember,
|
||||||
channel: GuildChannel | ThreadChannel,
|
channel: GuildTextBasedChannel,
|
||||||
requiredPermissions: number | bigint,
|
requiredPermissions: number | bigint,
|
||||||
): bigint {
|
): bigint {
|
||||||
const memberChannelPermissions = channel.permissionsFor(member.id);
|
const memberChannelPermissions = channel.permissionsFor(member.id);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Snowflake, TextChannel } from "discord.js";
|
import { GuildTextBasedChannel, Snowflake, TextChannel } from "discord.js";
|
||||||
import { GuildPluginData } from "knub";
|
import { GuildPluginData } from "knub";
|
||||||
import { getChannelIdFromMessageId } from "../data/getChannelIdFromMessageId";
|
import { getChannelIdFromMessageId } from "../data/getChannelIdFromMessageId";
|
||||||
import { isSnowflake } from "../utils";
|
import { isSnowflake } from "../utils";
|
||||||
|
@ -7,7 +7,7 @@ const channelAndMessageIdRegex = /^(\d+)[\-\/](\d+)$/;
|
||||||
const messageLinkRegex = /^https:\/\/(?:\w+\.)?discord(?:app)?\.com\/channels\/\d+\/(\d+)\/(\d+)$/i;
|
const messageLinkRegex = /^https:\/\/(?:\w+\.)?discord(?:app)?\.com\/channels\/\d+\/(\d+)\/(\d+)$/i;
|
||||||
|
|
||||||
export interface MessageTarget {
|
export interface MessageTarget {
|
||||||
channel: TextChannel;
|
channel: GuildTextBasedChannel;
|
||||||
messageId: string;
|
messageId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ export async function resolveMessageTarget(pluginData: GuildPluginData<any>, val
|
||||||
}
|
}
|
||||||
|
|
||||||
const channel = pluginData.guild.channels.resolve(result.channelId as Snowflake);
|
const channel = pluginData.guild.channels.resolve(result.channelId as Snowflake);
|
||||||
if (!channel || !(channel instanceof TextChannel)) {
|
if (!channel?.isText()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue