This commit is contained in:
Isaac (eartharoid) 2020-08-17 14:46:23 +01:00
parent fa36d8dbe2
commit 62494aaa4d
29 changed files with 1612 additions and 186 deletions

6
.gitignore vendored
View File

@ -2,6 +2,6 @@ logs/
node_modules/ node_modules/
user/.env user/.env
user/storage.db user/storage.db
user/transcripts/*.txt user/transcripts/text/*.txt
user/transcripts/*.log user/transcripts/raw/*.log
user/transcripts/*.json user/transcripts/raw/*.json

View File

@ -1,9 +1,9 @@
# DiscordTickets # DiscordTickets
[![Run on Repl.it](https://repl.it/badge/github/eartharoid/DiscordTickets)](https://repl.it/github/eartharoid/DiscordTickets) [![Run on Repl.it](https://repl.it/badge/github/eartharoid/DiscordTickets)](https://repl.it/github/eartharoid/DiscordTickets) [![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/B0B214BHI)
A simple Discord bot to manage support ticket channels to allow you and your team to provide better and quicker assistance to your members/customers. A simple Discord bot to manage support ticket channels to allow you and your team to provide better and quicker assistance to your members/customers.
**Go to the [wiki](https://github.com/Eartharoid/DiscordTickets/wiki) for more information** **Go to the [wiki](https://github.com/Eartharoid/DiscordTickets/wiki) for more information**
# REWRITE IN PROGRESS, PLEASE DON'T DOWNOAD FROM MASTER, DOWNLOAD [LATEST RELEASE](https://github.com/eartharoid/DiscordTickets/releases) OR WAIT A FEW DAYS. # REWRITE IN PROGRESS, PLEASE DON'T DOWNLOAD FROM MASTER, DOWNLOAD [LATEST RELEASE](https://github.com/eartharoid/DiscordTickets/releases) OR WAIT A FEW DAYS.

221
package-lock.json generated
View File

@ -81,8 +81,7 @@
"@types/color-name": { "@types/color-name": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
"dev": true
}, },
"@types/node": { "@types/node": {
"version": "14.0.27", "version": "14.0.27",
@ -129,7 +128,6 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
"integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==",
"dev": true,
"requires": { "requires": {
"string-width": "^3.0.0" "string-width": "^3.0.0"
} }
@ -140,11 +138,25 @@
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
"dev": true "dev": true
}, },
"ansi-escapes": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
"integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
"requires": {
"type-fest": "^0.11.0"
},
"dependencies": {
"type-fest": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
"integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ=="
}
}
},
"ansi-regex": { "ansi-regex": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
"dev": true
}, },
"ansi-styles": { "ansi-styles": {
"version": "3.2.1", "version": "3.2.1",
@ -173,12 +185,14 @@
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
"optional": true
}, },
"are-we-there-yet": { "are-we-there-yet": {
"version": "1.1.5", "version": "1.1.5",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
"optional": true,
"requires": { "requires": {
"delegates": "^1.0.0", "delegates": "^1.0.0",
"readable-stream": "^2.0.6" "readable-stream": "^2.0.6"
@ -272,7 +286,6 @@
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
"integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==",
"dev": true,
"requires": { "requires": {
"ansi-align": "^3.0.0", "ansi-align": "^3.0.0",
"camelcase": "^5.3.1", "camelcase": "^5.3.1",
@ -288,7 +301,6 @@
"version": "4.2.1", "version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"dev": true,
"requires": { "requires": {
"@types/color-name": "^1.1.1", "@types/color-name": "^1.1.1",
"color-convert": "^2.0.1" "color-convert": "^2.0.1"
@ -298,7 +310,6 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"dev": true,
"requires": { "requires": {
"ansi-styles": "^4.1.0", "ansi-styles": "^4.1.0",
"supports-color": "^7.1.0" "supports-color": "^7.1.0"
@ -308,7 +319,6 @@
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": { "requires": {
"color-name": "~1.1.4" "color-name": "~1.1.4"
} }
@ -316,32 +326,27 @@
"color-name": { "color-name": {
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
"dev": true
}, },
"emoji-regex": { "emoji-regex": {
"version": "8.0.0", "version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
"dev": true
}, },
"has-flag": { "has-flag": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
"dev": true
}, },
"is-fullwidth-code-point": { "is-fullwidth-code-point": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
"dev": true
}, },
"string-width": { "string-width": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
"dev": true,
"requires": { "requires": {
"emoji-regex": "^8.0.0", "emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0", "is-fullwidth-code-point": "^3.0.0",
@ -352,7 +357,6 @@
"version": "7.1.0", "version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"dev": true,
"requires": { "requires": {
"has-flag": "^4.0.0" "has-flag": "^4.0.0"
} }
@ -418,8 +422,7 @@
"camelcase": { "camelcase": {
"version": "5.3.1", "version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
"dev": true
}, },
"caseless": { "caseless": {
"version": "0.12.0", "version": "0.12.0",
@ -498,7 +501,8 @@
"chownr": { "chownr": {
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
"optional": true
}, },
"ci-info": { "ci-info": {
"version": "2.0.0", "version": "2.0.0",
@ -509,8 +513,7 @@
"cli-boxes": { "cli-boxes": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz",
"integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==", "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w=="
"dev": true
}, },
"clone-response": { "clone-response": {
"version": "1.0.2", "version": "1.0.2",
@ -524,7 +527,8 @@
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"optional": true
}, },
"color-convert": { "color-convert": {
"version": "1.9.3", "version": "1.9.3",
@ -571,12 +575,14 @@
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
"optional": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"optional": true
}, },
"cross-spawn": { "cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
@ -646,12 +652,14 @@
"delegates": { "delegates": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
"optional": true
}, },
"detect-libc": { "detect-libc": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
"optional": true
}, },
"discord.js": { "discord.js": {
"version": "12.2.0", "version": "12.2.0",
@ -715,8 +723,7 @@
"emoji-regex": { "emoji-regex": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
"dev": true
}, },
"end-of-stream": { "end-of-stream": {
"version": "1.4.4", "version": "1.4.4",
@ -961,6 +968,7 @@
"version": "1.2.7", "version": "1.2.7",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
"integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
"optional": true,
"requires": { "requires": {
"minipass": "^2.6.0" "minipass": "^2.6.0"
} }
@ -999,6 +1007,7 @@
"version": "2.7.4", "version": "2.7.4",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
"optional": true,
"requires": { "requires": {
"aproba": "^1.0.3", "aproba": "^1.0.3",
"console-control-strings": "^1.0.0", "console-control-strings": "^1.0.0",
@ -1013,12 +1022,14 @@
"ansi-regex": { "ansi-regex": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"optional": true
}, },
"is-fullwidth-code-point": { "is-fullwidth-code-point": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"optional": true,
"requires": { "requires": {
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
@ -1027,6 +1038,7 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"optional": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
@ -1037,6 +1049,7 @@
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
@ -1150,7 +1163,8 @@
"has-unicode": { "has-unicode": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
"optional": true
}, },
"has-yarn": { "has-yarn": {
"version": "2.1.0", "version": "2.1.0",
@ -1179,6 +1193,7 @@
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"optional": true,
"requires": { "requires": {
"safer-buffer": ">= 2.1.2 < 3" "safer-buffer": ">= 2.1.2 < 3"
} }
@ -1199,6 +1214,7 @@
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz",
"integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==",
"optional": true,
"requires": { "requires": {
"minimatch": "^3.0.4" "minimatch": "^3.0.4"
} }
@ -1335,7 +1351,8 @@
"isarray": { "isarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"optional": true
}, },
"isexe": { "isexe": {
"version": "2.0.0", "version": "2.0.0",
@ -1430,17 +1447,17 @@
} }
}, },
"leeks.js": { "leeks.js": {
"version": "0.0.8", "version": "0.0.9",
"resolved": "https://registry.npmjs.org/leeks.js/-/leeks.js-0.0.8.tgz", "resolved": "https://registry.npmjs.org/leeks.js/-/leeks.js-0.0.9.tgz",
"integrity": "sha512-MSnFldVRr1zNNTWbCbHaaYExyyzrVIH9zBW0VRedhz7/J4CELYN9fpifE4MH1DQIdB5rGL9c5wLOOUJGJf0M8g==" "integrity": "sha512-e6UVJ1fj8f2clpHy+KpXVWVxjzB3XYFGyKRJHDlT8Gy/75BT+9bYUacpHSCoXp7RTtyMSr4eBjZrp0nHyyQVbg=="
}, },
"leekslazylogger": { "leekslazylogger": {
"version": "2.0.0-alpha.5", "version": "2.0.0-alpha.6",
"resolved": "https://registry.npmjs.org/leekslazylogger/-/leekslazylogger-2.0.0-alpha.5.tgz", "resolved": "https://registry.npmjs.org/leekslazylogger/-/leekslazylogger-2.0.0-alpha.6.tgz",
"integrity": "sha512-AwOoDZpM7ZiNTFrKmJtI7wjphouTqNpJikPtsuwTMeXOYs7X7CokyQLJr1G+9T4CXoKfD1MuFMKPGPKsorNDRg==", "integrity": "sha512-DqOSsd8r9ks9ddCTxI34p41SGCX8+QvVij8/NDNe//yTHo2+JlipWYfnUR2UNMvXTXaIAtGYguTxhMaU4ibs4w==",
"requires": { "requires": {
"@eartharoid/dtf": "^1.0.7", "@eartharoid/dtf": "^1.0.7",
"leeks.js": "^0.0.8" "leeks.js": "0.0.9"
} }
}, },
"levn": { "levn": {
@ -1453,6 +1470,11 @@
"type-check": "~0.4.0" "type-check": "~0.4.0"
} }
}, },
"line-reader": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/line-reader/-/line-reader-0.4.0.tgz",
"integrity": "sha1-F+RIGNoKwzVnW6MAlU+U72cOZv0="
},
"lodash": { "lodash": {
"version": "4.17.19", "version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
@ -1517,6 +1539,7 @@
"version": "2.9.0", "version": "2.9.0",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
"integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
"optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.2", "safe-buffer": "^5.1.2",
"yallist": "^3.0.0" "yallist": "^3.0.0"
@ -1526,6 +1549,7 @@
"version": "1.3.3", "version": "1.3.3",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
"integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
"optional": true,
"requires": { "requires": {
"minipass": "^2.9.0" "minipass": "^2.9.0"
} }
@ -1566,6 +1590,7 @@
"version": "2.5.0", "version": "2.5.0",
"resolved": "https://registry.npmjs.org/needle/-/needle-2.5.0.tgz", "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.0.tgz",
"integrity": "sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA==", "integrity": "sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA==",
"optional": true,
"requires": { "requires": {
"debug": "^3.2.6", "debug": "^3.2.6",
"iconv-lite": "^0.4.4", "iconv-lite": "^0.4.4",
@ -1576,6 +1601,7 @@
"version": "3.2.6", "version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
"optional": true,
"requires": { "requires": {
"ms": "^2.1.1" "ms": "^2.1.1"
} }
@ -1585,7 +1611,8 @@
"node-addon-api": { "node-addon-api": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.0.tgz", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.0.tgz",
"integrity": "sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA==" "integrity": "sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA==",
"optional": true
}, },
"node-fetch": { "node-fetch": {
"version": "2.6.0", "version": "2.6.0",
@ -1642,6 +1669,7 @@
"version": "0.11.0", "version": "0.11.0",
"resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz",
"integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==", "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==",
"optional": true,
"requires": { "requires": {
"detect-libc": "^1.0.2", "detect-libc": "^1.0.2",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
@ -1659,6 +1687,7 @@
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
"integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==",
"optional": true,
"requires": { "requires": {
"abbrev": "1", "abbrev": "1",
"osenv": "^0.1.4" "osenv": "^0.1.4"
@ -1667,12 +1696,14 @@
"semver": { "semver": {
"version": "5.7.1", "version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"optional": true
}, },
"tar": { "tar": {
"version": "4.4.13", "version": "4.4.13",
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
"integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
"optional": true,
"requires": { "requires": {
"chownr": "^1.1.1", "chownr": "^1.1.1",
"fs-minipass": "^1.2.5", "fs-minipass": "^1.2.5",
@ -1745,6 +1776,7 @@
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz",
"integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==",
"optional": true,
"requires": { "requires": {
"npm-normalize-package-bin": "^1.0.1" "npm-normalize-package-bin": "^1.0.1"
} }
@ -1752,12 +1784,14 @@
"npm-normalize-package-bin": { "npm-normalize-package-bin": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz",
"integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==",
"optional": true
}, },
"npm-packlist": { "npm-packlist": {
"version": "1.4.8", "version": "1.4.8",
"resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz",
"integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==",
"optional": true,
"requires": { "requires": {
"ignore-walk": "^3.0.1", "ignore-walk": "^3.0.1",
"npm-bundled": "^1.0.1", "npm-bundled": "^1.0.1",
@ -1768,6 +1802,7 @@
"version": "4.1.2", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
"optional": true,
"requires": { "requires": {
"are-we-there-yet": "~1.1.2", "are-we-there-yet": "~1.1.2",
"console-control-strings": "~1.1.0", "console-control-strings": "~1.1.0",
@ -1778,7 +1813,8 @@
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"optional": true
}, },
"oauth-sign": { "oauth-sign": {
"version": "0.9.0", "version": "0.9.0",
@ -1789,7 +1825,8 @@
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
"optional": true
}, },
"once": { "once": {
"version": "1.4.0", "version": "1.4.0",
@ -1816,17 +1853,20 @@
"os-homedir": { "os-homedir": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
"optional": true
}, },
"os-tmpdir": { "os-tmpdir": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
"optional": true
}, },
"osenv": { "osenv": {
"version": "0.1.5", "version": "0.1.5",
"resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
"integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
"optional": true,
"requires": { "requires": {
"os-homedir": "^1.0.0", "os-homedir": "^1.0.0",
"os-tmpdir": "^1.0.0" "os-tmpdir": "^1.0.0"
@ -1910,7 +1950,8 @@
"process-nextick-args": { "process-nextick-args": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"optional": true
}, },
"progress": { "progress": {
"version": "2.0.3", "version": "2.0.3",
@ -1982,6 +2023,7 @@
"version": "2.3.7", "version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"optional": true,
"requires": { "requires": {
"core-util-is": "~1.0.0", "core-util-is": "~1.0.0",
"inherits": "~2.0.3", "inherits": "~2.0.3",
@ -2095,17 +2137,20 @@
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"optional": true
}, },
"sax": { "sax": {
"version": "1.2.4", "version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"optional": true
}, },
"semver": { "semver": {
"version": "7.3.2", "version": "7.3.2",
@ -2157,7 +2202,8 @@
"set-blocking": { "set-blocking": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
"optional": true
}, },
"setimmediate": { "setimmediate": {
"version": "1.0.5", "version": "1.0.5",
@ -2205,6 +2251,7 @@
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.0.0.tgz", "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.0.0.tgz",
"integrity": "sha512-rjvqHFUaSGnzxDy2AHCwhHy6Zp6MNJzCPGYju4kD8yi6bze4d1/zMTg6C7JI49b7/EM7jKMTvyfN/4ylBKdwfw==", "integrity": "sha512-rjvqHFUaSGnzxDy2AHCwhHy6Zp6MNJzCPGYju4kD8yi6bze4d1/zMTg6C7JI49b7/EM7jKMTvyfN/4ylBKdwfw==",
"optional": true,
"requires": { "requires": {
"node-addon-api": "2.0.0", "node-addon-api": "2.0.0",
"node-gyp": "3.x", "node-gyp": "3.x",
@ -2240,7 +2287,6 @@
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"dev": true,
"requires": { "requires": {
"emoji-regex": "^7.0.1", "emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0", "is-fullwidth-code-point": "^2.0.0",
@ -2250,14 +2296,12 @@
"ansi-regex": { "ansi-regex": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
"dev": true
}, },
"strip-ansi": { "strip-ansi": {
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": { "requires": {
"ansi-regex": "^4.1.0" "ansi-regex": "^4.1.0"
} }
@ -2268,6 +2312,7 @@
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"optional": true,
"requires": { "requires": {
"safe-buffer": "~5.1.0" "safe-buffer": "~5.1.0"
} }
@ -2276,7 +2321,6 @@
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": { "requires": {
"ansi-regex": "^5.0.0" "ansi-regex": "^5.0.0"
} }
@ -2296,6 +2340,30 @@
"has-flag": "^3.0.0" "has-flag": "^3.0.0"
} }
}, },
"supports-hyperlinks": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz",
"integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==",
"requires": {
"has-flag": "^4.0.0",
"supports-color": "^7.0.0"
},
"dependencies": {
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
"supports-color": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"table": { "table": {
"version": "5.4.6", "version": "5.4.6",
"resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
@ -2322,8 +2390,16 @@
"term-size": { "term-size": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz",
"integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw=="
"dev": true },
"terminal-link": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
"integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==",
"requires": {
"ansi-escapes": "^4.2.1",
"supports-hyperlinks": "^2.0.0"
}
}, },
"text-table": { "text-table": {
"version": "0.2.0", "version": "0.2.0",
@ -2396,8 +2472,7 @@
"type-fest": { "type-fest": {
"version": "0.8.1", "version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
"dev": true
}, },
"typedarray-to-buffer": { "typedarray-to-buffer": {
"version": "3.1.5", "version": "3.1.5",
@ -2536,7 +2611,8 @@
"util-deprecate": { "util-deprecate": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"optional": true
}, },
"uuid": { "uuid": {
"version": "8.3.0", "version": "8.3.0",
@ -2578,6 +2654,7 @@
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
"optional": true,
"requires": { "requires": {
"string-width": "^1.0.2 || 2" "string-width": "^1.0.2 || 2"
}, },
@ -2585,12 +2662,14 @@
"ansi-regex": { "ansi-regex": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"optional": true
}, },
"string-width": { "string-width": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"optional": true,
"requires": { "requires": {
"is-fullwidth-code-point": "^2.0.0", "is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^4.0.0" "strip-ansi": "^4.0.0"
@ -2600,6 +2679,7 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"optional": true,
"requires": { "requires": {
"ansi-regex": "^3.0.0" "ansi-regex": "^3.0.0"
} }
@ -2610,7 +2690,6 @@
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
"integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
"dev": true,
"requires": { "requires": {
"string-width": "^4.0.0" "string-width": "^4.0.0"
}, },
@ -2618,20 +2697,17 @@
"emoji-regex": { "emoji-regex": {
"version": "8.0.0", "version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
"dev": true
}, },
"is-fullwidth-code-point": { "is-fullwidth-code-point": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
"dev": true
}, },
"string-width": { "string-width": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
"dev": true,
"requires": { "requires": {
"emoji-regex": "^8.0.0", "emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0", "is-fullwidth-code-point": "^3.0.0",
@ -2694,7 +2770,8 @@
"yallist": { "yallist": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"optional": true
} }
} }
} }

View File

@ -1,14 +1,21 @@
{ {
"name": "@eartharoid/discordtickets", "name": "@eartharoid/discordtickets",
"version": "2.0.0", "version": "2.0.0",
"description": "A Discord ticket/support - an open-source & self-hosted bot", "private": true,
"description": "An open-source & self-hosted Discord bot for ticket management.",
"main": "src/index.js", "main": "src/index.js",
"dependencies": { "dependencies": {
"@eartharoid/dtf": "^1.0.7",
"boxen": "^4.2.0",
"discord.js": "^12.2.0", "discord.js": "^12.2.0",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"leekslazylogger": "^2.0.0-alpha.5", "leekslazylogger": "^2.0.0-alpha.6",
"line-reader": "^0.4.0",
"node-fetch": "^2.6.0", "node-fetch": "^2.6.0",
"sequelize": "^6.3.4", "sequelize": "^6.3.4",
"terminal-link": "^2.1.1"
},
"optionalDependencies": {
"sqlite3": "^5.0.0" "sqlite3": "^5.0.0"
}, },
"peerDependencies": { "peerDependencies": {
@ -22,6 +29,9 @@
"start": "node src/", "start": "node src/",
"test": "echo \"Nothing to test! Run with 'npm start'\" && exit 1" "test": "echo \"Nothing to test! Run with 'npm start'\" && exit 1"
}, },
"engines": {
"node": ">=12"
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/eartharoid/DiscordTickets.git" "url": "git+https://github.com/eartharoid/DiscordTickets.git"
@ -36,5 +46,6 @@
"bugs": { "bugs": {
"url": "https://github.com/eartharoid/DiscordTickets/issues" "url": "https://github.com/eartharoid/DiscordTickets/issues"
}, },
"homepage": "https://github.com/eartharoid/DiscordTickets" "homepage": "https://github.com/eartharoid/DiscordTickets/#readme",
"funding": "https://github.com/eartharoid/DiscordTickets/?sponsor=1"
} }

View File

@ -20,6 +20,8 @@ module.exports = {
args: true, args: true,
async execute(client, message, args, Ticket) { async execute(client, message, args, Ticket) {
const guild = client.guilds.cache.get(config.guild);
const notTicket = new Discord.MessageEmbed() const notTicket = new Discord.MessageEmbed()
.setColor(config.err_colour) .setColor(config.err_colour)
.setAuthor(message.author.username, message.author.displayAvatarURL()) .setAuthor(message.author.username, message.author.displayAvatarURL())
@ -27,7 +29,7 @@ module.exports = {
.setDescription('Use this command in the ticket channel you want to add a user to, or mention the channel.') .setDescription('Use this command in the ticket channel you want to add a user to, or mention the channel.')
.addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`) .addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`)
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`) .addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
.setFooter(message.guild.name, message.guild.iconURL()); .setFooter(guild.name, guild.iconURL());
let ticket; let ticket;
@ -60,12 +62,12 @@ module.exports = {
.setDescription(`You don't have permission to alter ${channel} as it does not belong to you and you are not staff.`) .setDescription(`You don't have permission to alter ${channel} as it does not belong to you and you are not staff.`)
.addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`) .addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`)
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`) .addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
let member = message.guild.member(message.mentions.users.first() || message.guild.members.cache.get(args[0])); let member = guild.member(message.mentions.users.first() || guild.members.cache.get(args[0]));
if(!member) if(!member)
return message.channel.send( return message.channel.send(
@ -76,7 +78,7 @@ module.exports = {
.setDescription('Please mention a valid member.') .setDescription('Please mention a valid member.')
.addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`) .addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`)
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`) .addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
try { try {
@ -94,7 +96,7 @@ module.exports = {
.setAuthor(member.user.username, member.user.displayAvatarURL()) .setAuthor(member.user.username, member.user.displayAvatarURL())
.setTitle('**Member added**') .setTitle('**Member added**')
.setDescription(`${member} has been added by ${message.author}`) .setDescription(`${member} has been added by ${message.author}`)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
@ -105,7 +107,7 @@ module.exports = {
.setAuthor(member.user.username, member.user.displayAvatarURL()) .setAuthor(member.user.username, member.user.displayAvatarURL())
.setTitle(':white_check_mark: **Member added**') .setTitle(':white_check_mark: **Member added**')
.setDescription(`${member} has been added to <#${ticket.get('channel')}>`) .setDescription(`${member} has been added to <#${ticket.get('channel')}>`)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
log.info(`${message.author.tag} added a user to a ticket (#${message.channel.id})`); log.info(`${message.author.tag} added a user to a ticket (#${message.channel.id})`);

View File

@ -10,6 +10,7 @@ const ChildLogger = require('leekslazylogger').ChildLogger;
const log = new ChildLogger(); const log = new ChildLogger();
const Discord = require('discord.js'); const Discord = require('discord.js');
const config = require('../../user/config'); const config = require('../../user/config');
const fs = require('fs');
module.exports = { module.exports = {
name: 'close', name: 'close',
@ -20,6 +21,8 @@ module.exports = {
args: false, args: false,
async execute(client, message, args, Ticket) { async execute(client, message, args, Ticket) {
const guild = client.guilds.cache.get(config.guild);
const notTicket = new Discord.MessageEmbed() const notTicket = new Discord.MessageEmbed()
.setColor(config.err_colour) .setColor(config.err_colour)
.setAuthor(message.author.username, message.author.displayAvatarURL()) .setAuthor(message.author.username, message.author.displayAvatarURL())
@ -27,30 +30,18 @@ module.exports = {
.setDescription('Use this command in the ticket channel you want to close, or mention the channel.') .setDescription('Use this command in the ticket channel you want to close, or mention the channel.')
.addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`) .addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`)
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`) .addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
.setFooter(message.guild.name, message.guild.iconURL()); .setFooter(guild.name, guild.iconURL());
let ticket; let ticket;
const channel = message.mentions.channels.first(); let channel = message.mentions.channels.first();
// let channel = message.guild.channels.resolve(message.mentions.channels.first()); // not necessary // || client.channels.resolve(await Ticket.findOne({ where: { id: args[0] } }).channel) // channels.fetch()
if(!channel) { if(!channel) {
channel = message.channel;
ticket = await Ticket.findOne({ where: { channel: message.channel.id } }); ticket = await Ticket.findOne({ where: { channel: channel.id } });
if(!ticket) if(!ticket)
return message.channel.send(notTicket); return channel.send(notTicket);
ticket.update({ open: false}, { where: { channel: message.channel.id } });
message.channel.send(
new Discord.MessageEmbed()
.setColor(config.colour)
.setAuthor(message.author.username, message.author.displayAvatarURL())
.setTitle(`:white_check_mark: **Ticket ${ticket.id} closed**`)
.setDescription('The channel will be automatically deleted once the contents have been archived.')
.setFooter(message.guild.name, message.guild.iconURL())
);
setTimeout(() => message.channel.delete(), 5000);
} else { } else {
@ -59,11 +50,11 @@ module.exports = {
notTicket notTicket
.setTitle(':x: **Channel is not a ticket**') .setTitle(':x: **Channel is not a ticket**')
.setDescription(`${channel} is not a ticket channel.`); .setDescription(`${channel} is not a ticket channel.`);
return message.channel.send(notTicket); return channel.send(notTicket);
} }
if(message.author.id !== ticket.get('creator') && !message.member.roles.cache.has(config.staff_role)) if(message.author.id !== ticket.get('creator') && !message.member.roles.cache.has(config.staff_role))
return message.channel.send( return channel.send(
new Discord.MessageEmbed() new Discord.MessageEmbed()
.setColor(config.err_colour) .setColor(config.err_colour)
.setAuthor(message.author.username, message.author.displayAvatarURL()) .setAuthor(message.author.username, message.author.displayAvatarURL())
@ -71,22 +62,60 @@ module.exports = {
.setDescription(`You don't have permission to close ${channel} as it does not belong to you and you are not staff.`) .setDescription(`You don't have permission to close ${channel} as it does not belong to you and you are not staff.`)
.addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`) .addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`)
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`) .addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
);
}
let success;
let pre = fs.existsSync(`user/transcripts/text/${channel.id}.txt`)
|| fs.existsSync(`user/transcripts/raw/${channel.id}.log`) ?
`You will be able to view an archived version later with \`${config.prefix}transcript ${ticket.get('id')}\``
: '';
let confirm = await message.channel.send(
new Discord.MessageEmbed()
.setColor(config.colour)
.setAuthor(message.author.username, message.author.displayAvatarURL())
.setTitle(':grey_question: Are you sure?')
.setDescription(`${pre}\n**React with :white_check_mark: to confirm.**`)
.setFooter(guild.name + ' | Expires in 15 seconds', guild.iconURL())
); );
ticket.update({ open: false}, { where: { channel: channel.id } }); await confirm.react('✅');
message.channel.send( const collector = confirm.createReactionCollector(
(r, u) => r.emoji.name === '✅' && u.id === message.author.id,
{ time: 15000 });
collector.on('collect', () => {
if (channel.id !== message.channel.id)
channel.send(
new Discord.MessageEmbed()
.setColor(config.colour)
.setAuthor(message.author.username, message.author.displayAvatarURL())
.setTitle('**Ticket closed**')
.setDescription(`Ticket closed by ${message.author}`)
.setFooter(guild.name, guild.iconURL())
);
confirm.reactions.removeAll();
confirm.edit(
new Discord.MessageEmbed() new Discord.MessageEmbed()
.setColor(config.colour) .setColor(config.colour)
.setAuthor(message.author.username, message.author.displayAvatarURL()) .setAuthor(message.author.username, message.author.displayAvatarURL())
.setTitle(`:white_check_mark: **Ticket ${ticket.id} closed**`) .setTitle(`:white_check_mark: **Ticket ${ticket.id} closed**`)
.setDescription('The channel will be automatically deleted once the contents have been archived.') .setDescription('The channel will be automatically deleted in a few seconds, once the contents have been archived.')
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
setTimeout(() => channel.delete(), 5000); success = true;
} ticket.update({ open: false}, { where: { channel: channel.id } });
setTimeout(() => {
channel.delete();
if (channel.id !== message.channel.id)
message.delete()
.then(() => confirm.delete());
}, 15000);
log.info(`${message.author.tag} closed a ticket (#ticket-${ticket.get('id')})`); log.info(`${message.author.tag} closed a ticket (#ticket-${ticket.get('id')})`);
@ -98,9 +127,27 @@ module.exports = {
.setTitle('Ticket closed') .setTitle('Ticket closed')
.addField('Creator', `<@${ticket.get('creator')}>` , true) .addField('Creator', `<@${ticket.get('creator')}>` , true)
.addField('Closed by', message.author, true) .addField('Closed by', message.author, true)
.setFooter(client.user.username, client.user.avatarURL()) .setFooter(guild.name, guild.iconURL())
.setTimestamp() .setTimestamp()
); );
});
},
collector.on('end', () => {
if(!success) {
confirm.reactions.removeAll();
confirm.edit(
new Discord.MessageEmbed()
.setColor(config.err_colour)
.setAuthor(message.author.username, message.author.displayAvatarURL())
.setTitle(':x: **Expired**')
.setDescription('You took to long to react; confirmation failed.')
.setFooter(guild.name, guild.iconURL()));
message.delete({ timeout: 10000 })
.then(() => confirm.delete());
}
});
}
}; };

View File

@ -20,6 +20,8 @@ module.exports = {
args: false, args: false,
execute(client, message, args) { execute(client, message, args) {
const guild = client.guilds.cache.get(config.guild);
const commands = Array.from(client.commands.values()); const commands = Array.from(client.commands.values());
if (!args.length) { if (!args.length) {
@ -47,7 +49,7 @@ module.exports = {
\n${cmds.join('\n\n')} \n${cmds.join('\n\n')}
\nPlease contact a member of staff if you require assistance.` \nPlease contact a member of staff if you require assistance.`
) )
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
.setTimestamp() .setTimestamp()
).catch((error) => { ).catch((error) => {
log.warn('Could not send help menu'); log.warn('Could not send help menu');

View File

@ -21,15 +21,16 @@ module.exports = {
args: false, args: false,
async execute(client, message, args, Ticket) { async execute(client, message, args, Ticket) {
const guild = client.guilds.cache.get(config.guild);
const supportRole = message.guild.roles.cache.get(config.staff_role); const supportRole = guild.roles.cache.get(config.staff_role);
if (!supportRole) if (!supportRole)
return message.channel.send( return message.channel.send(
new Discord.MessageEmbed() new Discord.MessageEmbed()
.setColor(config.err_colour) .setColor(config.err_colour)
.setTitle(':x: **Error**') .setTitle(':x: **Error**')
.setDescription(`${config.name} has not been set up correctly. Could not find a 'support team' role with the id \`${config.staff_role}\``) .setDescription(`${config.name} has not been set up correctly. Could not find a 'support team' role with the id \`${config.staff_role}\``)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
@ -44,9 +45,9 @@ module.exports = {
if (tickets.count >= config.tickets.max) { if (tickets.count >= config.tickets.max) {
let ticketList = []; let ticketList = [];
for (let t in tickets.rows) { for (let t in tickets.rows) {
let desc = tickets.rows[t].topic.substring(0, 20); let desc = tickets.rows[t].topic.substring(0, 30);
ticketList ticketList
.push(`<#${tickets.rows[t].channel}>: \`${desc}${desc.length > 20 ? '...' : ''}\``); .push(`<#${tickets.rows[t].channel}>: \`${desc}${desc.length > 30 ? '...' : ''}\``);
} }
let m = await message.channel.send( let m = await message.channel.send(
@ -55,7 +56,7 @@ module.exports = {
.setAuthor(message.author.username, message.author.displayAvatarURL()) .setAuthor(message.author.username, message.author.displayAvatarURL())
.setTitle(`:x: **You already have ${tickets.count} or more open tickets**`) .setTitle(`:x: **You already have ${tickets.count} or more open tickets**`)
.setDescription(`Use \`${config.prefix}close\` to close unneeded tickets.\n\n${ticketList.join(',\n')}`) .setDescription(`Use \`${config.prefix}close\` to close unneeded tickets.\n\n${ticketList.join(',\n')}`)
.setFooter(message.guild.name + ' | This message will be deleted in 15 seconds', message.guild.iconURL()) .setFooter(guild.name + ' | This message will be deleted in 15 seconds', guild.iconURL())
); );
return setTimeout(async () => { return setTimeout(async () => {
@ -73,7 +74,7 @@ module.exports = {
.setAuthor(message.author.username, message.author.displayAvatarURL()) .setAuthor(message.author.username, message.author.displayAvatarURL())
.setTitle(':x: **Description too long**') .setTitle(':x: **Description too long**')
.setDescription('Please limit your ticket topic to less than 256 characters. A short sentence will do.') .setDescription('Please limit your ticket topic to less than 256 characters. A short sentence will do.')
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
else if (topic.length < 1) else if (topic.length < 1)
topic = 'No topic given'; topic = 'No topic given';
@ -89,12 +90,12 @@ module.exports = {
let name = 'ticket-' + ticket.get('id'); let name = 'ticket-' + ticket.get('id');
message.guild.channels.create(name, { guild.channels.create(name, {
type: 'text', type: 'text',
topic: `${message.author} | ${topic}`, topic: `${message.author} | ${topic}`,
parent: config.tickets.category, parent: config.tickets.category,
permissionOverwrites: [{ permissionOverwrites: [{
id: message.guild.roles.everyone, id: guild.roles.everyone,
deny: ['VIEW_CHANNEL', 'SEND_MESSAGES'] deny: ['VIEW_CHANNEL', 'SEND_MESSAGES']
}, },
{ {
@ -131,6 +132,7 @@ module.exports = {
await m.delete(); await m.delete();
}, 15000); }, 15000);
require('../utils/archive').create(client, c); // create files
let ping; let ping;
switch (config.tickets.ping) { switch (config.tickets.ping) {
@ -167,7 +169,7 @@ module.exports = {
.setAuthor(message.author.username, message.author.displayAvatarURL()) .setAuthor(message.author.username, message.author.displayAvatarURL())
.setDescription(text) .setDescription(text)
.addField('Topic', `\`${topic}\``) .addField('Topic', `\`${topic}\``)
.setFooter(client.user.username, client.user.avatarURL()) .setFooter(guild.name, guild.iconURL())
); );
if (config.tickets.pin) if (config.tickets.pin)
@ -183,7 +185,7 @@ module.exports = {
.setDescription(`\`${topic}\``) .setDescription(`\`${topic}\``)
.addField('Creator', message.author, true) .addField('Creator', message.author, true)
.addField('Channel', c, true) .addField('Channel', c, true)
.setFooter(client.user.username, client.user.avatarURL()) .setFooter(guild.name, guild.iconURL())
.setTimestamp() .setTimestamp()
); );

63
src/commands/panel.js Normal file
View File

@ -0,0 +1,63 @@
/**
*
* @name DiscordTickets
* @author eartharoid <contact@eartharoid.me>
* @license GNU-GPLv3
*
*/
const ChildLogger = require('leekslazylogger').ChildLogger;
const log = new ChildLogger();
const Discord = require('discord.js');
const config = require('../../user/config');
module.exports = {
name: 'panel',
description: 'Create or a panel widget in the channel the command is used in. Note that there can only be 1 panel.',
usage: '',
aliases: ['widget'],
example: '',
args: false,
permission: 'MANAGE_SERVER',
async execute(client, message, args, Ticket, Setting) {
const guild = client.guilds.cache.get(config.guild);
let msgID = await Setting.findOne({ where: { key: 'panel_msg_id' } });
let chanID = await Setting.findOne({ where: { key: 'panel_chan_id' } });
let panel;
if(!chanID)
chanID = await Setting.create({
key: 'panel_chan_id',
value: message.channel.id,
});
if(!msgID) {
msgID = await Setting.create({
key: 'panel_msg_id',
value: '',
});
} else {
panel = await client.channels.cache.get(chanID.get('value')).messages.fetch(msgID.get('value')); // get old panel message
if (panel)
panel.delete({ reason: 'Creating new panel/widget' }).then(() => log.info('Deleted old panel')); // delete old panel
}
message.delete();
panel = await message.channel.send(
new Discord.MessageEmbed()
.setColor(config.colour)
.setTitle(config.panel.title)
.setDescription(config.panel.description)
.setFooter(guild.name, guild.iconURL())
.setTimestamp()
); // send new panel
panel.react(config.panel.reaction); // add reaction
Setting.update({ value: panel.id }, { where: { key: 'panel_msg_id' }}); // update database
log.info(`${message.author.tag} created a panel widget`);
}
};

View File

@ -20,6 +20,8 @@ module.exports = {
args: true, args: true,
async execute(client, message, args, Ticket) { async execute(client, message, args, Ticket) {
const guild = client.guilds.cache.get(config.guild);
const notTicket = new Discord.MessageEmbed() const notTicket = new Discord.MessageEmbed()
.setColor(config.err_colour) .setColor(config.err_colour)
.setAuthor(message.author.username, message.author.displayAvatarURL()) .setAuthor(message.author.username, message.author.displayAvatarURL())
@ -27,7 +29,7 @@ module.exports = {
.setDescription('Use this command in the ticket channel you want to remove a user from, or mention the channel.') .setDescription('Use this command in the ticket channel you want to remove a user from, or mention the channel.')
.addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`) .addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`)
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`) .addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
.setFooter(message.guild.name, message.guild.iconURL()); .setFooter(guild.name, guild.iconURL());
let ticket; let ticket;
@ -60,12 +62,12 @@ module.exports = {
.setDescription(`You don't have permission to alter ${channel} as it does not belong to you and you are not staff.`) .setDescription(`You don't have permission to alter ${channel} as it does not belong to you and you are not staff.`)
.addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`) .addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`)
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`) .addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
let member = message.guild.member(message.mentions.users.first() || message.guild.members.cache.get(args[0])); let member = guild.member(message.mentions.users.first() || guild.members.cache.get(args[0]));
if(!member) if(!member)
return message.channel.send( return message.channel.send(
@ -76,7 +78,7 @@ module.exports = {
.setDescription('Please mention a valid member.') .setDescription('Please mention a valid member.')
.addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`) .addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`)
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`) .addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
try { try {
@ -94,7 +96,7 @@ module.exports = {
.setAuthor(member.user.username, member.user.displayAvatarURL()) .setAuthor(member.user.username, member.user.displayAvatarURL())
.setTitle('**Member remove**') .setTitle('**Member remove**')
.setDescription(`${member} has been removed by ${message.author}`) .setDescription(`${member} has been removed by ${message.author}`)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
@ -105,7 +107,7 @@ module.exports = {
.setAuthor(member.user.username, member.user.displayAvatarURL()) .setAuthor(member.user.username, member.user.displayAvatarURL())
.setTitle(':white_check_mark: **Member removed**') .setTitle(':white_check_mark: **Member removed**')
.setDescription(`${member} has been removed from <#${ticket.get('channel')}>`) .setDescription(`${member} has been removed from <#${ticket.get('channel')}>`)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
log.info(`${message.author.tag} removed a user from a ticket (#${message.channel.id})`); log.info(`${message.author.tag} removed a user from a ticket (#${message.channel.id})`);

23
src/commands/stats.js Normal file
View File

@ -0,0 +1,23 @@
/**
*
* @name DiscordTickets
* @author eartharoid <contact@eartharoid.me>
* @license GNU-GPLv3
*
*/
const ChildLogger = require('leekslazylogger').ChildLogger;
const log = new ChildLogger();
const Discord = require('discord.js');
const config = require('../../user/config');
module.exports = {
name: 'stats',
description: 'View ticket stats.',
usage: '',
aliases: ['data'],
example: '',
args: false,
async execute(client, message, args, Ticket) {
}
};

View File

@ -19,21 +19,22 @@ module.exports = {
args: false, args: false,
async execute(client, message, args, Ticket) { async execute(client, message, args, Ticket) {
const guild = client.guilds.cache.get(config.guild);
const supportRole = message.guild.roles.cache.get(config.staff_role); const supportRole = guild.roles.cache.get(config.staff_role);
if (!supportRole) if (!supportRole)
return message.channel.send( return message.channel.send(
new Discord.MessageEmbed() new Discord.MessageEmbed()
.setColor(config.err_colour) .setColor(config.err_colour)
.setTitle(':x: **Error**') .setTitle(':x: **Error**')
.setDescription(`${config.name} has not been set up correctly. Could not find a 'support team' role with the id \`${config.staff_role}\``) .setDescription(`${config.name} has not been set up correctly. Could not find a 'support team' role with the id \`${config.staff_role}\``)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
let context; let context = 'self';
let user = message.mentions.users.first() || message.guild.members.cache.get(args[0]); let user = message.mentions.users.first() || guild.members.cache.get(args[0]);
if(!user) { if(user) {
if(!message.member.roles.cache.has(config.staff_role)) if(!message.member.roles.cache.has(config.staff_role))
return message.channel.send( return message.channel.send(
new Discord.MessageEmbed() new Discord.MessageEmbed()
@ -43,15 +44,14 @@ module.exports = {
.setDescription('You don\'t have permission to list others\' tickets as you are not staff.') .setDescription('You don\'t have permission to list others\' tickets as you are not staff.')
.addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`) .addField('Usage', `\`${config.prefix}${this.name} ${this.usage}\`\n`)
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`) .addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
user = message.author;
context = 'staff'; context = 'staff';
} else {
user = message.author;
} }
context = 'self';
let openTickets = await Ticket.findAndCountAll({ let openTickets = await Ticket.findAndCountAll({
where: { where: {
@ -71,9 +71,9 @@ module.exports = {
let embed = new Discord.MessageEmbed() let embed = new Discord.MessageEmbed()
.setColor(config.colour) .setColor(config.colour)
.setAuthor(message.author.username, message.author.displayAvatarURL()) .setAuthor(user.username, user.displayAvatarURL())
.setTitle('Your tickets') .setTitle(`${context === 'self' ? 'Your' : user.username + '\'s'} tickets`)
.setFooter(message.guild.name + ' | This message will be deleted in 60 seconds', message.guild.iconURL()); .setFooter(guild.name + ' | This message will be deleted in 60 seconds', guild.iconURL());
if(config.transcripts.web.enabled) if(config.transcripts.web.enabled)
embed.setDescription(`You can access all of your ticket archives on the [web portal](${config.transcripts.web.server}/${user.id}).`); embed.setDescription(`You can access all of your ticket archives on the [web portal](${config.transcripts.web.server}/${user.id}).`);
@ -91,13 +91,14 @@ module.exports = {
for (let t in closedTickets.rows) { for (let t in closedTickets.rows) {
let desc = closedTickets.rows[t].topic.substring(0, 30); let desc = closedTickets.rows[t].topic.substring(0, 30);
let transcript = ''; let transcript = '';
if(fs.existsSync(`user/transcripts/text/${closedTickets.rows[t].channel}.txt`)) let c = closedTickets.rows[t].channel;
if(fs.existsSync(`user/transcripts/text/${c}.txt`) || fs.existsSync(`user/transcripts/raw/${c}.log`))
transcript = `\n> Type \`${config.prefix}transcript ${closedTickets.rows[t].id}\` to download text transcript.`; transcript = `\n> Type \`${config.prefix}transcript ${closedTickets.rows[t].id}\` to download text transcript.`;
closed.push(`> #${closedTickets.rows[t].id}: \`${desc}${desc.length > 20 ? '...' : ''}\`${transcript}`); closed.push(`> #${closedTickets.rows[t].id}: \`${desc}${desc.length > 20 ? '...' : ''}\`${transcript}`);
} }
let pre = context === 'self' ? 'You have' : user + ' has'; let pre = context === 'self' ? 'You have' : user.username + ' has';
embed.addField('Open tickets', openTickets.count === 0 ? `${pre} no open tickets.` : open.join('\n\n'), false); embed.addField('Open tickets', openTickets.count === 0 ? `${pre} no open tickets.` : open.join('\n\n'), false);
embed.addField('Closed tickets', closedTickets.count === 0 ? `${pre} no old tickets` : closed.join('\n\n'), false); embed.addField('Closed tickets', closedTickets.count === 0 ? `${pre} no old tickets` : closed.join('\n\n'), false);

View File

@ -18,6 +18,9 @@ module.exports = {
example: 'transcript 57', example: 'transcript 57',
args: false, args: false,
async execute(client, message, args, Ticket) { async execute(client, message, args, Ticket) {
/** @TODO TRY TO SEND ATTACHMENT TO DM */ /**
* @TODO TRY TO SEND ATTACHMENT TO DM
* @TODO ONLY ALLOW CREATOR AND STAFF TO RUN CMD
*/
} }
}; };

View File

@ -11,7 +11,7 @@ const log = new ChildLogger();
module.exports = { module.exports = {
event: 'debug', event: 'debug',
execute(client, e) { execute(client, [e]) {
log.debug(e); log.debug(e);
} }
}; };

View File

@ -11,7 +11,7 @@ const log = new ChildLogger();
module.exports = { module.exports = {
event: 'error', event: 'error',
execute(client, e) { execute(client, [e]) {
log.error(e); log.error(e);
} }
}; };

View File

@ -10,19 +10,69 @@ const Discord = require('discord.js');
const ChildLogger = require('leekslazylogger').ChildLogger; const ChildLogger = require('leekslazylogger').ChildLogger;
const log = new ChildLogger(); const log = new ChildLogger();
const config = require('../../user/config'); const config = require('../../user/config');
const fs = require('fs');
const dtf = require('@eartharoid/dtf');
module.exports = { module.exports = {
event: 'message', event: 'message',
async execute(client, message, Ticket) { async execute(client, [message], {Ticket, Setting}) {
const guild = client.guilds.cache.get(config.guild);
if (message.author.bot || message.author.id === client.user.id) return; if (message.author.bot || message.author.id === client.user.id) return;
if (message.channel.type === 'dm') { if (message.channel.type === 'dm') {
log.console(`Received a DM from ${message.author.tag}: ${message.cleanContent}`); log.console(`Received a DM from ${message.author.tag}: ${message.cleanContent}`);
return message.channel.send(`Hello there, ${message.author.username}! return message.channel.send(`Hello there, ${message.author.username}!
I am the support bot for **${client.guilds.cache.get(config.guild)}**. I am the support bot for **${guild}**.
Type \`${config.prefix}new\` on the server to create a new ticket.`); Type \`${config.prefix}new\` on the server to create a new ticket.`);
} }
if (message.guild.id !== guild.id)
return message.reply(`This bot can only be used within the "${guild}" server`);
/**
*
* Ticket transcripts
*
*/
let ticket = await Ticket.findOne({ where: { channel: message.channel.id } });
if(ticket) {
if(config.transcripts.text.enabled) {
let path = `user/transcripts/text/${message.channel.id}.txt`;
let time = dtf('HH:mm:ss n_D MMM YY', message.createdAt),
name = message.author.tag,
msg = message.cleanContent;
let string = `[${time}] [${name}] :> ${msg}`;
fs.appendFileSync(path, string + '\n');
}
if(config.transcripts.web.enabled) {
let path = `user/transcripts/raw/${message.channel.id}.log`;
let embeds = [];
for (let embed in message.embeds)
embeds.push(message.embeds[embed].toJSON());
fs.appendFileSync(path, JSON.stringify({
id: message.id,
type: 'UNKNOWN',
author: message.author.id,
content: message.content,
// deleted: false,
time: message.createdTimestamp,
embeds: embeds,
attachments: [...message.attachments]
}) + ', \n');
}
}
/**
*
* Command handler
*
*/
const prefixRegex = new RegExp(`^(<@!?${client.user.id}>|\\${config.prefix})\\s*`); const prefixRegex = new RegExp(`^(<@!?${client.user.id}>|\\${config.prefix})\\s*`);
if (!prefixRegex.test(message.content)) return; if (!prefixRegex.test(message.content)) return;
const [, matchedPrefix] = message.content.match(prefixRegex); const [, matchedPrefix] = message.content.match(prefixRegex);
@ -38,7 +88,7 @@ Type \`${config.prefix}new\` on the server to create a new ticket.`);
.setColor(config.err_colour) .setColor(config.err_colour)
.setTitle(':x: No permission') .setTitle(':x: No permission')
.setDescription(`**You do not have permission to use the \`${command.name}\` command** (requires \`${command.permission}\`).`) .setDescription(`**You do not have permission to use the \`${command.name}\` command** (requires \`${command.permission}\`).`)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
} }
@ -48,7 +98,7 @@ Type \`${config.prefix}new\` on the server to create a new ticket.`);
.setColor(config.err_colour) .setColor(config.err_colour)
.addField('Usage', `\`${config.prefix}${command.name} ${command.usage}\`\n`) .addField('Usage', `\`${config.prefix}${command.name} ${command.usage}\`\n`)
.addField('Help', `Type \`${config.prefix}help ${command.name}\` for more information`) .addField('Help', `Type \`${config.prefix}help ${command.name}\` for more information`)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
if (!client.cooldowns.has(command.name)) client.cooldowns.set(command.name, new Discord.Collection()); if (!client.cooldowns.has(command.name)) client.cooldowns.set(command.name, new Discord.Collection());
@ -67,7 +117,7 @@ Type \`${config.prefix}new\` on the server to create a new ticket.`);
new Discord.MessageEmbed() new Discord.MessageEmbed()
.setColor(config.err_colour) .setColor(config.err_colour)
.setDescription(`:x: Please wait ${timeLeft.toFixed(1)} second(s) before reusing the \`${command.name}\` command.`) .setDescription(`:x: Please wait ${timeLeft.toFixed(1)} second(s) before reusing the \`${command.name}\` command.`)
.setFooter(message.guild.name, message.guild.iconURL()) .setFooter(guild.name, guild.iconURL())
); );
} }
} }
@ -76,7 +126,7 @@ Type \`${config.prefix}new\` on the server to create a new ticket.`);
setTimeout(() => timestamps.delete(message.author.id), cooldownAmount); setTimeout(() => timestamps.delete(message.author.id), cooldownAmount);
try { try {
command.execute(client, message, args, Ticket); command.execute(client, message, args, Ticket, Setting);
log.console(`${message.author.tag} used the '${command.name}' command`); log.console(`${message.author.tag} used the '${command.name}' command`);
} catch (error) { } catch (error) {
log.warn(`An error occurred whilst executing the '${command.name}' command`); log.warn(`An error occurred whilst executing the '${command.name}' command`);

View File

@ -0,0 +1,199 @@
/**
*
* @name DiscordTickets
* @author eartharoid <contact@eartharoid.me>
* @license GNU-GPLv3
*
*/
const ChildLogger = require('leekslazylogger').ChildLogger;
const log = new ChildLogger();
const Discord = require('discord.js');
const config = require('../../user/config');
const fs = require('fs');
module.exports = {
event: 'messageReactionAdd',
async execute(client, [r, u], {Ticket, Setting}) {
if (r.partial)
try {
await r.fetch();
} catch (err) {
log.error(err);
return;
}
let panelID = await Setting.findOne({ where: { key: 'panel_msg_id' } });
if (!panelID) return;
if(r.message.id !== panelID.get('value')) return;
if (r.emoji.name !== config.panel.reaction || u.id === client.user.id) return;
let channel = r.message.channel;
const supportRole = channel.guild.roles.cache.get(config.staff_role);
if (!supportRole)
return channel.send(
new Discord.MessageEmbed()
.setColor(config.err_colour)
.setTitle(':x: **Error**')
.setDescription(`${config.name} has not been set up correctly. Could not find a 'support team' role with the id \`${config.staff_role}\``)
.setFooter(channel.guild.name, channel.guild.iconURL())
);
// everything is cool
await r.users.remove(u.id); // effectively cancel reaction
let tickets = await Ticket.findAndCountAll({
where: {
creator: u.id,
open: true
},
limit: config.tickets.max
});
if (tickets.count >= config.tickets.max) {
let ticketList = [];
for (let t in tickets.rows) {
let desc = tickets.rows[t].topic.substring(0, 30);
ticketList
.push(`<#${tickets.rows[t].channel}>: \`${desc}${desc.length > 30 ? '...' : ''}\``);
}
let dm = u.dmChannel || await u.createDM();
try {
return dm.send(
new Discord.MessageEmbed()
.setColor(config.err_colour)
.setAuthor(u.username, u.displayAvatarURL())
.setTitle(`:x: **You already have ${tickets.count} or more open tickets**`)
.setDescription(`Use \`${config.prefix}close\` in a server channel to close unneeded tickets.\n\n${ticketList.join(',\n')}`)
.setFooter(channel.guild.name, channel.guild.iconURL())
);
} catch (e) {
let m = await channel.send(
new Discord.MessageEmbed()
.setColor(config.err_colour)
.setAuthor(u.username, u.displayAvatarURL())
.setTitle(`:x: **You already have ${tickets.count} or more open tickets**`)
.setDescription(`Use \`${config.prefix}close\` to close unneeded tickets.\n\n${ticketList.join(',\n')}`)
.setFooter(channel.guild.name + ' | This message will be deleted in 15 seconds', channel.guild.iconURL())
);
return m.delete({ timeout: 15000 });
}
}
let topic = 'No topic given (created via panel)';
let ticket = await Ticket.create({
channel: '',
creator: u.id,
open: true,
archived: false,
topic: topic
});
let name = 'ticket-' + ticket.get('id');
channel.guild.channels.create(name, {
type: 'text',
topic: `${u} | ${topic}`,
parent: config.tickets.category,
permissionOverwrites: [{
id: channel.guild.roles.everyone,
deny: ['VIEW_CHANNEL', 'SEND_MESSAGES']
},
{
id: channel.guild.member(u),
allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY']
},
{
id: supportRole,
allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY']
}
],
reason: 'User requested a new support ticket channel'
}).then(async c => {
Ticket.update({
channel: c.id
}, {
where: {
id: ticket.id
}
});
require('../utils/archive').create(client, c); // create files
let ping;
switch (config.tickets.ping) {
case 'staff':
ping = `<@&${config.staff_role}>,\n`;
break;
case false:
ping = '';
break;
default:
ping = `@${config.tickets.ping},\n`;
}
await c.send(ping + `${u} has created a new ticket`);
if (config.tickets.send_img) {
const images = fs.readdirSync('user/images');
await c.send({
files: [
'user/images/' +
images[Math.floor(Math.random() * images.length)]
]
});
}
let text = config.tickets.text
.replace('{{ name }}', u.username)
.replace('{{ tag }}', u);
let w = await c.send(
new Discord.MessageEmbed()
.setColor(config.colour)
.setAuthor(u.username, u.displayAvatarURL())
.setDescription(text)
.addField('Topic', `\`${topic}\``)
.setFooter(channel.guild.name, channel.guild.iconURL())
);
if (config.tickets.pin)
await w.pin();
// await w.pin().then(m => m.delete()); // oopsie, this deletes the pinned message
if (config.logs.discord.enabled)
client.channels.cache.get(config.logs.discord.channel).send(
new Discord.MessageEmbed()
.setColor(config.colour)
.setAuthor(u.username, u.displayAvatarURL())
.setTitle('New ticket (via panel)')
.setDescription(`\`${topic}\``)
.addField('Creator', u, true)
.addField('Channel', c, true)
.setFooter(channel.guild.name, channel.guild.iconURL())
.setTimestamp()
);
log.info(`${u.tag} created a new ticket (#${name}) via panel`);
}).catch(log.error);
}
};

View File

@ -0,0 +1,27 @@
/**
*
* @name DiscordTickets
* @author eartharoid <contact@eartharoid.me>
* @license GNU-GPLv3
*
*/
const Discord = require('discord.js');
const ChildLogger = require('leekslazylogger').ChildLogger;
const log = new ChildLogger();
const config = require('../../user/config');
const fs = require('fs');
const dtf = require('@eartharoid/dtf');
module.exports = {
event: 'messageUpdate',
async execute(client, [o, n], {Ticket, Setting}) {
/**
* CHECK IF O === N
*/
console.log(o.author.tag);
// https://discord.js.org/#/docs/main/stable/class/Client?scrollTo=e-messageUpdate
// append new to raw
}
};

View File

@ -11,8 +11,8 @@ const log = new ChildLogger();
module.exports = { module.exports = {
event: 'rateLimit', event: 'rateLimit',
execute(client, limit) { execute(client, [limit]) {
log.warn('Rate-limited!'); log.warn('Rate-limited! (Enable debug mode in config for details)');
log.debug(limit); log.debug(limit);
} }
}; };

View File

@ -12,7 +12,7 @@ const config = require('../../user/config');
module.exports = { module.exports = {
event: 'ready', event: 'ready',
execute(client) { execute(client, [e], {Ticket, Setting}) {
log.success(`Authenticated as ${client.user.tag}`); log.success(`Authenticated as ${client.user.tag}`);

View File

@ -11,7 +11,7 @@ const log = new ChildLogger();
module.exports = { module.exports = {
event: 'warn', event: 'warn',
execute(client, e) { execute(client, [e]) {
log.warn(e); log.warn(e);
} }
}; };

View File

@ -11,7 +11,8 @@ const Discord = require('discord.js');
const fs = require('fs'); const fs = require('fs');
const leeks = require('leeks.js'); const leeks = require('leeks.js');
const client = new Discord.Client({ const client = new Discord.Client({
autoReconnect: true autoReconnect: true,
partials: ['MESSAGE', 'CHANNEL', 'REACTION']
}); });
client.events = new Discord.Collection(); client.events = new Discord.Collection();
client.commands = new Discord.Collection(); client.commands = new Discord.Collection();
@ -66,7 +67,17 @@ Ticket.init({
modelName: 'ticket' modelName: 'ticket'
}); });
class Setting extends Model {}
Setting.init({
key: DataTypes.STRING,
value: DataTypes.STRING,
}, {
sequelize,
modelName: 'setting'
});
Ticket.sync(); Ticket.sync();
Setting.sync();
/** /**
* event loader * event loader
@ -75,7 +86,8 @@ const events = fs.readdirSync('src/events').filter(file => file.endsWith('.js'))
for (const file of events) { for (const file of events) {
const event = require(`./events/${file}`); const event = require(`./events/${file}`);
client.events.set(event.event, event); client.events.set(event.event, event);
client.on(event.event, e => client.events.get(event.event).execute(client, e, Ticket)); // client.on(event.event, e => client.events.get(event.event).execute(client, e, Ticket, Setting));
client.on(event.event, (e1, e2) => client.events.get(event.event).execute(client, [e1, e2], {Ticket, Setting}));
log.console(log.format(`> Loaded &7${event.event}&f event`)); log.console(log.format(`> Loaded &7${event.event}&f event`));
} }
@ -93,7 +105,8 @@ log.info(`Loaded ${events.length} events and ${commands.length} commands`);
process.on('unhandledRejection', error => { process.on('unhandledRejection', error => {
log.warn('An error was not caught'); log.warn('An error was not caught');
log.error(`Uncaught error: \n${error.stack}`); log.warn(`Uncaught ${error.name}: ${error.message}`);
log.error(error);
}); });
client.login(process.env.TOKEN); client.login(process.env.TOKEN);

View File

@ -8,15 +8,43 @@
const ChildLogger = require('leekslazylogger').ChildLogger; const ChildLogger = require('leekslazylogger').ChildLogger;
const log = new ChildLogger(); const log = new ChildLogger();
const lineReader = require('line-reader');
const fs = require('fs');
const config = require('../../user/config');
module.exports.create = (client, channel) => { module.exports.create = (client, channel) => {
}; // channel.members
module.exports.addUser = (client, channel, user) => { if(config.transcripts.text.enabled) {
// text/channel.txt
}
if(config.transcripts.web.enabled) {
// raw/channel.log
}
}; };
module.exports.addMessage = (client, channel, message) => { module.exports.addMessage = (client, channel, message) => {
// if !entities.users.user, add
};
module.exports.export = (client, channel) => {
let path = `user/transcripts/raw/${channel.id}.log`;
if(config.transcripts.web.enabled && fs.existsSync(path)) {
lineReader.eachLine(path, (line, last) => {
console.log(line);
//if raw id exists, overwrite previous
});
}
/**
* @TODO users, roles, etc
* check channel.members again!
* */
}; };

View File

@ -7,6 +7,8 @@
*/ */
const { version, homepage } = require('../../package.json'); const { version, homepage } = require('../../package.json');
const link = require('terminal-link');
module.exports = (leeks) => { module.exports = (leeks) => {
console.log(leeks.colours.cyan(` console.log(leeks.colours.cyan(`
######## #### ###### ###### ####### ######## ######## ######## #### ###### ###### ####### ######## ########
@ -26,6 +28,7 @@ module.exports = (leeks) => {
## #### ###### ## ## ######## ## ###### ## #### ###### ## ## ######## ## ######
`)); `));
console.log(leeks.colours.cyanBright(`DiscordTickets bot v${version} by eartharoid`)); console.log(leeks.colours.cyanBright(`DiscordTickets bot v${version} by eartharoid`));
console.log(leeks.colours.cyanBright(homepage)); console.log(leeks.colours.cyanBright(homepage + '\n'));
console.log(leeks.colours.cyanBright(`Please ${link('donate', 'https://ko-fi.com/eartharoid')} if you find this bot useful`));
console.log('\n\n'); console.log('\n\n');
}; };

180
src/utils/panel.js Normal file
View File

@ -0,0 +1,180 @@
/**
*
* @name DiscordTickets
* @author eartharoid <contact@eartharoid.me>
* @license GNU-GPLv3
*
*/
const ChildLogger = require('leekslazylogger').ChildLogger;
const log = new ChildLogger();
const Discord = require('discord.js');
const fs = require('fs');
const config = require('../../user/config');
module.exports = async (client, Ticket, Setting) => {
let panelID = await Setting.findOne({ where: { key: 'panel_msg_id' } });
if (!panelID) return;
let chanID = await Setting.findOne({ where: { key: 'panel_chan_id' } });
if (!chanID) return;
let channel = client.channels.cache.get(chanID.get('value'));
if (!channel)
return Setting.destroy({ where: { key: 'panel_chan_id' } });
let panel = channel.messages.cache.get(panelID.get('value'));
if(!panel)
return Setting.destroy({ where: { key: 'panel_msg_id' } });
const collector = panel.createReactionCollector(
(r, u) => r.emoji.name === config.panel.reaction && u.id !== client.user.id);
collector.on('collect', async (r, u) => {
await r.users.remove(u.id); // effectively cancel reaction
const supportRole = channel.guild.roles.cache.get(config.staff_role);
if (!supportRole)
return channel.send(
new Discord.MessageEmbed()
.setColor(config.err_colour)
.setTitle(':x: **Error**')
.setDescription(`${config.name} has not been set up correctly. Could not find a 'support team' role with the id \`${config.staff_role}\``)
.setFooter(channel.guild.name, channel.guild.iconURL())
);
let tickets = await Ticket.findAndCountAll({
where: {
creator: u.id,
open: true
},
limit: config.tickets.max
});
if (tickets.count >= config.tickets.max) {
let ticketList = [];
for (let t in tickets.rows) {
let desc = tickets.rows[t].topic.substring(0, 30);
ticketList
.push(`<#${tickets.rows[t].channel}>: \`${desc}${desc.length > 30 ? '...' : ''}\``);
}
let dm = u.dmChannel || await u.createDM();
let m = await dm.send(
new Discord.MessageEmbed()
.setColor(config.err_colour)
.setAuthor(u.username, u.displayAvatarURL())
.setTitle(`:x: **You already have ${tickets.count} or more open tickets**`)
.setDescription(`Use \`${config.prefix}close\` to close unneeded tickets.\n\n${ticketList.join(',\n')}`)
.setFooter(channel.guild.name + ' | This message will be deleted in 15 seconds', channel.guild.iconURL())
);
return m.delete({ timeout: 15000 });
}
let topic = 'No topic given (created via panel)';
let ticket = await Ticket.create({
channel: '',
creator: u.id,
open: true,
archived: false,
topic: topic
});
let name = 'ticket-' + ticket.get('id');
channel.guild.channels.create(name, {
type: 'text',
topic: `${u} | ${topic}`,
parent: config.tickets.category,
permissionOverwrites: [{
id: channel.guild.roles.everyone,
deny: ['VIEW_CHANNEL', 'SEND_MESSAGES']
},
{
id: channel.guild.member(u),
allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY']
},
{
id: supportRole,
allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY']
}
],
reason: 'User requested a new support ticket channel'
}).then(async c => {
Ticket.update({
channel: c.id
}, {
where: {
id: ticket.id
}
});
let ping;
switch (config.tickets.ping) {
case 'staff':
ping = `<@&${config.staff_role}>,\n`;
break;
case false:
ping = '';
break;
default:
ping = `@${config.tickets.ping},\n`;
}
await c.send(ping + `${u} has created a new ticket`);
if (config.tickets.send_img) {
const images = fs.readdirSync('user/images');
await c.send({
files: [
'user/images/' +
images[Math.floor(Math.random() * images.length)]
]
});
}
let text = config.tickets.text
.replace('{{ name }}', u.username)
.replace('{{ tag }}', u);
let w = await c.send(
new Discord.MessageEmbed()
.setColor(config.colour)
.setAuthor(u.username, u.displayAvatarURL())
.setDescription(text)
.addField('Topic', `\`${topic}\``)
.setFooter(channel.guild.name, channel.guild.iconURL())
);
if (config.tickets.pin)
await w.pin();
// await w.pin().then(m => m.delete()); // oopsie, this deletes the pinned message
if (config.logs.discord.enabled)
client.channels.cache.get(config.logs.discord.channel).send(
new Discord.MessageEmbed()
.setColor(config.colour)
.setAuthor(u.username, u.displayAvatarURL())
.setTitle('New ticket (via panel)')
.setDescription(`\`${topic}\``)
.addField('Creator', u, true)
.addField('Channel', c, true)
.setFooter(channel.guild.name, channel.guild.iconURL())
.setTimestamp()
);
log.info(`${u.tag} created a new ticket (#${name}) via panel`);
}).catch(log.error);
});
};

View File

@ -8,10 +8,13 @@
const ChildLogger = require('leekslazylogger').ChildLogger; const ChildLogger = require('leekslazylogger').ChildLogger;
const log = new ChildLogger(); const log = new ChildLogger();
const leeks = require('leeks.js');
const fetch = require('node-fetch'); const fetch = require('node-fetch');
const config = require('../../user/config'); const config = require('../../user/config');
let {version} = require('../../package.json'); let {version} = require('../../package.json');
version = 'v' + version; version = 'v' + version;
const boxen = require('boxen');
const link = require('terminal-link');
module.exports = () => { module.exports = () => {
if(!config.updater) if(!config.updater)
@ -21,11 +24,24 @@ module.exports = () => {
.then(res => res.json()) .then(res => res.json())
.then(json => { .then(json => {
const update = json[0]; const update = json[0];
let notice = [];
if (version !== update.tag_name) { if (version !== update.tag_name) {
log.notice('There is an update available for Discord Tickets'); log.notice(log.f(`There is an update available for Discord Tickets (${version} -> ${update.tag_name})`));
log.info(`Download "&f${update.name}&3" from &6https://github.com/eartharoid/DiscordTickets/releases/`);
log.notice(`You currently have ${version}; The latest is ${update.tag_name}`); notice.push(`&6You are currently using &c${version}&6, the latest is &a${update.tag_name}&6.`);
notice.push(`&6Download "&f${update.name}&6" from`);
notice.push(link('&6the GitHub releases page', 'https://github.com/eartharoid/DiscordTickets/releases/'));
console.log(
boxen(log.f(notice.join('\n')), {
padding: 1,
margin: 1,
align: 'center',
borderColor: 'yellow',
borderStyle: 'round'
})
);
} }
}); });
}; };

View File

@ -54,11 +54,17 @@ module.exports = {
keep_for: 90, keep_for: 90,
}, },
web: { web: {
enabled: false, enabled: true,
server: 'https://tickets.example.com', // WITHOUT! trailing / server: 'https://tickets.example.com', // WITHOUT! trailing /
} }
}, },
panel: {
title: 'Support Tickets',
description: 'Need help? No problem! React to this panel to create a new support ticket so our Support Team can assist you.',
reaction: '🧾'
},
storage: { storage: {
type: 'sqlite' type: 'sqlite'
}, },

10
user/transcripts/.json Normal file
View File

@ -0,0 +1,10 @@
{
"entities": {
"users": {},
"channels": {},
"roles": {}
},
"messages": [],
"channel_name": ""
}

View File

@ -0,0 +1,661 @@
{
"entities": {
"users": {
"173237945149423619": {
"avatar": "https://cdn.discordapp.com/avatars/173237945149423619/a_20579a6ab02c959ce2f482ee6ec9a187.gif",
"username": "Kanin",
"discriminator": "0001",
"badge": null
},
"337481187419226113": {
"avatar": "https://cdn.discordapp.com/avatars/337481187419226113/ae4a1951d381d6bca97cdb4ce307fbce.png",
"username": "Naila",
"discriminator": "1361",
"badge": "bot"
},
"610443119225471007": {
"avatar": "https://cdn.discordapp.com/avatars/610443119225471007/4c9ca7e3a57c71098bf0c166d9772135.png",
"username": "Naila likes Testing",
"discriminator": "8783",
"badge": "bot"
},
"9999": {
"avatar": "https://bowser65.xyz/avatar.b1efbb7f.png",
"username": "Bowoser the webhook",
"discriminator": "0000",
"badge": "Bot"
}
},
"channels": {
"645102034579750922": {
"name": "python-testing"
}
},
"roles": {
"686034948440064070": {
"name": "Test role",
"color": 10181046
},
"645429085656580127": {
"name": "Kanin's Bots",
"color": 7506394
}
}
},
"messages": [
{
"id": "1",
"author": "9999",
"time": 1576091466245,
"content": "Did you know that webhooks can use [named links](https://myanimelist.net/anime/40010)? p cool isn't it. Spoiler: ||nobody cares :^)||"
},
{
"id": "1",
"type": 7,
"author": "337481187419226113",
"time": 1576091466245,
"content": "Wheres <@337481187419226113>? In the server!"
},
{
"id": "1",
"type": 8,
"author": "173237945149423619",
"time": 1576091466245,
"content": "<@173237945149423619> just boosted the server!"
},
{
"id": "1",
"type": 10,
"author": "9999",
"time": 1576091466245,
"content": "<@9999> just boosted the server! Powercord has achieved **Level 2!**"
},
{
"id": "1",
"author": "9999",
"time": 1576091466245,
"deleted": true,
"content": "Test message"
},
{
"id": "1",
"author": "9999",
"time": 1576091466245,
"content": "Test message"
},
{
"type": 10,
"id": "1",
"author": "9999",
"time": 1576091466245,
"content": "<@9999> just boosted the server! Powercord has achieved **Level 2!**"
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583650388316,
"content": "https://open.spotify.com/track/3lHSI9u83d3W5jPcvs4Mvt?si=ypkN7LIvRmi_X4gO7CSuCQ",
"embeds": [
{
"thumbnail": {
"url": "https://i.scdn.co/image/ab67616d0000b273fd546e748b9276138041b4e1",
"proxy_url": "https://images-ext-2.discordapp.net/external/HA-QRIWHxw-U_hM4gWnvimwy-v8vkNh7ZT1c78N0nto/https/i.scdn.co/image/ab67616d0000b273fd546e748b9276138041b4e1",
"width": 640,
"height": 640
},
"provider": {
"name": "Spotify",
"url": null
},
"type": "link",
"description": "Firewall, a song by Kompany on Spotify",
"url": "https://open.spotify.com/track/3lHSI9u83d3W5jPcvs4Mvt?si=ypkN7LIvRmi_X4gO7CSuCQ",
"title": "Firewall"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583650426875,
"content": "https://twitter.com/discordapp/status/1234924931328012288",
"embeds": [
{
"footer": {
"text": "Twitter",
"icon_url": "https://abs.twimg.com/icons/apple-touch-icon-192x192.png",
"proxy_icon_url": "https://images-ext-1.discordapp.net/external/bXJWV2Y_F3XSra_kEqIYXAAsI3m1meckfLhYuWzxIfI/https/abs.twimg.com/icons/apple-touch-icon-192x192.png"
},
"image": {
"url": "https://pbs.twimg.com/media/ESNU_9MUEAAQs9Q.jpg:large",
"proxy_url": "https://images-ext-1.discordapp.net/external/KFg4sHycrkWRsrjt95-xkAZPBdPMxRgagMmMK-BDaeo/https/pbs.twimg.com/media/ESNU_9MUEAAQs9Q.jpg%3Alarge",
"width": 2048,
"height": 1366
},
"id": "1",
"author": {
"name": "Discord (@discordapp)",
"url": "https://twitter.com/discordapp",
"icon_url": "https://pbs.twimg.com/profile_images/1212820842712727552/XCuWn8yF_bigger.jpg",
"proxy_icon_url": "https://images-ext-1.discordapp.net/external/1IRnHq-wu1ZgquR75Iy35WkDn2N0g1yd5wOZBjb6aHM/https/pbs.twimg.com/profile_images/1212820842712727552/XCuWn8yF_bigger.jpg"
},
"fields": [
{
"name": "Retweets",
"value": "93055",
"inline": true
},
{
"name": "Likes",
"value": "60415",
"inline": true
}
],
"color": 1942002,
"type": "rich",
"description": "We wanted to do something special for those who couldn\u2019t attend PAX East with us. \n\nRT + follow us by 3/8 for a chance to win everything pictured (yes, gaming chair IS included)",
"url": "https://twitter.com/discordapp/status/1234924931328012288"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583650448346,
"content": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"embeds": [
{
"thumbnail": {
"url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg",
"proxy_url": "https://images-ext-1.discordapp.net/external/l-AFI3CsQVpcpSDYFtsDvDKag46BJ-uaQ9BTcU2JPC8/https/i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg",
"width": 1280,
"height": 720
},
"video": {
"url": "https://www.youtube.com/embed/dQw4w9WgXcQ",
"width": 1280,
"height": 720
},
"provider": {
"name": "YouTube",
"url": "https://www.youtube.com"
},
"id": "1",
"author": {
"name": "RickAstleyVEVO",
"url": "https://www.youtube.com/channel/UC38IQsAvIsxxjztdMZQtwHA"
},
"color": 16711680,
"type": "video",
"description": "Rick Astley's official music video for \u201cNever Gonna Give You Up\u201d \nListen to Rick Astley: https://RickAstley.lnk.to/_listenYD\n\nSubscribe to the official Rick Astley YouTube channel: https://RickAstley.lnk.to/subscribeYD\n\nFollow Rick Astley:\nFacebook: https://RickAstley.lnk.to/f...",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"title": "Rick Astley - Never Gonna Give You Up (Video)"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583650530255,
"attachments": [
{
"id": 686029297001037844,
"filename": "handcuffs.mp4",
"size": 66494,
"height": 276,
"width": 500,
"url": "https://cdn.discordapp.com/attachments/686027141946671186/686029297001037844/handcuffs.mp4",
"proxy_url": "https://media.discordapp.net/attachments/686027141946671186/686029297001037844/handcuffs.mp4"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583650662623,
"attachments": [
{
"id": 686029850678525970,
"filename": "Alan-Walker_Play.mp3",
"size": 4506155,
"height": null,
"width": null,
"url": "https://cdn.discordapp.com/attachments/686027141946671186/686029850678525970/Alan-Walker_Play.mp3",
"proxy_url": "https://media.discordapp.net/attachments/686027141946671186/686029850678525970/Alan-Walker_Play.mp3"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583650669549,
"content": "https://cdn.discordapp.com/attachments/686027141946671186/686029297001037844/handcuffs.mp4",
"embeds": [
{
"video": {
"url": "https://cdn.discordapp.com/attachments/686027141946671186/686029297001037844/handcuffs.mp4",
"width": 500,
"height": 276,
"proxy_url": "https://media.discordapp.net/attachments/686027141946671186/686029297001037844/handcuffs.mp4"
},
"type": "video",
"url": "https://cdn.discordapp.com/attachments/686027141946671186/686029297001037844/handcuffs.mp4"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583650676893,
"content": "https://cdn.discordapp.com/attachments/686027141946671186/686029850678525970/Alan-Walker_Play.mp3"
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583650695396,
"content": "n!help"
},
{
"id": "1",
"author": "337481187419226113",
"time": 1583650695607,
"embeds": [
{
"id": "1",
"author": {
"name": "Here is the help you requested!"
},
"color": 11533055,
"type": "rich",
"description": "**Support server**: https://discord.gg/fox\n**Bot invite**: [Recommended perms](https://discordapp.com/oauth2/authorize?client_id=337481187419226113&scope=bot&permissions=502656087) | [No perms](https://discordapp.com/oauth2/authorize?client_id=337481187419226113&scope=bot)\n\n__**Animals**__\nbear, bird, dolphin, duck, elephant, fox, giraffe, hippo, horse, killerwhale, koala, lion, meow, panda, pig, redpanda, shark, snake, spider, turtle, woof\n\n__**BotInfo**__\napis, invite, stats\n\n__**Dev**__\nmodules\n\n__**GuildManagement**__\nguildset\n\n__**Help**__\nhelp\n\n__**Music**__\nautoplay, disconnect, now, pause, play, queue, remove, repeat, search, seek, shuffle, skip, songinfo, stop, volume\n\n__**NSFW**__\nboobbot, sheri\n\n__**Registration**__\nregister, setreg, unregister\n\n__**Reminders**__\ndeletereminder, remind, reminders\n\n__**Social**__\nbite, blush, cry, cuddle, dance, greet, highfive, hug, insult, kiss, lick, pat, poke, pout, punch, ship, shoot, shrug, slap, sleepy, smile, stare, thumbsup, tickle\n\n__**Testing**__\narchive, embed\n\n__**UserInfo**__\nuser\n\n__**Welcomer**__\nwelcomer\n\n\nType `n!help [command]` for more info on a command.\nYou can also type `n!help [category]` for more info on a category."
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583651353324,
"content": "n!eval\n```py\nfrom random import randint\nfrom datetime import datetime\nawait channel.send(embed=discord.Embed(color=random.randint(0, 0xFFFFFF), title=\"I like pizza\", description=\":D\", url=\"https://google.com/\", timestamp=datetime.now()).set_footer(text=\"This is the footer\", icon_url=\"https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.purposegames.com%2Fimages%2Fgames%2Fbackground%2F355%2F355380.png&f=1&nofb=1\").set_image(url=\"https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fi.ytimg.com%2Fvi%2FxWYSzqDvTmQ%2Fhqdefault.jpg&f=1&nofb=1\").set_thumbnail(url=\"https://external-content.duckduckgo.com/iu/?u=http%3A%2F%2Fgetwallpapers.com%2Fwallpaper%2Ffull%2F6%2F3%2F7%2F17853.jpg&f=1&nofb=1\").set_author(name=\"This is the author\", url=\"https://discordapp.com/\", icon_url=\"https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.meteo.be%2Fmeteo%2Fdownload%2Ffr%2F196752%2Fimage%2Fgertgoesaert_29122006_glenelg_zuid-australi__2.jpg&f=1&nofb=1\").add_field(name=\"Field 1\", value=\"Not inline\", inline=False).add_field(name=\"Field 2\", value=\"Still not inline\", inline=False).add_field(name=\"Field 3\", value=\"Okay this one is inline\"))\n```"
},
{
"id": "1",
"author": "337481187419226113",
"time": 1583651353470,
"embeds": [
{
"footer": {
"text": "This is the footer",
"icon_url": "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.purposegames.com%2Fimages%2Fgames%2Fbackground%2F355%2F355380.png&f=1&nofb=1",
"proxy_icon_url": "https://images-ext-2.discordapp.net/external/g1ZlkveRtSjquZ_9lsZN26CV9g-T0Cqzjr287aUTVdY/%3Fu%3Dhttps%253A%252F%252Fwww.purposegames.com%252Fimages%252Fgames%252Fbackground%252F355%252F355380.png%26f%3D1%26nofb%3D1/https/external-content.duckduckgo.com/iu/"
},
"image": {
"url": "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fi.ytimg.com%2Fvi%2FxWYSzqDvTmQ%2Fhqdefault.jpg&f=1&nofb=1",
"proxy_url": "https://images-ext-1.discordapp.net/external/W0zZckLByXwVPGJcdi2R-yA2qCOxPnSwNTaly3kd4-s/%3Fu%3Dhttps%253A%252F%252Fi.ytimg.com%252Fvi%252FxWYSzqDvTmQ%252Fhqdefault.jpg%26f%3D1%26nofb%3D1/https/external-content.duckduckgo.com/iu/",
"width": 480,
"height": 360
},
"thumbnail": {
"url": "https://external-content.duckduckgo.com/iu/?u=http%3A%2F%2Fgetwallpapers.com%2Fwallpaper%2Ffull%2F6%2F3%2F7%2F17853.jpg&f=1&nofb=1",
"proxy_url": "https://images-ext-2.discordapp.net/external/SkZBSZG4Qbg4N4YRkmX99YULtwwgArGgkZUnfqLhDiQ/%3Fu%3Dhttp%253A%252F%252Fgetwallpapers.com%252Fwallpaper%252Ffull%252F6%252F3%252F7%252F17853.jpg%26f%3D1%26nofb%3D1/https/external-content.duckduckgo.com/iu/",
"width": 2031,
"height": 1625
},
"id": "1",
"author": {
"name": "This is the author",
"url": "https://discordapp.com/",
"icon_url": "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.meteo.be%2Fmeteo%2Fdownload%2Ffr%2F196752%2Fimage%2Fgertgoesaert_29122006_glenelg_zuid-australi__2.jpg&f=1&nofb=1",
"proxy_icon_url": "https://images-ext-2.discordapp.net/external/YcCgh239WtAHT8lvLLbv3TDYi_7y_nug2RoVeL36fQU/%3Fu%3Dhttps%253A%252F%252Fwww.meteo.be%252Fmeteo%252Fdownload%252Ffr%252F196752%252Fimage%252Fgertgoesaert_29122006_glenelg_zuid-australi__2.jpg%26f%3D1%26nofb%3D1/https/external-content.duckduckgo.com/iu/"
},
"fields": [
{
"name": "Field 1",
"value": "Not inline",
"inline": false
},
{
"name": "Field 2",
"value": "Still not inline",
"inline": false
},
{
"name": "Field 3",
"value": "Okay this one is inline",
"inline": true
}
],
"color": 11492902,
"timestamp": "2020-03-07T21:09:13.380000+00:00",
"type": "rich",
"description": ":D",
"url": "https://google.com/",
"title": "I like pizza"
}
]
},
{
"id": "1",
"author": "337481187419226113",
"time": 1583651353649,
"content": "```py\n>>> from random import randint\n... from datetime import datetime\n... await channel.send(embed=discord.Embed(color=random.randint(0, 0xFFFFFF), title=\"I like pizza\", description=\":D\", url=\"https://google.com/\", timestamp=datetime.now()).set_footer(text=\"This is the footer\", icon_url=\"https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.purposegames.com%2Fimages%2Fgames%2Fbackground%2F355%2F355380.png&f=1&nofb=1\").set_image(url=\"https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fi.ytimg.com%2Fvi%2FxWYSzqDvTmQ%2Fhqdefault.jpg&f=1&nofb=1\").set_thumbnail(url=\"https://external-content.duckduckgo.com/iu/?u=http%3A%2F%2Fgetwallpapers.com%2Fwallpaper%2Ffull%2F6%2F3%2F7%2F17853.jpg&f=1&nofb=1\").set_author(name=\"This is the author\", url=\"https://discordapp.com/\", icon_url=\"https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.meteo.be%2Fmeteo%2Fdownload%2Ffr%2F196752%2Fimage%2Fgertgoesaert_29122006_glenelg_zuid-australi__2.jpg&f=1&nofb=1\").add_field(name=\"Field 1\", value=\"Not inline\", inline=False).add_field(name=\"Field 2\", value=\"Still not inline\", inline=False).add_field(name=\"Field 3\", value=\"Okay this one is inline\"))\n... \n\n\nTime to execute: 177.601ms```"
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583651467343,
"attachments": [
{
"id": 686033227827249157,
"filename": "xelA_settings.json",
"size": 3763,
"height": null,
"width": null,
"url": "https://cdn.discordapp.com/attachments/686027141946671186/686033227827249157/xelA_settings.json",
"proxy_url": "https://media.discordapp.net/attachments/686027141946671186/686033227827249157/xelA_settings.json"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583651524708,
"attachments": [
{
"id": 686033467573927966,
"filename": "Naila.png",
"size": 2411472,
"height": 4464,
"width": 2640,
"url": "https://cdn.discordapp.com/attachments/686027141946671186/686033467573927966/Naila.png",
"proxy_url": "https://media.discordapp.net/attachments/686027141946671186/686033467573927966/Naila.png"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583651531191,
"content": "https://cdn.discordapp.com/attachments/686027141946671186/686033467573927966/Naila.png",
"embeds": [
{
"thumbnail": {
"url": "https://cdn.discordapp.com/attachments/686027141946671186/686033467573927966/Naila.png",
"proxy_url": "https://media.discordapp.net/attachments/686027141946671186/686033467573927966/Naila.png",
"width": 2640,
"height": 4464
},
"type": "image",
"url": "https://cdn.discordapp.com/attachments/686027141946671186/686033467573927966/Naila.png"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583651570256,
"attachments": [
{
"id": 686033658985185308,
"filename": "iu.png",
"size": 167870,
"height": 248,
"width": 480,
"url": "https://cdn.discordapp.com/attachments/686027141946671186/686033658985185308/iu.png",
"proxy_url": "https://media.discordapp.net/attachments/686027141946671186/686033658985185308/iu.png"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583651611768,
"content": "https://tenor.com/view/illya-blink-anime-eyes-cute-gif-16059710",
"embeds": [
{
"thumbnail": {
"url": "https://media.tenor.co/images/8b1afd9e853b9c5a7af6fbb0f8b661ce/tenor.png",
"proxy_url": "https://images-ext-2.discordapp.net/external/jXg7OeyDcV_YDkrCpXNqNSpfOtWhY3UfXWzQiWZZrsA/https/media.tenor.co/images/8b1afd9e853b9c5a7af6fbb0f8b661ce/tenor.png",
"width": 640,
"height": 360
},
"video": {
"url": "https://media.tenor.co/videos/dfb2eb33b95df0c579bc966cb664aaec/mp4",
"width": 640,
"height": 360
},
"provider": {
"name": "Tenor",
"url": "https://tenor.co"
},
"type": "gifv",
"url": "https://tenor.com/view/illya-blink-anime-eyes-cute-gif-16059710"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583651646667,
"content": "<:denArcticFox:637121071962783754>\ud83d\ude02\u2764\ufe0f<:denDafuck:638581806471446569><:eyessquint:521498616783962123>\ud83c\udde89\ufe0f\u20e3<:Pog:459080170100228096>"
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583651766661,
"content": "<:awoo1:331095654678003722><:awoo2:331095654439059468><:awoo3:331095654611025921><:awoo4:331095655130857482><:awoo5:331095655068073985>\n<:awoo6:331095655080656899><:awoo7:331095655407812608><:awoo8:331095657270214656><:awoo9:331095657102180354><:awoo10:331095656607383552>\n<:awoo11:331095656368439296><:awoo12:331095657639051265><:awoo13:331095657853222912><:awoo14:331095657714548736><:awoo15:331095656297136130>\n<:awoo16:331095656422965248><:awoo17:331095657232465920><:awoo18:331095656921956362><:awoo19:331095657882320896><:awoo20:331095657500770305>\n<:awoo21:331095656854847489><:awoo22:331095657655959552><:awoo23:331095657311895553><:awoo24:331095657181872129><:awoo25:331095657102180352>"
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583651772258,
"content": "Those are emojis btw"
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583651852254,
"content": "discord. gg/fox discord. gg/discord-feedback"
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583651903319,
"content": "<@&686034948440064070> <@!173237945149423619> <@&645429085656580127> <#645102034579750922>"
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583673485361,
"content": "> This is a quote"
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583673497315,
"content": "> lots\n> of\n> quotes"
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583673521320,
"content": "n!!archive 100"
},
{
"id": "1",
"author": "610443119225471007",
"time": 1583673523550,
"attachments": [
{
"id": 686140837285199892,
"filename": "data.json",
"size": 22318,
"height": null,
"width": null,
"url": "https://cdn.discordapp.com/attachments/686027141946671186/686140837285199892/data.json",
"proxy_url": "https://media.discordapp.net/attachments/686027141946671186/686140837285199892/data.json"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583673585521,
"content": "too much tabbing"
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583673588834,
"content": "n!!archive 100"
},
{
"id": "1",
"author": "610443119225471007",
"time": 1583673590802,
"attachments": [
{
"id": 686141119293292584,
"filename": "data.json",
"size": 20074,
"height": null,
"width": null,
"url": "https://cdn.discordapp.com/attachments/686027141946671186/686141119293292584/data.json",
"proxy_url": "https://media.discordapp.net/attachments/686027141946671186/686141119293292584/data.json"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583674090609,
"content": "So since the last one loaded as a png have an uploaded gif",
"attachments": [
{
"id": 686143215606431808,
"filename": "dance.gif",
"size": 1657487,
"height": 270,
"width": 480,
"url": "https://cdn.discordapp.com/attachments/686027141946671186/686143215606431808/dance.gif",
"proxy_url": "https://media.discordapp.net/attachments/686027141946671186/686143215606431808/dance.gif"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583674098301,
"content": "n!!archive 100"
},
{
"id": "1",
"author": "610443119225471007",
"time": 1583674099651,
"attachments": [
{
"id": 686143254000959530,
"filename": "data.json",
"size": 21165,
"height": null,
"width": null,
"url": "https://cdn.discordapp.com/attachments/686027141946671186/686143254000959530/data.json",
"proxy_url": "https://media.discordapp.net/attachments/686027141946671186/686143254000959530/data.json"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583674619343,
"content": "https://twitter.com/SpaceX/status/1236172031919448067?s=20",
"embeds": [
{
"footer": {
"text": "Twitter",
"icon_url": "https://abs.twimg.com/icons/apple-touch-icon-192x192.png",
"proxy_icon_url": "https://images-ext-1.discordapp.net/external/bXJWV2Y_F3XSra_kEqIYXAAsI3m1meckfLhYuWzxIfI/https/abs.twimg.com/icons/apple-touch-icon-192x192.png"
},
"image": {
"url": "https://pbs.twimg.com/media/ESfDyyvUMAALqKA.jpg:large",
"proxy_url": "https://images-ext-2.discordapp.net/external/Sr4lbVDZzceMRo1E9f6-q5hpypkr7ksiOyUivMAJ6_4/https/pbs.twimg.com/media/ESfDyyvUMAALqKA.jpg%3Alarge",
"width": 2048,
"height": 1365
},
"id": "1",
"author": {
"name": "SpaceX (@SpaceX)",
"url": "https://twitter.com/SpaceX",
"icon_url": "https://pbs.twimg.com/profile_images/1082744382585856001/rH_k3PtQ_bigger.jpg",
"proxy_icon_url": "https://images-ext-2.discordapp.net/external/YWj4_0iHgQjUu-YFui4-4oQj5PKkm5D5zuSYlajgnNg/https/pbs.twimg.com/profile_images/1082744382585856001/rH_k3PtQ_bigger.jpg"
},
"fields": [
{
"name": "Retweets",
"value": "2582",
"inline": true
},
{
"name": "Likes",
"value": "17395",
"inline": true
}
],
"color": 1942002,
"type": "rich",
"description": "Falcon 9 launches the final mission of the first version of Dragon",
"url": "https://twitter.com/SpaceX/status/1236172031919448067?s=20"
},
{
"image": {
"url": "https://pbs.twimg.com/media/ESfDyywUcAASwpl.jpg:large",
"proxy_url": "https://images-ext-2.discordapp.net/external/Eev3nZHn0gFQmoV_BcoIaCTokqoOXSPIDjT-e4Tt7pY/https/pbs.twimg.com/media/ESfDyywUcAASwpl.jpg%3Alarge",
"width": 2048,
"height": 1365
},
"type": "rich",
"url": "https://twitter.com/SpaceX/status/1236172031919448067?s=20"
},
{
"image": {
"url": "https://pbs.twimg.com/media/ESfD0T4VAAEpRIe.jpg:large",
"proxy_url": "https://images-ext-1.discordapp.net/external/N9fvJXQA0DeBBITbLyHr3TiTUrP3F7UpQiA6Xey13sE/https/pbs.twimg.com/media/ESfD0T4VAAEpRIe.jpg%3Alarge",
"width": 2048,
"height": 1365
},
"type": "rich",
"url": "https://twitter.com/SpaceX/status/1236172031919448067?s=20"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583674629651,
"content": "n!!archive 100"
},
{
"id": "1",
"author": "610443119225471007",
"time": 1583674630978,
"attachments": [
{
"id": 686145482271358984,
"filename": "data.json",
"size": 24442,
"height": null,
"width": null,
"url": "https://cdn.discordapp.com/attachments/686027141946671186/686145482271358984/data.json",
"proxy_url": "https://media.discordapp.net/attachments/686027141946671186/686145482271358984/data.json"
}
]
},
{
"id": "1",
"author": "173237945149423619",
"time": 1583687671807,
"content": "n!!archive 100"
}
],
"channel_name": "test-archive"
}