mirror of
https://github.com/kirameki-cafe/Yumi.git
synced 2026-09-13 18:59:19 +00:00
Merge pull request #3 from YuzuZensai/djs14
Update to discord.js v14, Support Voice Text Channel
This commit is contained in:
@@ -7,6 +7,11 @@ DATABASE_URL=postgresql://user:password@host:port/dbName?schema=public
|
|||||||
DISCORD_TOKEN=SuperSecretDiscordToken
|
DISCORD_TOKEN=SuperSecretDiscordToken
|
||||||
DEVELOPER_IDS=DEV1_ID,DEV2_ID
|
DEVELOPER_IDS=DEV1_ID,DEV2_ID
|
||||||
PRIVATE_BOT=true
|
PRIVATE_BOT=true
|
||||||
|
SUPPORT_URL=https://example.com/support
|
||||||
|
|
||||||
OSU_API_KEY=SuperSecretosu!Key
|
OSU_API_KEY=SuperSecretosu!Key
|
||||||
YOUTUBE_COOKIE_BASE64=SuperSecretCookie_EncodeItInBase64_AndThen_RemoveTheLastEqualToo
|
YOUTUBE_COOKIE_BASE64=SuperSecretCookie_EncodeItInBase64_AndThen_RemoveTheLastEqualToo
|
||||||
|
SPOTIFY_CLIENT_ID=SpotfyClientID
|
||||||
|
SPOTIFY_CLIENT_SECRET=SpotfyClientSecret
|
||||||
|
SPOTIFY_REFRESH_TOKEN=SpotfyRefreshToken
|
||||||
|
SPOTIFY_CLIENT_MARKET=CountryCodeHere
|
||||||
|
|||||||
+2
-2
@@ -6,7 +6,7 @@ RUN DEBIAN_FRONTEND=noninteractive
|
|||||||
|
|
||||||
RUN apt-get update -y
|
RUN apt-get update -y
|
||||||
RUN apt-get -y install curl gnupg git python2 make g++ iputils-ping ffmpeg
|
RUN apt-get -y install curl gnupg git python2 make g++ iputils-ping ffmpeg
|
||||||
RUN curl -sL https://deb.nodesource.com/setup_17.x | bash -
|
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
|
||||||
RUN apt-get -y install nodejs
|
RUN apt-get -y install nodejs
|
||||||
RUN npm i -g yarn
|
RUN npm i -g yarn
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ WORKDIR /home/node/app
|
|||||||
|
|
||||||
RUN apt-get update -y
|
RUN apt-get update -y
|
||||||
RUN apt-get -y install curl gnupg git python2 make g++ iputils-ping ffmpeg
|
RUN apt-get -y install curl gnupg git python2 make g++ iputils-ping ffmpeg
|
||||||
RUN curl -sL https://deb.nodesource.com/setup_17.x | bash -
|
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
|
||||||
RUN apt-get -y install nodejs
|
RUN apt-get -y install nodejs
|
||||||
RUN npm i -g yarn
|
RUN npm i -g yarn
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,14 @@ Take a look inside [.env.example](https://github.com/YuzuZensai/Yumi/blob/main/.
|
|||||||
- ``DISCORD_TOKEN`` Your discord bot token
|
- ``DISCORD_TOKEN`` Your discord bot token
|
||||||
- ``DEVELOPER_IDS`` List of Discord Snowflake User ID that can access developer only modules, separated by ``,``
|
- ``DEVELOPER_IDS`` List of Discord Snowflake User ID that can access developer only modules, separated by ``,``
|
||||||
- ``PRIVATE_BOT`` Should the bot invite be public? ``true`` or ``false``
|
- ``PRIVATE_BOT`` Should the bot invite be public? ``true`` or ``false``
|
||||||
|
- ``SUPPORT_URL`` (Optional) URL to your support server (If not set, support module will show not available message)
|
||||||
- ``OSU_API_KEY`` [osu! API v1 key](https://github.com/ppy/osu-api/wiki)
|
- ``OSU_API_KEY`` [osu! API v1 key](https://github.com/ppy/osu-api/wiki)
|
||||||
- ``YOUTUBE_COOKIE_BASE64`` YouTube cookies encoded in base64 [How to get cookies?](https://github.com/play-dl/play-dl/tree/main/instructions#youtube-cookies=) *
|
- ``YOUTUBE_COOKIE_BASE64`` YouTube cookies encoded in base64 [How to get cookies?](https://github.com/play-dl/play-dl/tree/main/instructions#youtube-cookies=) *
|
||||||
|
- ``SPOTIFY_CLIENT_ID`` Spotify client ID
|
||||||
|
- ``SPOTIFY_CLIENT_SECRET`` Spotify client secret
|
||||||
|
- ``SPOTIFY_REFRESH_TOKEN`` Spotify refresh token **
|
||||||
|
- ``SPOTIFY_CLIENT_MARKET`` Spotify market country code
|
||||||
|
|
||||||
\* Encode the cookies from the request headers base64 and put it in here instead of creating new file with ``play.authorization();`` code
|
\* Encode the cookies from the request headers base64 and put it in here instead of creating new file with ``play.authorization();`` code
|
||||||
|
|
||||||
|
\*\* Get refresh token from ``https://accounts.spotify.com/en/authorize?client_id=<client id>&response_type=code&redirect_uri=<redirect uri>``
|
||||||
|
|||||||
+29
-6
@@ -1,8 +1,10 @@
|
|||||||
{
|
{
|
||||||
"common": {
|
"common": {
|
||||||
"available_args": "Available arguments",
|
"available_args": "Available arguments",
|
||||||
"no_permissions": "Access denied (O_O;)",
|
"member_no_permissions": "Access denied (O_O;)",
|
||||||
"no_permissions_description": "You need ``{{PERMISSIONS}}`` permission on this guild",
|
"member_no_permissions_description": "You need ``{{PERMISSIONS}}`` permissions on this guild",
|
||||||
|
"bot_no_permissions": "I don't have permission (O_O;)",
|
||||||
|
"bot_no_permissions_description": "I need ``{{PERMISSIONS}}`` permissions",
|
||||||
"processing": "Please wait a moment~",
|
"processing": "Please wait a moment~",
|
||||||
"processing_description": "Getting it done right now! (งᓀ‸ᓂ)ง"
|
"processing_description": "Getting it done right now! (งᓀ‸ᓂ)ง"
|
||||||
},
|
},
|
||||||
@@ -35,7 +37,9 @@
|
|||||||
"streaming_x": "Streaming {{NAME}}",
|
"streaming_x": "Streaming {{NAME}}",
|
||||||
"listening_x": "Listening to {{NAME}}",
|
"listening_x": "Listening to {{NAME}}",
|
||||||
"watching_x": "Watching {{NAME}}",
|
"watching_x": "Watching {{NAME}}",
|
||||||
"competing_x": "Competing {{NAME}}"
|
"competing_x": "Competing {{NAME}}",
|
||||||
|
"since": "Since {{{TIME}}}",
|
||||||
|
"end": "Ending {{{TIME}}}"
|
||||||
},
|
},
|
||||||
"say": {
|
"say": {
|
||||||
"title": "Say",
|
"title": "Say",
|
||||||
@@ -106,13 +110,19 @@
|
|||||||
"queue_added_songs_description": "Added {{COUNT}} songs to the queue",
|
"queue_added_songs_description": "Added {{COUNT}} songs to the queue",
|
||||||
"error": "Error while looking up the song"
|
"error": "Error while looking up the song"
|
||||||
},
|
},
|
||||||
|
"musicplayer_playmy": {
|
||||||
|
"not_detected": "You don't seem to be listening to any music currently according to your activity"
|
||||||
|
},
|
||||||
"musicplayer_queue": {
|
"musicplayer_queue": {
|
||||||
"title": "Queue",
|
"title": "Queue",
|
||||||
|
"valid_args": "``Clear`` ``Shuffle``",
|
||||||
"empty": "The queue is empty! (っ˘ω˘ς )",
|
"empty": "The queue is empty! (っ˘ω˘ς )",
|
||||||
"now_playing": "Now playing",
|
"now_playing": "Now playing",
|
||||||
"upcoming_song": "Upcoming song",
|
"upcoming_song": "Upcoming song",
|
||||||
"looping_current": "(Looping current)",
|
"looping_current": "(Looping current)",
|
||||||
"song_x_in_queue": "There are {{COUNT}} song in the queue!"
|
"song_x_in_queue": "There are {{COUNT}} song in the queue!",
|
||||||
|
"cleared": "Queue cleared~ (。•ˇ‸ˇ•。)",
|
||||||
|
"shuffled": "Queue shuffled"
|
||||||
},
|
},
|
||||||
"musicplayer_search": {
|
"musicplayer_search": {
|
||||||
"title": "Search",
|
"title": "Search",
|
||||||
@@ -127,8 +137,8 @@
|
|||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"title": "Settings",
|
"title": "Settings",
|
||||||
"description": "Change how {{BOT_NAME}} behave on **{{GUILD_NAME}}**",
|
"description": "Change how {{BOT_NAME}} behave on **{{{GUILD_NAME}}}**",
|
||||||
"valid_args": "``Prefix`` ``EnableServiceAnnouncement`` ``ServiceAnnouncementChannel``"
|
"valid_args": "``Prefix`` ``Language`` ``EnableServiceAnnouncement`` ``ServiceAnnouncementChannel``"
|
||||||
},
|
},
|
||||||
"settings_prefix": {
|
"settings_prefix": {
|
||||||
"info": "Current prefix is {{{PREFIX}}}",
|
"info": "Current prefix is {{{PREFIX}}}",
|
||||||
@@ -140,10 +150,23 @@
|
|||||||
"prefix_updated": "Prefix updated",
|
"prefix_updated": "Prefix updated",
|
||||||
"prefix_updated_description": "From now onwards, I shall be called by using ``{{PREFIX}}``"
|
"prefix_updated_description": "From now onwards, I shall be called by using ``{{PREFIX}}``"
|
||||||
},
|
},
|
||||||
|
"settings_language": {
|
||||||
|
"info": "Current language is {{LANGUAGE}}",
|
||||||
|
"info_description": "Provide a new language to change\n**Available languages**: ``{{LANGUAGES}}``",
|
||||||
|
"language_invalid": "Invalid language",
|
||||||
|
"language_invalid_description": "The language code is invalid or not supported yet",
|
||||||
|
"language_updated": "Language updated",
|
||||||
|
"language_updated_description": "I will be using {{LANGUAGE}} from now on"
|
||||||
|
},
|
||||||
"ping": {
|
"ping": {
|
||||||
"title": "Network performance",
|
"title": "Network performance",
|
||||||
"title_processing": "Measuring network performance ( ◕▿◕ )",
|
"title_processing": "Measuring network performance ( ◕▿◕ )",
|
||||||
"running_on": "Running on {{HOST}}",
|
"running_on": "Running on {{HOST}}",
|
||||||
"development_environment": "Development Environment"
|
"development_environment": "Development Environment"
|
||||||
|
},
|
||||||
|
"support": {
|
||||||
|
"title": "Support",
|
||||||
|
"info": "[Join {{BOT_NAME}}'s support server]({{{LINK}}})",
|
||||||
|
"not_available": "{{BOT_NAME}}'s support server is currently unavailable"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+29
-6
@@ -1,8 +1,10 @@
|
|||||||
{
|
{
|
||||||
"common": {
|
"common": {
|
||||||
"available_args": "Available arguments",
|
"available_args": "Available arguments",
|
||||||
"no_permissions": "許可していない (O_O;)",
|
"member_no_permissions": "許可していない (O_O;)",
|
||||||
"no_permissions_description": "このギルドでは ``{{PERMISSIONS}}`` の許可が必要です!",
|
"member_no_permissions_description": "このギルドでは ``{{PERMISSIONS}}`` の許可が必要です!",
|
||||||
|
"bot_no_permissions": "許可がない (O_O;)",
|
||||||
|
"bot_no_permissions_description": "そのためには、あたしの``{{PERMISSIONS}}``の権限が必要です",
|
||||||
"processing": "アクションの実行",
|
"processing": "アクションの実行",
|
||||||
"processing_description": "今これを成し遂げています (งᓀ‸ᓂ)ง"
|
"processing_description": "今これを成し遂げています (งᓀ‸ᓂ)ง"
|
||||||
},
|
},
|
||||||
@@ -35,7 +37,9 @@
|
|||||||
"streaming_x": "{{NAME}}をストリーミング中",
|
"streaming_x": "{{NAME}}をストリーミング中",
|
||||||
"listening_x": "{{NAME}}を再生中",
|
"listening_x": "{{NAME}}を再生中",
|
||||||
"watching_x": "{{NAME}}鑑賞中",
|
"watching_x": "{{NAME}}鑑賞中",
|
||||||
"competing_x": "{{NAME}}に参戦中です"
|
"competing_x": "{{NAME}}に参戦中です",
|
||||||
|
"since": "{{{TIME}}}から",
|
||||||
|
"end": "{{{TIME}}}で終了"
|
||||||
},
|
},
|
||||||
"say": {
|
"say": {
|
||||||
"title": "言うこと",
|
"title": "言うこと",
|
||||||
@@ -106,13 +110,19 @@
|
|||||||
"queue_added_songs_description": "キューに{{COUNT}}曲を追加",
|
"queue_added_songs_description": "キューに{{COUNT}}曲を追加",
|
||||||
"error": "曲の検索中にエラーが発生"
|
"error": "曲の検索中にエラーが発生"
|
||||||
},
|
},
|
||||||
|
"musicplayer_playmy": {
|
||||||
|
"not_detected": "あなたの活動状況を見ると、現在、音楽を聴いていないようですね"
|
||||||
|
},
|
||||||
"musicplayer_queue": {
|
"musicplayer_queue": {
|
||||||
"title": "キュー",
|
"title": "キュー",
|
||||||
|
"valid_args": "``Clear`` ``Shuffle``",
|
||||||
"empty": "キューは空です! (っ˘ω˘ς )",
|
"empty": "キューは空です! (っ˘ω˘ς )",
|
||||||
"now_playing": "再生中",
|
"now_playing": "再生中",
|
||||||
"upcoming_song": "次の曲",
|
"upcoming_song": "次の曲",
|
||||||
"looping_current": "(この曲の繰り返し)",
|
"looping_current": "(この曲の繰り返し)",
|
||||||
"song_x_in_queue": "{{COUNT}}曲も並んでいますよ。"
|
"song_x_in_queue": "{{COUNT}}曲も並んでいますよ。",
|
||||||
|
"cleared": "キューがクリアされました (。•ˇ‸ˇ•。)",
|
||||||
|
"shuffled": "キューがシャッフルされました"
|
||||||
},
|
},
|
||||||
"musicplayer_search": {
|
"musicplayer_search": {
|
||||||
"title": "検索",
|
"title": "検索",
|
||||||
@@ -127,8 +137,8 @@
|
|||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"title": "設定",
|
"title": "設定",
|
||||||
"description": "**{{GUILD_NAME}}**サーバでの{{BOT_NAME}}の動作変更",
|
"description": "**{{{GUILD_NAME}}}**サーバでの{{BOT_NAME}}の動作変更",
|
||||||
"valid_args": "``Prefix`` ``EnableServiceAnnouncement`` ``ServiceAnnouncementChannel``"
|
"valid_args": "``Prefix`` ``Language`` ``EnableServiceAnnouncement`` ``ServiceAnnouncementChannel``"
|
||||||
},
|
},
|
||||||
"settings_prefix": {
|
"settings_prefix": {
|
||||||
"info": "現在の接頭辞は「{{{PREFIX}}}」です。",
|
"info": "現在の接頭辞は「{{{PREFIX}}}」です。",
|
||||||
@@ -140,10 +150,23 @@
|
|||||||
"prefix_updated": "プレフィックスを更新",
|
"prefix_updated": "プレフィックスを更新",
|
||||||
"prefix_updated_description": "これ以降、私は 「``{{PREFIX}}``」 を使って呼び出されることになります。"
|
"prefix_updated_description": "これ以降、私は 「``{{PREFIX}}``」 を使って呼び出されることになります。"
|
||||||
},
|
},
|
||||||
|
"settings_language": {
|
||||||
|
"info": "現在の言語は{{LANGUAGE}}です",
|
||||||
|
"info_description": "変更する新しい言語を提供する\n**利用可能な言語**: ``{{LANGUAGES}}``",
|
||||||
|
"language_invalid": "無効な言語",
|
||||||
|
"language_invalid_description": "言語コードが無効であるか、まだサポートされていません",
|
||||||
|
"language_updated": "言語が変更されました",
|
||||||
|
"language_updated_description": "これからは{{LANGUAGE}}を使います"
|
||||||
|
},
|
||||||
"ping": {
|
"ping": {
|
||||||
"title": "ネットワークパフォーマンス",
|
"title": "ネットワークパフォーマンス",
|
||||||
"title_processing": "ネットワーク性能の測定 ( ◕▿◕ )",
|
"title_processing": "ネットワーク性能の測定 ( ◕▿◕ )",
|
||||||
"running_on": "{{HOST}}で実行中",
|
"running_on": "{{HOST}}で実行中",
|
||||||
"development_environment": "開発環境"
|
"development_environment": "開発環境"
|
||||||
|
},
|
||||||
|
"support": {
|
||||||
|
"title": "サポート",
|
||||||
|
"info": "[{{BOT_NAME}}のサポートサーバーに参加する]({{{LINK}}})",
|
||||||
|
"not_available": "{{BOT_NAME}}のサポートサーバーは現在利用できません"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+29
-6
@@ -1,8 +1,10 @@
|
|||||||
{
|
{
|
||||||
"common": {
|
"common": {
|
||||||
"available_args": "อาร์กิวเมนต์ ตัวเลือกที่ใช้ได้",
|
"available_args": "อาร์กิวเมนต์ ตัวเลือกที่ใช้ได้",
|
||||||
"no_permissions": "คุณไม่มีสิทธิ์เข้าถึง (O_O;)",
|
"member_no_permissions": "คุณไม่มีสิทธิ์เข้าถึง (O_O;)",
|
||||||
"no_permissions_description": "คุณต้องมีสิทธิ์เข้าถึง ``{{PERMISSIONS}}`` ในกิลด์นี้!",
|
"member_no_permissions_description": "คุณต้องมีสิทธิ์เข้าถึง ``{{PERMISSIONS}}`` ในกิลด์นี้!",
|
||||||
|
"bot_no_permissions": "ฉันไม่มีสิทธิ์เข้าถึง (O_O;)",
|
||||||
|
"bot_no_permissions_description": "ฉันต้องการสิทธิ์เข้าถึง ``{{PERMISSIONS}}``",
|
||||||
"processing": "รอแปปนึงน้า",
|
"processing": "รอแปปนึงน้า",
|
||||||
"processing_description": "ฉันกำลังดำเนินการให้อยู่ (งᓀ‸ᓂ)ง"
|
"processing_description": "ฉันกำลังดำเนินการให้อยู่ (งᓀ‸ᓂ)ง"
|
||||||
},
|
},
|
||||||
@@ -35,7 +37,9 @@
|
|||||||
"streaming_x": "กำลังสตรีม {{NAME}}",
|
"streaming_x": "กำลังสตรีม {{NAME}}",
|
||||||
"listening_x": "กำลังฟัง {{NAME}}",
|
"listening_x": "กำลังฟัง {{NAME}}",
|
||||||
"watching_x": "กำลังดู {{NAME}}",
|
"watching_x": "กำลังดู {{NAME}}",
|
||||||
"competing_x": "กำลังแข่งขัน {{NAME}}"
|
"competing_x": "กำลังแข่งขัน {{NAME}}",
|
||||||
|
"since": "ตั้งแต่ {{{TIME}}}",
|
||||||
|
"end": "สิ้นสุดใน {{{TIME}}}"
|
||||||
},
|
},
|
||||||
"say": {
|
"say": {
|
||||||
"title": "สั่งพูด",
|
"title": "สั่งพูด",
|
||||||
@@ -106,13 +110,19 @@
|
|||||||
"queue_added_songs_description": "เพิ่ม {{COUNT}} เพลงในคิว",
|
"queue_added_songs_description": "เพิ่ม {{COUNT}} เพลงในคิว",
|
||||||
"error": "เกิดข้อผิดพลาดขณะค้นหาเพลง"
|
"error": "เกิดข้อผิดพลาดขณะค้นหาเพลง"
|
||||||
},
|
},
|
||||||
|
"musicplayer_playmy": {
|
||||||
|
"not_detected": "เท่าที่ดูจากกิจกรรมของคุณ เหมือนว่าตอนนี้คุณไม่ได้เล่นเพลงอะไรอยู่นะ"
|
||||||
|
},
|
||||||
"musicplayer_queue": {
|
"musicplayer_queue": {
|
||||||
"title": "คิวเพลง",
|
"title": "คิวเพลง",
|
||||||
|
"valid_args": "``Clear`` ``Shuffle``",
|
||||||
"empty": "ตอนนี้คิวว่างนะ (っ˘ω˘ς )",
|
"empty": "ตอนนี้คิวว่างนะ (っ˘ω˘ς )",
|
||||||
"now_playing": "กำลังเล่น",
|
"now_playing": "กำลังเล่น",
|
||||||
"upcoming_song": "เพลงต่อไป",
|
"upcoming_song": "เพลงต่อไป",
|
||||||
"looping_current": "(กำลังวนซ้ำเพลงนี้)",
|
"looping_current": "(กำลังวนซ้ำเพลงนี้)",
|
||||||
"song_x_in_queue": "ตอนนี้มี {{COUNT}} เพลงอยู่ในคิว!"
|
"song_x_in_queue": "ตอนนี้มี {{COUNT}} เพลงอยู่ในคิว!",
|
||||||
|
"cleared": "เคลียร์คิวเรียบร้อยละ~ (。•ˇ‸ˇ•。)",
|
||||||
|
"shuffled": "สุ่มคิวเรียบร้อยละ"
|
||||||
},
|
},
|
||||||
"musicplayer_search": {
|
"musicplayer_search": {
|
||||||
"title": "ค้นหา",
|
"title": "ค้นหา",
|
||||||
@@ -127,8 +137,8 @@
|
|||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"title": "การตั้งค่า",
|
"title": "การตั้งค่า",
|
||||||
"description": "เปลี่ยนพฤติกรรมของ {{BOT_NAME}} บน **{{GUILD_NAME}}**",
|
"description": "เปลี่ยนพฤติกรรมของ {{BOT_NAME}} บน **{{{GUILD_NAME}}}**",
|
||||||
"valid_args": "``Prefix`` ``EnableServiceAnnouncement`` ``ServiceAnnouncementChannel``"
|
"valid_args": "``Prefix`` ``Language`` ``EnableServiceAnnouncement`` ``ServiceAnnouncementChannel``"
|
||||||
},
|
},
|
||||||
"settings_prefix": {
|
"settings_prefix": {
|
||||||
"info": "คำนำหน้าปัจจุบันคือ {{{PREFIX}}}",
|
"info": "คำนำหน้าปัจจุบันคือ {{{PREFIX}}}",
|
||||||
@@ -140,10 +150,23 @@
|
|||||||
"prefix_updated": "อัปเดตคำนำหน้าแล้ว",
|
"prefix_updated": "อัปเดตคำนำหน้าแล้ว",
|
||||||
"prefix_updated_description": "จากนี้ไป คุณสามารถเรียกฉันโดยใช้ ``{{PREFIX}}`` นะ"
|
"prefix_updated_description": "จากนี้ไป คุณสามารถเรียกฉันโดยใช้ ``{{PREFIX}}`` นะ"
|
||||||
},
|
},
|
||||||
|
"settings_language": {
|
||||||
|
"info": "ภาษาปัจจุบันตอนนี้คือ {{LANGUAGE}}",
|
||||||
|
"info_description": "ระบุภาษาใหม่เพื่อเปลี่ยน\n**ภาษาที่ใช้ได้**: ``{{LANGUAGES}}``",
|
||||||
|
"language_invalid": "ภาษาไม่ถูกต้อง",
|
||||||
|
"language_invalid_description": "รหัสภาษาไม่ถูกต้องหรือยังไม่รองรับ",
|
||||||
|
"language_updated": "เปลี่ยนภาษาเรียบร้อย",
|
||||||
|
"language_updated_description": "ตั้งแต่นี้ไปฉันจะใช้ภาษา {{LANGUAGE}}"
|
||||||
|
},
|
||||||
"ping": {
|
"ping": {
|
||||||
"title": "ประสิทธิภาพของเครือข่าย",
|
"title": "ประสิทธิภาพของเครือข่าย",
|
||||||
"title_processing": "กำลังวัดประสิทธิภาพของเครือข่าย ( ◕▿◕ )",
|
"title_processing": "กำลังวัดประสิทธิภาพของเครือข่าย ( ◕▿◕ )",
|
||||||
"running_on": "ทำงานอยู่บน {{HOST}}",
|
"running_on": "ทำงานอยู่บน {{HOST}}",
|
||||||
"development_environment": "โหมดกำลังพัฒนา"
|
"development_environment": "โหมดกำลังพัฒนา"
|
||||||
|
},
|
||||||
|
"support": {
|
||||||
|
"title": "ติดต่อฝ่ายสนับสนุน",
|
||||||
|
"info": "[เข้าร่วมเซิร์ฟเวอร์สนับสนุนของ {{BOT_NAME}}]({{{LINK}}})",
|
||||||
|
"not_available": "เซิร์ฟเวอร์สนับสนุนของ {{BOT_NAME}} ไม่พร้อมใช้งานในขณะนี้"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+8
-9
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@discordjs/builders": "^0.15.0",
|
"@discordjs/opus": "^0.8.0",
|
||||||
"@discordjs/opus": "^0.7.0",
|
|
||||||
"@discordjs/rest": "^0.5.0",
|
"@discordjs/rest": "^0.5.0",
|
||||||
"@discordjs/voice": "^0.10.0",
|
"@discordjs/voice": "^0.10.0",
|
||||||
"@types/color-thief-node": "^1.0.1",
|
"@types/color-thief-node": "^1.0.1",
|
||||||
@@ -11,8 +10,8 @@
|
|||||||
"color-thief-node": "^1.0.4",
|
"color-thief-node": "^1.0.4",
|
||||||
"country-code-emoji": "^2.3.0",
|
"country-code-emoji": "^2.3.0",
|
||||||
"country-code-lookup": "^0.0.20",
|
"country-code-lookup": "^0.0.20",
|
||||||
"discord-api-types": "^0.35.0",
|
"discord-api-types": "^0.36.2",
|
||||||
"discord.js": "^13.8.1",
|
"discord.js": "14.0.1",
|
||||||
"dotenv": "^16.0.1",
|
"dotenv": "^16.0.1",
|
||||||
"i18n": "^0.15.0",
|
"i18n": "^0.15.0",
|
||||||
"libsodium-wrappers": "^0.7.10",
|
"libsodium-wrappers": "^0.7.10",
|
||||||
@@ -28,14 +27,14 @@
|
|||||||
"zlib-sync": "^0.1.7"
|
"zlib-sync": "^0.1.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@prisma/client": "^3.15.2",
|
"@prisma/client": "^4.0.0",
|
||||||
"@types/bluebird": "^3.5.36",
|
"@types/bluebird": "^3.5.36",
|
||||||
"@types/i18n": "^0.13.3",
|
"@types/i18n": "^0.13.4",
|
||||||
"@types/node": "^18.0.0",
|
"@types/node": "^18.0.4",
|
||||||
"@types/ping": "^0.4.1",
|
"@types/ping": "^0.4.1",
|
||||||
"@types/validator": "^13.7.3",
|
"@types/validator": "^13.7.4",
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
"prisma": "^3.15.2",
|
"prisma": "^4.0.0",
|
||||||
"ts-node-dev": "^2.0.0"
|
"ts-node-dev": "^2.0.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
import { Guild } from 'discord.js';
|
import { ActivityType, Guild } from 'discord.js';
|
||||||
|
|
||||||
import DiscordModule from '../utils/DiscordModule';
|
import DiscordModule from '../utils/DiscordModule';
|
||||||
import DiscordProvider from '../providers/Discord';
|
import DiscordProvider from '../providers/Discord';
|
||||||
@@ -48,7 +48,7 @@ export default class Core extends DiscordModule {
|
|||||||
|
|
||||||
private setActivity() {
|
private setActivity() {
|
||||||
DiscordProvider.client.user!.setActivity('for your heart 💖', {
|
DiscordProvider.client.user!.setActivity('for your heart 💖', {
|
||||||
type: 'COMPETING'
|
type: ActivityType.Competing
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { User as PrismaUser, Guild as PrismaGuild } from '@prisma/client';
|
import { User as PrismaUser, Guild as PrismaGuild } from '@prisma/client';
|
||||||
import {
|
import {
|
||||||
Message,
|
Message,
|
||||||
Interaction,
|
ActionRowBuilder,
|
||||||
CommandInteraction,
|
CommandInteraction,
|
||||||
MessageActionRow,
|
ButtonInteraction,
|
||||||
MessageButton,
|
ButtonBuilder,
|
||||||
ButtonInteraction
|
ButtonStyle
|
||||||
} from 'discord.js';
|
} from 'discord.js';
|
||||||
|
|
||||||
import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule';
|
import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule';
|
||||||
@@ -162,15 +162,15 @@ export default class Debug extends DiscordModule {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
invalidInteraction: async (data: HybridInteractionMessage) => {
|
invalidInteraction: async (data: HybridInteractionMessage) => {
|
||||||
const row = new MessageActionRow().addComponents(
|
const row = new ActionRowBuilder<ButtonBuilder>().addComponents([
|
||||||
new MessageButton()
|
new ButtonBuilder()
|
||||||
.setEmoji('😥')
|
.setEmoji('😥')
|
||||||
.setLabel(
|
.setLabel(
|
||||||
' Make invalid interaction (Wait 7 seconds, check error in console or logs)'
|
' Make invalid interaction (Wait 7 seconds, check error in console or logs)'
|
||||||
)
|
)
|
||||||
.setCustomId('dev_make_invalid_interaction')
|
.setCustomId('dev_make_invalid_interaction')
|
||||||
.setStyle('PRIMARY')
|
.setStyle(ButtonStyle.Primary)
|
||||||
);
|
]);
|
||||||
await sendHybridInteractionMessageResponse(data, {
|
await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.INVALID_TEST(data)],
|
embeds: [EMBEDS.INVALID_TEST(data)],
|
||||||
components: [row]
|
components: [row]
|
||||||
@@ -187,7 +187,7 @@ export default class Debug extends DiscordModule {
|
|||||||
});
|
});
|
||||||
|
|
||||||
query = args[0].toLowerCase();
|
query = args[0].toLowerCase();
|
||||||
} else if (data.isSlashCommand()) {
|
} else if (data.isApplicationCommand()) {
|
||||||
query = args.getSubcommand();
|
query = args.getSubcommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Message, MessageEmbed, Interaction, CommandInteraction, TextChannel } from 'discord.js';
|
import { Message, EmbedBuilder, CommandInteraction, TextChannel, EmbedData } from 'discord.js';
|
||||||
import { Promise } from 'bluebird';
|
import { Promise } from 'bluebird';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
@@ -21,35 +21,37 @@ import DiscordProvider from '../../providers/Discord';
|
|||||||
import Prisma from '../../providers/Prisma';
|
import Prisma from '../../providers/Prisma';
|
||||||
import Users from '../../services/Users';
|
import Users from '../../services/Users';
|
||||||
|
|
||||||
|
const hexToDecimal = (hex: string) => parseInt(hex.replace('#', ''), 16);
|
||||||
|
|
||||||
const EMBEDS = {
|
const EMBEDS = {
|
||||||
ANNOUNCEMENT_INFO: (data: Message | Interaction) => {
|
ANNOUNCEMENT_INFO: (data: HybridInteractionMessage) => {
|
||||||
return makeInfoEmbed({
|
return makeInfoEmbed({
|
||||||
title: 'Service Announcement',
|
title: 'Service Announcement',
|
||||||
description: `This module contains management tool for announcement feed\n The announcement message is located in \`\`configs/ServiceAnnouncement.json\`\``,
|
description: `This module contains management tool for announcement feed\n The announcement message is located in \`\`configs/ServiceAnnouncement.json\`\``,
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: 'Available arguments',
|
name: 'Available arguments',
|
||||||
value: '``reload`` ``previewNews`` ``sendNews`` ``previewMaintenance`` ``sendMaintenance`` ``previewMessage`` ``sendMessage`` ``previewAlert`` ``sendAlert``'
|
value: '``Reload`` ``PreviewNews`` ``SendNews`` ``PreviewMaintenance`` ``SendMaintenance`` ``PreviewMessage`` ``SendMessage`` ``PreviewAlert`` ``SendAlert``'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
NOT_DEVELOPER: (data: Message | Interaction) => {
|
NOT_DEVELOPER: (data: HybridInteractionMessage) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'Developer only',
|
title: 'Developer only',
|
||||||
description: `This command is restricted to the developers only`,
|
description: `This command is restricted to the developers only`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
MAKE_PAYLOAD: (payload: any) => {
|
MAKE_PAYLOAD: (payload: EmbedData) => {
|
||||||
const user = DiscordProvider.client.user;
|
const user = DiscordProvider.client.user;
|
||||||
payload.footer = {
|
payload.footer = {
|
||||||
text: `${user?.username}`,
|
text: `${user?.username}`,
|
||||||
iconURL: `${user?.displayAvatarURL()}?size=4096`
|
iconURL: `${user?.displayAvatarURL()}?size=4096`
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!payload.timestamp) payload.timestamp = new Date();
|
if (!payload.timestamp) payload.timestamp = Date.now();
|
||||||
|
|
||||||
if (payload.thumbnail?.url === 'bot_avatar')
|
if (payload.thumbnail?.url === 'bot_avatar')
|
||||||
payload.thumbnail.url = `${user?.displayAvatarURL()}?size=4096`;
|
payload.thumbnail.url = `${user?.displayAvatarURL()}?size=4096`;
|
||||||
@@ -58,49 +60,52 @@ const EMBEDS = {
|
|||||||
payload.image.url = `${user?.displayAvatarURL()}?size=4096`;
|
payload.image.url = `${user?.displayAvatarURL()}?size=4096`;
|
||||||
|
|
||||||
if (payload.description)
|
if (payload.description)
|
||||||
payload.description = payload.description.replaceAll('{bot_username}', user?.username);
|
payload.description = payload.description.replaceAll('{bot_username}', user?.username!);
|
||||||
|
|
||||||
return new MessageEmbed(payload);
|
if (payload.color && isNaN(payload.color))
|
||||||
|
payload.color = hexToDecimal(payload.color.toString());
|
||||||
|
|
||||||
|
return new EmbedBuilder(payload);
|
||||||
},
|
},
|
||||||
RELOADED: (data: Message | Interaction) => {
|
RELOADED: (data: HybridInteractionMessage) => {
|
||||||
return makeSuccessEmbed({
|
return makeSuccessEmbed({
|
||||||
title: 'Service Announcement Configuration Reloaded',
|
title: 'Service Announcement Configuration Reloaded',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
RELOAD_ERROR: (data: Message | Interaction, error: string) => {
|
RELOAD_ERROR: (data: HybridInteractionMessage, error: string) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'Unable to reload Service Announcement Configuration',
|
title: 'Unable to reload Service Announcement Configuration',
|
||||||
description: `\`\`\`${error}\`\`\``,
|
description: `\`\`\`${error}\`\`\``,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
SENDING_SERVICE_ANNOUNCEMENT: (data: Message | Interaction) => {
|
SENDING_SERVICE_ANNOUNCEMENT: (data: HybridInteractionMessage) => {
|
||||||
return makeProcessingEmbed({
|
return makeProcessingEmbed({
|
||||||
title: 'Service Announcement',
|
title: 'Service Announcement',
|
||||||
description: `Broadcasting Service Announcement`,
|
description: `Broadcasting Service Announcement`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
SERVICE_ANNOUNCEMENT_SENT: (data: Message | Interaction) => {
|
SERVICE_ANNOUNCEMENT_SENT: (data: HybridInteractionMessage) => {
|
||||||
return makeSuccessEmbed({
|
return makeSuccessEmbed({
|
||||||
title: 'Service Announcement',
|
title: 'Service Announcement',
|
||||||
description: `Broadcasted Service Announcement`,
|
description: `Broadcasted Service Announcement`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
SERVICE_ANNOUNCEMENT_SENT_WITH_ERRORS: (data: Message | Interaction) => {
|
SERVICE_ANNOUNCEMENT_SENT_WITH_ERRORS: (data: HybridInteractionMessage) => {
|
||||||
return makeWarningEmbed({
|
return makeWarningEmbed({
|
||||||
title: 'Service Announcement',
|
title: 'Service Announcement',
|
||||||
description: `Broadcasted Service Announcement with errors, check console for more info`,
|
description: `Broadcasted Service Announcement with errors, check console for more info`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let Announcements = {
|
let Announcements = {
|
||||||
News: {
|
News: {
|
||||||
color: '#FAEDF0',
|
color: hexToDecimal('#FAEDF0'),
|
||||||
title: '📰 Newsletter',
|
title: '📰 Newsletter',
|
||||||
description: 'Some description here',
|
description: 'Some description here',
|
||||||
thumbnail: {
|
thumbnail: {
|
||||||
@@ -108,7 +113,7 @@ let Announcements = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Maintenance: {
|
Maintenance: {
|
||||||
color: '#383b80',
|
color: hexToDecimal('#383b80'),
|
||||||
title: '🔧 Maintenance',
|
title: '🔧 Maintenance',
|
||||||
description: 'The bot is going offline for maintenance.',
|
description: 'The bot is going offline for maintenance.',
|
||||||
thumbnail: {
|
thumbnail: {
|
||||||
@@ -116,7 +121,7 @@ let Announcements = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Message: {
|
Message: {
|
||||||
color: '#A1DE93',
|
color: hexToDecimal('#A1DE93'),
|
||||||
title: '✉️ Message',
|
title: '✉️ Message',
|
||||||
description: 'Some description here',
|
description: 'Some description here',
|
||||||
thumbnail: {
|
thumbnail: {
|
||||||
@@ -124,7 +129,7 @@ let Announcements = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Alert: {
|
Alert: {
|
||||||
color: '#EC255A',
|
color: hexToDecimal('#EC255A'),
|
||||||
title: '🚨 Alert',
|
title: '🚨 Alert',
|
||||||
description: 'Some description here',
|
description: 'Some description here',
|
||||||
thumbnail: {
|
thumbnail: {
|
||||||
@@ -162,7 +167,7 @@ export default class ServiceAnnouncement extends DiscordModule {
|
|||||||
async run(data: HybridInteractionMessage, args: any) {
|
async run(data: HybridInteractionMessage, args: any) {
|
||||||
if (!Users.isDeveloper(data.getUser()!.id))
|
if (!Users.isDeveloper(data.getUser()!.id))
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.NOT_DEVELOPER(data.getRaw())]
|
embeds: [EMBEDS.NOT_DEVELOPER(data)]
|
||||||
});
|
});
|
||||||
|
|
||||||
const channel = data.getChannel();
|
const channel = data.getChannel();
|
||||||
@@ -180,7 +185,7 @@ export default class ServiceAnnouncement extends DiscordModule {
|
|||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
Logger.error('Unable to load custom ServiceAnnouncement config: ' + err);
|
Logger.error('Unable to load custom ServiceAnnouncement config: ' + err);
|
||||||
return await sendMessage(channel, undefined, {
|
return await sendMessage(channel, undefined, {
|
||||||
embeds: [EMBEDS.RELOAD_ERROR(data.getRaw(), err)]
|
embeds: [EMBEDS.RELOAD_ERROR(data, err)]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -192,7 +197,7 @@ export default class ServiceAnnouncement extends DiscordModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return await sendMessage(channel, undefined, {
|
return await sendMessage(channel, undefined, {
|
||||||
embeds: [EMBEDS.RELOADED(data.getRaw())]
|
embeds: [EMBEDS.RELOADED(data)]
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
previewNews: async (data: HybridInteractionMessage) => {
|
previewNews: async (data: HybridInteractionMessage) => {
|
||||||
@@ -247,7 +252,7 @@ export default class ServiceAnnouncement extends DiscordModule {
|
|||||||
|
|
||||||
let _placeholder = await sendHybridInteractionMessageResponse(
|
let _placeholder = await sendHybridInteractionMessageResponse(
|
||||||
data,
|
data,
|
||||||
{ embeds: [EMBEDS.SENDING_SERVICE_ANNOUNCEMENT(data.getRaw())] },
|
{ embeds: [EMBEDS.SENDING_SERVICE_ANNOUNCEMENT(data)] },
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
if (_placeholder) placeholder = new HybridInteractionMessage(_placeholder);
|
if (_placeholder) placeholder = new HybridInteractionMessage(_placeholder);
|
||||||
@@ -295,15 +300,15 @@ export default class ServiceAnnouncement extends DiscordModule {
|
|||||||
.getMessage()
|
.getMessage()
|
||||||
.edit({
|
.edit({
|
||||||
embeds: [
|
embeds: [
|
||||||
EMBEDS.SERVICE_ANNOUNCEMENT_SENT_WITH_ERRORS(data.getRaw())
|
EMBEDS.SERVICE_ANNOUNCEMENT_SENT_WITH_ERRORS(data)
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
else if (data.isSlashCommand())
|
else if (data.isApplicationCommand())
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
data,
|
data,
|
||||||
{
|
{
|
||||||
embeds: [
|
embeds: [
|
||||||
EMBEDS.SERVICE_ANNOUNCEMENT_SENT_WITH_ERRORS(data.getRaw())
|
EMBEDS.SERVICE_ANNOUNCEMENT_SENT_WITH_ERRORS(data)
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
true
|
true
|
||||||
@@ -312,11 +317,11 @@ export default class ServiceAnnouncement extends DiscordModule {
|
|||||||
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
||||||
return placeholder
|
return placeholder
|
||||||
.getMessage()
|
.getMessage()
|
||||||
.edit({ embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_SENT(data.getRaw())] });
|
.edit({ embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_SENT(data)] });
|
||||||
else if (data.isSlashCommand())
|
else if (data.isApplicationCommand())
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
data,
|
data,
|
||||||
{ embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_SENT(data.getRaw())] },
|
{ embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_SENT(data)] },
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -328,17 +333,17 @@ export default class ServiceAnnouncement extends DiscordModule {
|
|||||||
if (data.isMessage()) {
|
if (data.isMessage()) {
|
||||||
if (args.length === 0)
|
if (args.length === 0)
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.ANNOUNCEMENT_INFO(data.getRaw())]
|
embeds: [EMBEDS.ANNOUNCEMENT_INFO(data)]
|
||||||
});
|
});
|
||||||
query = args[0].toLowerCase();
|
query = args[0].toLowerCase();
|
||||||
} else if (data.isSlashCommand()) {
|
} else if (data.isApplicationCommand()) {
|
||||||
query = args.getSubcommand();
|
query = args.getSubcommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (query) {
|
switch (query) {
|
||||||
case 'info':
|
case 'info':
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.ANNOUNCEMENT_INFO(data.getRaw())]
|
embeds: [EMBEDS.ANNOUNCEMENT_INFO(data)]
|
||||||
});
|
});
|
||||||
case 'reload':
|
case 'reload':
|
||||||
return await funct.reload(data);
|
return await funct.reload(data);
|
||||||
|
|||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
import { CommandInteraction, Interaction, Message } from 'discord.js';
|
import { CommandInteraction, Message } from 'discord.js';
|
||||||
import { I18n } from 'i18n';
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
import DiscordProvider from '../providers/Discord';
|
import DiscordProvider from '../providers/Discord';
|
||||||
@@ -24,7 +24,7 @@ const EMBEDS = {
|
|||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: `☕ ${locale.__('help.general')}`,
|
name: `☕ ${locale.__('help.general')}`,
|
||||||
value: `help, ping, invite, userinfo, stats`,
|
value: `help, ping, invite, userinfo, stats, support`,
|
||||||
inline: true
|
inline: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -34,7 +34,7 @@ const EMBEDS = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: `🎵 ${locale.__('help.music')}`,
|
name: `🎵 ${locale.__('help.music')}`,
|
||||||
value: `play (p), search, skip, pause, resume, queue (q), nowplaying (np), repeat (loop), summon (join), disconnect (leave, dc)`,
|
value: `play (p), playmy, search, skip, pause, resume, queue (q), nowplaying (np), repeat (loop), summon (join), disconnect (leave, dc)`,
|
||||||
inline: true
|
inline: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Message, Interaction, CommandInteraction } from 'discord.js';
|
import { Message, CommandInteraction, BaseInteraction } from 'discord.js';
|
||||||
|
|
||||||
import Users from '../services/Users';
|
import Users from '../services/Users';
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
} from '../utils/DiscordInteraction';
|
} from '../utils/DiscordInteraction';
|
||||||
|
|
||||||
const EMBEDS = {
|
const EMBEDS = {
|
||||||
INTERACTION_INFO: (data: Message | Interaction) => {
|
INTERACTION_INFO: (data: HybridInteractionMessage) => {
|
||||||
return makeInfoEmbed({
|
return makeInfoEmbed({
|
||||||
title: 'Interaction',
|
title: 'Interaction',
|
||||||
description: `This module contains management tool for interaction based contents`,
|
description: `This module contains management tool for interaction based contents`,
|
||||||
@@ -28,47 +28,47 @@ const EMBEDS = {
|
|||||||
value: '``reloadAll`` ``unloadAll`` ``reloadglobal``'
|
value: '``reloadAll`` ``unloadAll`` ``reloadglobal``'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
PROCESSING: (data: Message | Interaction) => {
|
PROCESSING: (data: HybridInteractionMessage) => {
|
||||||
return makeProcessingEmbed({
|
return makeProcessingEmbed({
|
||||||
icon: data instanceof Message ? undefined : '⌛',
|
icon: data instanceof Message ? undefined : '⌛',
|
||||||
title: `Performing actions`,
|
title: `Performing actions`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
NOT_DEVELOPER: (data: Message | Interaction) => {
|
NOT_DEVELOPER: (data: HybridInteractionMessage) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'Developer only',
|
title: 'Developer only',
|
||||||
description: `This command is restricted to the developers only`,
|
description: `This command is restricted to the developers only`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
UNLOADALL_SUCCESS: (data: Message | Interaction) => {
|
UNLOADALL_SUCCESS: (data: HybridInteractionMessage) => {
|
||||||
return makeSuccessEmbed({
|
return makeSuccessEmbed({
|
||||||
title: 'Unloaded all Interaction',
|
title: 'Unloaded all Interaction',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
UNLOADALL_ERROR: (data: Message | Interaction, err: any) => {
|
UNLOADALL_ERROR: (data: HybridInteractionMessage, err: any) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'An error occurred while trying to unload interaction',
|
title: 'An error occurred while trying to unload interaction',
|
||||||
description: '```' + err + '```',
|
description: '```' + err + '```',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
RELOADALL_SUCCESS: (data: Message | Interaction) => {
|
RELOADALL_SUCCESS: (data: HybridInteractionMessage) => {
|
||||||
return makeSuccessEmbed({
|
return makeSuccessEmbed({
|
||||||
title: 'Reloaded all Interaction',
|
title: 'Reloaded all Interaction',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
RELOADALL_ERROR: (data: Message | Interaction, err: any) => {
|
RELOADALL_ERROR: (data: HybridInteractionMessage, err: any) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'An error occurred while trying to reload interaction',
|
title: 'An error occurred while trying to reload interaction',
|
||||||
description: '```' + err + '```',
|
description: '```' + err + '```',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -92,7 +92,7 @@ export default class InteractionManager extends DiscordModule {
|
|||||||
|
|
||||||
if (!Users.isDeveloper(user.id))
|
if (!Users.isDeveloper(user.id))
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.NOT_DEVELOPER(data.getRaw())]
|
embeds: [EMBEDS.NOT_DEVELOPER(data)]
|
||||||
});
|
});
|
||||||
|
|
||||||
const funct = {
|
const funct = {
|
||||||
@@ -100,7 +100,7 @@ export default class InteractionManager extends DiscordModule {
|
|||||||
let placeholder: HybridInteractionMessage | undefined;
|
let placeholder: HybridInteractionMessage | undefined;
|
||||||
|
|
||||||
let _placeholder = await sendHybridInteractionMessageResponse(data, {
|
let _placeholder = await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.PROCESSING(data.getRaw())]
|
embeds: [EMBEDS.PROCESSING(data)]
|
||||||
});
|
});
|
||||||
if (_placeholder) placeholder = new HybridInteractionMessage(_placeholder);
|
if (_placeholder) placeholder = new HybridInteractionMessage(_placeholder);
|
||||||
|
|
||||||
@@ -110,22 +110,22 @@ export default class InteractionManager extends DiscordModule {
|
|||||||
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
||||||
return placeholder
|
return placeholder
|
||||||
.getMessage()
|
.getMessage()
|
||||||
.edit({ embeds: [EMBEDS.UNLOADALL_SUCCESS(data.getRaw())] });
|
.edit({ embeds: [EMBEDS.UNLOADALL_SUCCESS(data)] });
|
||||||
else if (data.isSlashCommand())
|
else if (data.isApplicationCommand())
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
data,
|
data,
|
||||||
{ embeds: [EMBEDS.UNLOADALL_SUCCESS(data.getRaw())] },
|
{ embeds: [EMBEDS.UNLOADALL_SUCCESS(data)] },
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
||||||
return placeholder
|
return placeholder
|
||||||
.getMessage()
|
.getMessage()
|
||||||
.edit({ embeds: [EMBEDS.UNLOADALL_ERROR(data.getRaw(), err)] });
|
.edit({ embeds: [EMBEDS.UNLOADALL_ERROR(data, err)] });
|
||||||
else if (data.isSlashCommand())
|
else if (data.isApplicationCommand())
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
data,
|
data,
|
||||||
{ embeds: [EMBEDS.UNLOADALL_ERROR(data.getRaw(), err)] },
|
{ embeds: [EMBEDS.UNLOADALL_ERROR(data, err)] },
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ export default class InteractionManager extends DiscordModule {
|
|||||||
let placeholder: HybridInteractionMessage | undefined;
|
let placeholder: HybridInteractionMessage | undefined;
|
||||||
|
|
||||||
let _placeholder = await sendHybridInteractionMessageResponse(data, {
|
let _placeholder = await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.PROCESSING(data.getRaw())]
|
embeds: [EMBEDS.PROCESSING(data)]
|
||||||
});
|
});
|
||||||
if (_placeholder) placeholder = new HybridInteractionMessage(_placeholder);
|
if (_placeholder) placeholder = new HybridInteractionMessage(_placeholder);
|
||||||
|
|
||||||
@@ -145,22 +145,22 @@ export default class InteractionManager extends DiscordModule {
|
|||||||
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
||||||
return placeholder
|
return placeholder
|
||||||
.getMessage()
|
.getMessage()
|
||||||
.edit({ embeds: [EMBEDS.RELOADALL_SUCCESS(data.getRaw())] });
|
.edit({ embeds: [EMBEDS.RELOADALL_SUCCESS(data)] });
|
||||||
else if (data.isSlashCommand())
|
else if (data.isApplicationCommand())
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
data,
|
data,
|
||||||
{ embeds: [EMBEDS.RELOADALL_SUCCESS(data.getRaw())] },
|
{ embeds: [EMBEDS.RELOADALL_SUCCESS(data)] },
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
||||||
return placeholder
|
return placeholder
|
||||||
.getMessage()
|
.getMessage()
|
||||||
.edit({ embeds: [EMBEDS.RELOADALL_ERROR(data.getRaw(), err)] });
|
.edit({ embeds: [EMBEDS.RELOADALL_ERROR(data, err)] });
|
||||||
else if (data.isSlashCommand())
|
else if (data.isApplicationCommand())
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
data,
|
data,
|
||||||
{ embeds: [EMBEDS.RELOADALL_ERROR(data.getRaw(), err)] },
|
{ embeds: [EMBEDS.RELOADALL_ERROR(data, err)] },
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -169,7 +169,7 @@ export default class InteractionManager extends DiscordModule {
|
|||||||
let placeholder: HybridInteractionMessage | undefined;
|
let placeholder: HybridInteractionMessage | undefined;
|
||||||
|
|
||||||
let _placeholder = await sendHybridInteractionMessageResponse(data, {
|
let _placeholder = await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.PROCESSING(data.getRaw())]
|
embeds: [EMBEDS.PROCESSING(data)]
|
||||||
});
|
});
|
||||||
if (_placeholder) placeholder = new HybridInteractionMessage(_placeholder);
|
if (_placeholder) placeholder = new HybridInteractionMessage(_placeholder);
|
||||||
|
|
||||||
@@ -180,22 +180,22 @@ export default class InteractionManager extends DiscordModule {
|
|||||||
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
||||||
return placeholder
|
return placeholder
|
||||||
.getMessage()
|
.getMessage()
|
||||||
.edit({ embeds: [EMBEDS.RELOADALL_SUCCESS(data.getRaw())] });
|
.edit({ embeds: [EMBEDS.RELOADALL_SUCCESS(data)] });
|
||||||
else if (data.isSlashCommand())
|
else if (data.isApplicationCommand())
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
data,
|
data,
|
||||||
{ embeds: [EMBEDS.RELOADALL_SUCCESS(data.getRaw())] },
|
{ embeds: [EMBEDS.RELOADALL_SUCCESS(data)] },
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
||||||
return placeholder
|
return placeholder
|
||||||
.getMessage()
|
.getMessage()
|
||||||
.edit({ embeds: [EMBEDS.RELOADALL_ERROR(data.getRaw(), err)] });
|
.edit({ embeds: [EMBEDS.RELOADALL_ERROR(data, err)] });
|
||||||
else if (data.isSlashCommand())
|
else if (data.isApplicationCommand())
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
data,
|
data,
|
||||||
{ embeds: [EMBEDS.RELOADALL_ERROR(data.getRaw(), err)] },
|
{ embeds: [EMBEDS.RELOADALL_ERROR(data, err)] },
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -207,18 +207,18 @@ export default class InteractionManager extends DiscordModule {
|
|||||||
if (data.isMessage()) {
|
if (data.isMessage()) {
|
||||||
if (args.length === 0)
|
if (args.length === 0)
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.INTERACTION_INFO(data.getRaw())]
|
embeds: [EMBEDS.INTERACTION_INFO(data)]
|
||||||
});
|
});
|
||||||
|
|
||||||
query = args[0].toLowerCase();
|
query = args[0].toLowerCase();
|
||||||
} else if (data.isSlashCommand()) {
|
} else if (data.isApplicationCommand()) {
|
||||||
query = args.getSubcommand();
|
query = args.getSubcommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (query) {
|
switch (query) {
|
||||||
case 'info':
|
case 'info':
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.INTERACTION_INFO(data.getRaw())]
|
embeds: [EMBEDS.INTERACTION_INFO(data)]
|
||||||
});
|
});
|
||||||
case 'reloadall':
|
case 'reloadall':
|
||||||
return await funct.reloadAll(data);
|
return await funct.reloadAll(data);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Message, CommandInteraction, Interaction } from 'discord.js';
|
import { Message, CommandInteraction } from 'discord.js';
|
||||||
import { I18n } from 'i18n';
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
import Environment from '../providers/Environment';
|
import Environment from '../providers/Environment';
|
||||||
@@ -13,8 +13,8 @@ const EMBEDS = {
|
|||||||
INVITE_INFO: (data: HybridInteractionMessage, locale: I18n) => {
|
INVITE_INFO: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
const user = data.getUser();
|
const user = data.getUser();
|
||||||
let message;
|
let message;
|
||||||
if (!Environment.get().PRIVATE_BOT || user != null && Users.isDeveloper(user.id))
|
if (!(Environment.get().PRIVATE_BOT === 'true') || user != null && Users.isDeveloper(user.id))
|
||||||
message = locale.__('invite.info', { BOT_NAME: DiscordProvider.client.user!.username, LINK: `https://discord.com/api/oauth2/authorize?client_id=${DiscordProvider.client.user?.id}&permissions=0&scope=bot%20applications.commands`});
|
message = locale.__('invite.info', { BOT_NAME: DiscordProvider.client.user!.username, LINK: `https://discord.com/api/oauth2/authorize?client_id=${DiscordProvider.client.user?.id}&permissions=8&scope=bot%20applications.commands`});
|
||||||
|
|
||||||
return makeInfoEmbed({
|
return makeInfoEmbed({
|
||||||
title: `Invite`,
|
title: `Invite`,
|
||||||
|
|||||||
@@ -3,15 +3,17 @@ import {
|
|||||||
GuildChannel,
|
GuildChannel,
|
||||||
GuildMember,
|
GuildMember,
|
||||||
Message,
|
Message,
|
||||||
Permissions,
|
|
||||||
TextChannel,
|
TextChannel,
|
||||||
MessageActionRow,
|
ButtonBuilder,
|
||||||
MessageButton,
|
|
||||||
Interaction,
|
|
||||||
CommandInteraction,
|
CommandInteraction,
|
||||||
Role,
|
Role,
|
||||||
ThreadChannel,
|
ThreadChannel,
|
||||||
ButtonInteraction
|
ButtonInteraction,
|
||||||
|
BaseInteraction,
|
||||||
|
PermissionsBitField,
|
||||||
|
EmbedBuilder,
|
||||||
|
ButtonStyle,
|
||||||
|
ActionRowBuilder,
|
||||||
} from 'discord.js';
|
} from 'discord.js';
|
||||||
|
|
||||||
import DiscordProvider from '../providers/Discord';
|
import DiscordProvider from '../providers/Discord';
|
||||||
@@ -27,44 +29,44 @@ import {
|
|||||||
import DiscordModule, { HybridInteractionMessage } from '../utils/DiscordModule';
|
import DiscordModule, { HybridInteractionMessage } from '../utils/DiscordModule';
|
||||||
|
|
||||||
const EMBEDS = {
|
const EMBEDS = {
|
||||||
NO_PERMISSION: (data: Message | Interaction) => {
|
NO_PERMISSION: (data: Message | BaseInteraction) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'You need ``ADMINISTRATOR`` permission on this guild!',
|
title: 'You need ``ADMINISTRATOR`` permission on this guild!',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
NO_PARAMETER: (data: Message | Interaction) => {
|
NO_PARAMETER: (data: Message | BaseInteraction) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'Missing parameter',
|
title: 'Missing parameter',
|
||||||
description: `You must define membership screening channel and role to enable this feature`,
|
description: `You must define membership screening channel and role to enable this feature`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
NO_ROLE_MENTIONED: (data: Message | Interaction) => {
|
NO_ROLE_MENTIONED: (data: Message | BaseInteraction) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'No role mentioned',
|
title: 'No role mentioned',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
NO_ROLE_FOUND: (data: Message | Interaction) => {
|
NO_ROLE_FOUND: (data: Message | BaseInteraction) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'Cannot find that role',
|
title: 'Cannot find that role',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
NO_CHANNEL_MENTIONED: (data: Message | Interaction) => {
|
NO_CHANNEL_MENTIONED: (data: Message | BaseInteraction) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'No channel mentioned',
|
title: 'No channel mentioned',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
NO_CHANNEL_FOUND: (data: Message | Interaction) => {
|
NO_CHANNEL_FOUND: (data: Message | BaseInteraction) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'Cannot find that channel',
|
title: 'Cannot find that channel',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
MSINFO: (data: Message | Interaction) => {
|
MSINFO: (data: Message | BaseInteraction) => {
|
||||||
return makeInfoEmbed({
|
return makeInfoEmbed({
|
||||||
title: 'Membership Screening',
|
title: 'Membership Screening',
|
||||||
description: `Membership Screening is a feature to prevent unwanted people to join your guild, similar to whitelist feature. Moderators can approve or deny join request`,
|
description: `Membership Screening is a feature to prevent unwanted people to join your guild, similar to whitelist feature. Moderators can approve or deny join request`,
|
||||||
@@ -74,58 +76,58 @@ const EMBEDS = {
|
|||||||
value: '``setRole`` ``setChannel`` ``createMessage``'
|
value: '``setRole`` ``setChannel`` ``createMessage``'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
ALREADY_ENABLED: (data: Message | Interaction) => {
|
ALREADY_ENABLED: (data: Message | BaseInteraction) => {
|
||||||
return makeInfoEmbed({
|
return makeInfoEmbed({
|
||||||
title: 'Membership Screening is already enabled',
|
title: 'Membership Screening is already enabled',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
MESSAGE_CREATED: (data: Message | Interaction) => {
|
MESSAGE_CREATED: (data: Message | BaseInteraction) => {
|
||||||
return makeSuccessEmbed({
|
return makeSuccessEmbed({
|
||||||
title: 'Membership Screening message created',
|
title: 'Membership Screening message created',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
ALREADY_DISABLED: (data: Message | Interaction) => {
|
ALREADY_DISABLED: (data: Message | BaseInteraction) => {
|
||||||
return makeInfoEmbed({
|
return makeInfoEmbed({
|
||||||
title: 'Membership Screening is already disabled',
|
title: 'Membership Screening is already disabled',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
ENABLED: (data: Message | Interaction) => {
|
ENABLED: (data: Message | BaseInteraction) => {
|
||||||
return makeSuccessEmbed({
|
return makeSuccessEmbed({
|
||||||
title: 'Enabled Membership Screening',
|
title: 'Enabled Membership Screening',
|
||||||
description: `All new member join request will be sent in your defined channel`,
|
description: `All new member join request will be sent in your defined channel`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
DISABLED: (data: Message | Interaction) => {
|
DISABLED: (data: Message | BaseInteraction) => {
|
||||||
return makeSuccessEmbed({
|
return makeSuccessEmbed({
|
||||||
title: 'Disabled Membership Screening',
|
title: 'Disabled Membership Screening',
|
||||||
description: `No longer accepting request, all new member can join directly`,
|
description: `No longer accepting request, all new member can join directly`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
MANAGED_ROLE: (data: Message | Interaction, role: Role) => {
|
MANAGED_ROLE: (data: Message | BaseInteraction, role: Role) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'You cannot use this role',
|
title: 'You cannot use this role',
|
||||||
description:
|
description:
|
||||||
'``' + role.name + '``' + ' is managed by external service and cannot be used',
|
'``' + role.name + '``' + ' is managed by external service and cannot be used',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
CONFIGURED_ROLE: (data: Message | Interaction, role: Role) => {
|
CONFIGURED_ROLE: (data: Message | BaseInteraction, role: Role) => {
|
||||||
return makeSuccessEmbed({
|
return makeSuccessEmbed({
|
||||||
title: 'Configured Membership Screening Role',
|
title: 'Configured Membership Screening Role',
|
||||||
description:
|
description:
|
||||||
'New member will be given a ' + '``' + role.name + '``' + ' role after approval',
|
'New member will be given a ' + '``' + role.name + '``' + ' role after approval',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
CONFIGURED_CHANNEL: (data: Message | Interaction, channel: GuildChannel) => {
|
CONFIGURED_CHANNEL: (data: Message | BaseInteraction, channel: GuildChannel) => {
|
||||||
return makeSuccessEmbed({
|
return makeSuccessEmbed({
|
||||||
title: 'Configured Membership Screening Channel',
|
title: 'Configured Membership Screening Channel',
|
||||||
description:
|
description:
|
||||||
@@ -134,18 +136,18 @@ const EMBEDS = {
|
|||||||
channel.name +
|
channel.name +
|
||||||
'``' +
|
'``' +
|
||||||
' can approve or deny request',
|
' can approve or deny request',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
INVALID_CHANNEL: (data: Message | Interaction, channel: GuildChannel) => {
|
INVALID_CHANNEL: (data: Message | BaseInteraction, channel: GuildChannel) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'Invalid channel type, only TextChannel is supported',
|
title: 'Invalid channel type, only TextChannel is supported',
|
||||||
description: '``' + channel.name + '``' + ' is not a text channel',
|
description: '``' + channel.name + '``' + ' is not a text channel',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
INVALID_CHANNEL_THREAD: (
|
INVALID_CHANNEL_THREAD: (
|
||||||
data: Message | Interaction,
|
data: Message | BaseInteraction,
|
||||||
channel: GuildChannel | ThreadChannel
|
channel: GuildChannel | ThreadChannel
|
||||||
) => {
|
) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
@@ -155,38 +157,38 @@ const EMBEDS = {
|
|||||||
channel.name +
|
channel.name +
|
||||||
'``' +
|
'``' +
|
||||||
' is a thread channel. Please use a regular text channel',
|
' is a thread channel. Please use a regular text channel',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
BOT_NO_PERMISSION: (data: Message | Interaction, channel: GuildChannel) => {
|
BOT_NO_PERMISSION: (data: Message | BaseInteraction, channel: GuildChannel) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: `I don't have permission`,
|
title: `I don't have permission`,
|
||||||
description: 'I cannot access/send message in ' + '``' + channel.name + '``',
|
description: 'I cannot access/send message in ' + '``' + channel.name + '``',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
NO_LONGER_VALID_ROLE: (data: Message | Interaction) => {
|
NO_LONGER_VALID_ROLE: (data: Message | BaseInteraction) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'The configured role is no longer valid. Please update the role in configuration',
|
title: 'The configured role is no longer valid. Please update the role in configuration',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
CANNOT_PERFORM_ASSIGN_ROLE: (data: Message | Interaction) => {
|
CANNOT_PERFORM_ASSIGN_ROLE: (data: Message | BaseInteraction) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'Cannot grant the role to user, make sure I have permission to do that',
|
title: 'Cannot grant the role to user, make sure I have permission to do that',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
CANNOT_PERFORM_ASSIGN_KICK: (data: Message | Interaction) => {
|
CANNOT_PERFORM_ASSIGN_KICK: (data: Message | BaseInteraction) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'Cannot kick the user, make sure I have permission to do that',
|
title: 'Cannot kick the user, make sure I have permission to do that',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
CANNOT_PERFORM_ASSIGN_BAN: (data: Message | Interaction) => {
|
CANNOT_PERFORM_ASSIGN_BAN: (data: Message | BaseInteraction) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: 'Cannot ban the user, make sure I have permission to do that',
|
title: 'Cannot ban the user, make sure I have permission to do that',
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data instanceof BaseInteraction ? data.user : data.author
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
CREATE_MESSAGE: () => {
|
CREATE_MESSAGE: () => {
|
||||||
@@ -246,10 +248,12 @@ export default class MembershipScreening extends DiscordModule {
|
|||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
embed[0].footer = {
|
const newEmbed = new EmbedBuilder(embed[0].data);
|
||||||
|
|
||||||
|
newEmbed.setFooter({
|
||||||
text: `${interaction.user.username} | v${App.version}`,
|
text: `${interaction.user.username} | v${App.version}`,
|
||||||
iconURL: `${interaction.user.displayAvatarURL()}?size=4096`
|
iconURL: `${interaction.user.displayAvatarURL()}?size=4096`
|
||||||
};
|
});
|
||||||
|
|
||||||
if (['approve', 'deny', 'ban'].includes(payload.a)) {
|
if (['approve', 'deny', 'ban'].includes(payload.a)) {
|
||||||
if (!payload.d.requester) return;
|
if (!payload.d.requester) return;
|
||||||
@@ -268,26 +272,35 @@ export default class MembershipScreening extends DiscordModule {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!requesterMember) {
|
if (!requesterMember) {
|
||||||
embed[0].addField('❌ Invalid', `Unable to find the user. User left already?`);
|
newEmbed.addFields([
|
||||||
return await message.edit({ components: [], embeds: embed });
|
{
|
||||||
|
name: '❌ Invalid',
|
||||||
|
value: `Unable to find the user. User left already?`
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
return await message.edit({ components: [], embeds: [newEmbed] });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requesterMember.roles.cache.has(PrismaGuild.MembershipScreening_GivenRole)) {
|
if (requesterMember.roles.cache.has(PrismaGuild.MembershipScreening_GivenRole)) {
|
||||||
embed[0].addField(
|
newEmbed.addFields([
|
||||||
'✅ Approved',
|
{
|
||||||
`By: Unknown (User already obtained the role by other means)`
|
name: '✅ Approved',
|
||||||
);
|
value: `By: Unknown (User already obtained the role by other means)`
|
||||||
return await message.edit({ components: [], embeds: embed });
|
}
|
||||||
|
]);
|
||||||
|
return await message.edit({ components: [], embeds: [newEmbed] });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payload.a === 'approve') {
|
if (payload.a === 'approve') {
|
||||||
try {
|
try {
|
||||||
await requesterMember.roles.add(role);
|
await requesterMember.roles.add(role);
|
||||||
embed[0].addField(
|
newEmbed.addFields([
|
||||||
'✅ Approved',
|
{
|
||||||
`By: ${interaction.user.username}#${interaction.user.discriminator} (${interaction.user.id})`
|
name: '✅ Approved',
|
||||||
);
|
value: `By: ${interaction.user.username}#${interaction.user.discriminator} (${interaction.user.id})`
|
||||||
await message.edit({ components: [], embeds: embed });
|
}
|
||||||
|
]);
|
||||||
|
await message.edit({ components: [], embeds: [newEmbed] });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return interaction.reply({
|
return interaction.reply({
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
@@ -297,11 +310,13 @@ export default class MembershipScreening extends DiscordModule {
|
|||||||
} else if (payload.a === 'deny') {
|
} else if (payload.a === 'deny') {
|
||||||
try {
|
try {
|
||||||
await requesterMember.kick();
|
await requesterMember.kick();
|
||||||
embed[0].addField(
|
newEmbed.addFields([
|
||||||
'❌ Denied',
|
{
|
||||||
`By: ${interaction.user.username}#${interaction.user.discriminator} (${interaction.user.id})`
|
name: '❌ Denied',
|
||||||
);
|
value: `By: ${interaction.user.username}#${interaction.user.discriminator} (${interaction.user.id})`
|
||||||
await message.edit({ components: [], embeds: embed });
|
}
|
||||||
|
]);
|
||||||
|
await message.edit({ components: [], embeds: [newEmbed] });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return interaction.reply({
|
return interaction.reply({
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
@@ -313,11 +328,13 @@ export default class MembershipScreening extends DiscordModule {
|
|||||||
await requesterMember.ban({
|
await requesterMember.ban({
|
||||||
reason: `Membership Screening, action issued by ${interaction.user.username}#${interaction.user.discriminator} (${interaction.user.id})`
|
reason: `Membership Screening, action issued by ${interaction.user.username}#${interaction.user.discriminator} (${interaction.user.id})`
|
||||||
});
|
});
|
||||||
embed[0].addField(
|
newEmbed.addFields([
|
||||||
'🔪 Banned',
|
{
|
||||||
`By: ${interaction.user.username}#${interaction.user.discriminator} (${interaction.user.id})`
|
name: '🔪 Banned',
|
||||||
);
|
value: `By: ${interaction.user.username}#${interaction.user.discriminator} (${interaction.user.id})`
|
||||||
await message.edit({ components: [], embeds: embed });
|
}
|
||||||
|
]);
|
||||||
|
await message.edit({ components: [], embeds: [newEmbed] });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return interaction.reply({
|
return interaction.reply({
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
@@ -395,9 +412,9 @@ export default class MembershipScreening extends DiscordModule {
|
|||||||
role =
|
role =
|
||||||
data.getMessage().mentions.roles.first() ||
|
data.getMessage().mentions.roles.first() ||
|
||||||
guild.roles.cache.find((role) => role.name === _name);
|
guild.roles.cache.find((role) => role.name === _name);
|
||||||
} else if (data.isSlashCommand())
|
} else if (data.isApplicationCommand())
|
||||||
role = guild.roles.cache.find(
|
role = guild.roles.cache.find(
|
||||||
(role) => role.id === data.getSlashCommand().options.getRole('role')?.id
|
(role) => role.id === data.getSlashCommand().options.get('role')?.role?.id
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!role)
|
if (!role)
|
||||||
@@ -427,8 +444,8 @@ export default class MembershipScreening extends DiscordModule {
|
|||||||
embeds: [EMBEDS.NO_CHANNEL_MENTIONED(data.getRaw())]
|
embeds: [EMBEDS.NO_CHANNEL_MENTIONED(data.getRaw())]
|
||||||
});
|
});
|
||||||
mentionChannel = data.getMessage().mentions.channels.first();
|
mentionChannel = data.getMessage().mentions.channels.first();
|
||||||
} else if (data.isSlashCommand())
|
} else if (data.isApplicationCommand())
|
||||||
mentionChannel = data.getSlashCommand().options.getChannel('channel');
|
mentionChannel = data.getSlashCommand().options.get('channel', true).channel;
|
||||||
|
|
||||||
if (!mentionChannel)
|
if (!mentionChannel)
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
@@ -443,15 +460,14 @@ export default class MembershipScreening extends DiscordModule {
|
|||||||
embeds: [EMBEDS.INVALID_CHANNEL_THREAD(data.getRaw(), TargetChannel)]
|
embeds: [EMBEDS.INVALID_CHANNEL_THREAD(data.getRaw(), TargetChannel)]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!TargetChannel.isText())
|
if (!TargetChannel.isTextBased())
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.INVALID_CHANNEL(data.getRaw(), TargetChannel)]
|
embeds: [EMBEDS.INVALID_CHANNEL(data.getRaw(), TargetChannel)]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!guild
|
!guild.members.me?.permissionsIn(TargetChannel)
|
||||||
.me!.permissionsIn(TargetChannel)
|
.has([PermissionsBitField.Flags.SendMessages, PermissionsBitField.Flags.ViewChannel])
|
||||||
.has([Permissions.FLAGS.SEND_MESSAGES, Permissions.FLAGS.VIEW_CHANNEL])
|
|
||||||
)
|
)
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.BOT_NO_PERMISSION(data.getRaw(), TargetChannel)]
|
embeds: [EMBEDS.BOT_NO_PERMISSION(data.getRaw(), TargetChannel)]
|
||||||
@@ -470,7 +486,7 @@ export default class MembershipScreening extends DiscordModule {
|
|||||||
return await sendMessage(channel, undefined, {
|
return await sendMessage(channel, undefined, {
|
||||||
embeds: [EMBEDS.CREATE_MESSAGE()]
|
embeds: [EMBEDS.CREATE_MESSAGE()]
|
||||||
});
|
});
|
||||||
else if (data.isSlashCommand()) {
|
else if (data.isApplicationCommand()) {
|
||||||
await sendHybridInteractionMessageResponse(data, {
|
await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.MESSAGE_CREATED(data.getRaw())]
|
embeds: [EMBEDS.MESSAGE_CREATED(data.getRaw())]
|
||||||
});
|
});
|
||||||
@@ -483,7 +499,7 @@ export default class MembershipScreening extends DiscordModule {
|
|||||||
|
|
||||||
let query;
|
let query;
|
||||||
|
|
||||||
if (!member.permissions.has([Permissions.FLAGS.ADMINISTRATOR]))
|
if (!member.permissions.has([PermissionsBitField.Flags.Administrator]))
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.NO_PERMISSION(data.getRaw())]
|
embeds: [EMBEDS.NO_PERMISSION(data.getRaw())]
|
||||||
});
|
});
|
||||||
@@ -495,7 +511,7 @@ export default class MembershipScreening extends DiscordModule {
|
|||||||
});
|
});
|
||||||
|
|
||||||
query = args[0].toLowerCase();
|
query = args[0].toLowerCase();
|
||||||
} else if (data.isSlashCommand()) query = args.getSubcommand();
|
} else if (data.isApplicationCommand()) query = args.getSubcommand();
|
||||||
|
|
||||||
switch (query) {
|
switch (query) {
|
||||||
case 'enable':
|
case 'enable':
|
||||||
@@ -549,9 +565,9 @@ export default class MembershipScreening extends DiscordModule {
|
|||||||
|
|
||||||
embed.setThumbnail(`${member.user.displayAvatarURL()}?size=4096`);
|
embed.setThumbnail(`${member.user.displayAvatarURL()}?size=4096`);
|
||||||
|
|
||||||
const row = new MessageActionRow()
|
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||||
.addComponents(
|
.addComponents([
|
||||||
new MessageButton()
|
new ButtonBuilder()
|
||||||
.setCustomId(
|
.setCustomId(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
m: 'MembershipScreening',
|
m: 'MembershipScreening',
|
||||||
@@ -563,10 +579,8 @@ export default class MembershipScreening extends DiscordModule {
|
|||||||
)
|
)
|
||||||
.setEmoji('✅')
|
.setEmoji('✅')
|
||||||
.setLabel(' Approve')
|
.setLabel(' Approve')
|
||||||
.setStyle('SUCCESS')
|
.setStyle(ButtonStyle.Success),
|
||||||
)
|
new ButtonBuilder()
|
||||||
.addComponents(
|
|
||||||
new MessageButton()
|
|
||||||
.setCustomId(
|
.setCustomId(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
m: 'MembershipScreening',
|
m: 'MembershipScreening',
|
||||||
@@ -578,10 +592,8 @@ export default class MembershipScreening extends DiscordModule {
|
|||||||
)
|
)
|
||||||
.setEmoji('⛔')
|
.setEmoji('⛔')
|
||||||
.setLabel(' Deny and kick')
|
.setLabel(' Deny and kick')
|
||||||
.setStyle('DANGER')
|
.setStyle(ButtonStyle.Danger),
|
||||||
)
|
new ButtonBuilder()
|
||||||
.addComponents(
|
|
||||||
new MessageButton()
|
|
||||||
.setCustomId(
|
.setCustomId(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
m: 'MembershipScreening',
|
m: 'MembershipScreening',
|
||||||
@@ -593,7 +605,8 @@ export default class MembershipScreening extends DiscordModule {
|
|||||||
)
|
)
|
||||||
.setEmoji('🔪')
|
.setEmoji('🔪')
|
||||||
.setLabel(' Vision Hunt Decree (Ban)')
|
.setLabel(' Vision Hunt Decree (Ban)')
|
||||||
.setStyle('DANGER')
|
.setStyle(ButtonStyle.Danger)
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
await channel.send({ content: '\u200b', embeds: [embed], components: [row] });
|
await channel.send({ content: '\u200b', embeds: [embed], components: [row] });
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
import {
|
import {
|
||||||
Message,
|
Message,
|
||||||
CommandInteraction,
|
CommandInteraction,
|
||||||
Interaction,
|
|
||||||
VoiceChannel,
|
VoiceChannel,
|
||||||
Permissions,
|
|
||||||
GuildMember,
|
|
||||||
DMChannel,
|
DMChannel,
|
||||||
StageChannel,
|
StageChannel,
|
||||||
MessageActionRow,
|
ActionRowBuilder,
|
||||||
MessageButton,
|
ButtonBuilder,
|
||||||
TextChannel,
|
PermissionsBitField,
|
||||||
VoiceBasedChannel
|
ButtonStyle,
|
||||||
|
BaseGuildTextChannel,
|
||||||
|
BaseGuildVoiceChannel
|
||||||
} from 'discord.js';
|
} from 'discord.js';
|
||||||
import { I18n } from 'i18n';
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
@@ -28,11 +27,14 @@ import DiscordMusicPlayer, {
|
|||||||
VoiceDisconnectedEvent,
|
VoiceDisconnectedEvent,
|
||||||
ValidTracks,
|
ValidTracks,
|
||||||
DiscordMusicPlayerInstance,
|
DiscordMusicPlayerInstance,
|
||||||
DiscordMusicPlayerLoopMode
|
DiscordMusicPlayerLoopMode,
|
||||||
|
TrackUtils
|
||||||
} from '../../providers/DiscordMusicPlayer';
|
} from '../../providers/DiscordMusicPlayer';
|
||||||
|
|
||||||
import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule';
|
import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule';
|
||||||
import Locale from '../../services/Locale';
|
import Locale from '../../services/Locale';
|
||||||
|
import { SpotifyTrack, YouTubeVideo } from 'play-dl';
|
||||||
|
import { checkBotPermissionsInChannel } from '../../utils/DiscordPermission';
|
||||||
|
|
||||||
const EMBEDS = {
|
const EMBEDS = {
|
||||||
VOICECHANNEL_JOINED: (data: HybridInteractionMessage, locale: I18n) => {
|
VOICECHANNEL_JOINED: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
@@ -77,35 +79,37 @@ const EMBEDS = {
|
|||||||
user: data.getUser()
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
NOW_PLAYING: (data: HybridInteractionMessage, locale: I18n, track: ValidTracks) => {
|
NOW_PLAYING: async (data: HybridInteractionMessage, locale: I18n, track: ValidTracks) => {
|
||||||
|
|
||||||
|
const title = TrackUtils.getTitle(track);
|
||||||
|
const thumbnails = await TrackUtils.getThumbnails(track);
|
||||||
|
|
||||||
const embed = makeInfoEmbed({
|
const embed = makeInfoEmbed({
|
||||||
title: locale.__('musicplayer.now_playing'),
|
title: locale.__('musicplayer.now_playing'),
|
||||||
icon: '🎵 ',
|
icon: '🎵 ',
|
||||||
description: track.title,
|
description: title,
|
||||||
user: DiscordProvider.client.user
|
user: DiscordProvider.client.user
|
||||||
});
|
});
|
||||||
|
|
||||||
const highestResolutionThumbnail = track.thumbnails.reduce((prev, current) =>
|
if (TrackUtils.getHighestResolutionThumbnail(thumbnails))
|
||||||
prev.height * prev.width > current.height * current.width ? prev : current
|
embed.setImage(TrackUtils.getHighestResolutionThumbnail(thumbnails).url);
|
||||||
);
|
|
||||||
|
|
||||||
if (highestResolutionThumbnail) embed.setImage(highestResolutionThumbnail.url);
|
|
||||||
|
|
||||||
return embed;
|
return embed;
|
||||||
},
|
},
|
||||||
NOW_REPEATING: (data: HybridInteractionMessage, locale: I18n, track: ValidTracks) => {
|
NOW_REPEATING: async (data: HybridInteractionMessage, locale: I18n, track: ValidTracks) => {
|
||||||
|
|
||||||
|
const title = TrackUtils.getTitle(track);
|
||||||
|
const thumbnails = await TrackUtils.getThumbnails(track);
|
||||||
|
|
||||||
const embed = makeInfoEmbed({
|
const embed = makeInfoEmbed({
|
||||||
title: locale.__('musicplayer.now_playing_repeating'),
|
title: locale.__('musicplayer.now_playing_repeating'),
|
||||||
icon: '🎵 ',
|
icon: '🎵 ',
|
||||||
description: `${track.title}`,
|
description: title,
|
||||||
user: DiscordProvider.client.user
|
user: DiscordProvider.client.user
|
||||||
});
|
});
|
||||||
|
|
||||||
const highestResolutionThumbnail = track.thumbnails.reduce((prev, current) =>
|
if (TrackUtils.getHighestResolutionThumbnail(thumbnails))
|
||||||
prev.height * prev.width > current.height * current.width ? prev : current
|
embed.setImage(TrackUtils.getHighestResolutionThumbnail(thumbnails).url);
|
||||||
);
|
|
||||||
|
|
||||||
if (highestResolutionThumbnail) embed.setImage(highestResolutionThumbnail.url);
|
|
||||||
|
|
||||||
return embed;
|
return embed;
|
||||||
}
|
}
|
||||||
@@ -116,7 +120,7 @@ export async function joinVoiceChannelProcedure(
|
|||||||
instance: DiscordMusicPlayerInstance | null,
|
instance: DiscordMusicPlayerInstance | null,
|
||||||
voiceChannel: VoiceChannel | StageChannel
|
voiceChannel: VoiceChannel | StageChannel
|
||||||
) {
|
) {
|
||||||
const isSlashCommand = data.isSlashCommand();
|
const isSlashCommand = data.isApplicationCommand();
|
||||||
const isAcceptableInteraction = data.isSelectMenu() || data.isButton();
|
const isAcceptableInteraction = data.isSelectMenu() || data.isButton();
|
||||||
const isMessage = data.isMessage();
|
const isMessage = data.isMessage();
|
||||||
if (!isSlashCommand && !isAcceptableInteraction && !isMessage) return;
|
if (!isSlashCommand && !isAcceptableInteraction && !isMessage) return;
|
||||||
@@ -128,16 +132,18 @@ export async function joinVoiceChannelProcedure(
|
|||||||
if (!member || !channel || !guild) return;
|
if (!member || !channel || !guild) return;
|
||||||
|
|
||||||
if (channel instanceof DMChannel) return;
|
if (channel instanceof DMChannel) return;
|
||||||
if (!(channel instanceof TextChannel)) return;
|
if (!(channel instanceof BaseGuildTextChannel || channel instanceof BaseGuildVoiceChannel)) return;
|
||||||
|
|
||||||
const memberVoiceChannel = member.voice.channel; //isMessage ? member.voice.channel : DiscordProvider.client.guilds.cache.get(guild.id)!.members.cache.get((data as Interaction).user.id)?.voice.channel;
|
const memberVoiceChannel = member.voice.channel;
|
||||||
if (!memberVoiceChannel) return;
|
if (!memberVoiceChannel) return;
|
||||||
|
|
||||||
const bot = guild.me;
|
const bot = guild.members.me;
|
||||||
if (!bot) return;
|
if (!bot) return;
|
||||||
|
|
||||||
const locale = await Locale.getGuildLocale(guild.id);
|
const locale = await Locale.getGuildLocale(guild.id);
|
||||||
|
|
||||||
|
if(!await checkBotPermissionsInChannel({ guild, data, locale, channel: memberVoiceChannel, permissions: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.Connect]})) return;
|
||||||
|
|
||||||
// If already in VoiceChannel
|
// If already in VoiceChannel
|
||||||
if (bot.voice.channelId) {
|
if (bot.voice.channelId) {
|
||||||
// But, no music instance yet (The bot might just restarted)
|
// But, no music instance yet (The bot might just restarted)
|
||||||
@@ -179,7 +185,7 @@ export async function joinVoiceChannelProcedure(
|
|||||||
EMBEDS.VOICECHANNEL_INUSE(
|
EMBEDS.VOICECHANNEL_INUSE(
|
||||||
data,
|
data,
|
||||||
locale,
|
locale,
|
||||||
member.permissions.has([Permissions.FLAGS.MOVE_MEMBERS])
|
member.permissions.has([PermissionsBitField.Flags.MoveMembers])
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
@@ -217,30 +223,44 @@ export async function joinVoiceChannelProcedure(
|
|||||||
|
|
||||||
// Register Event Listeners
|
// Register Event Listeners
|
||||||
instance.events.on('playing', async (event: PlayerPlayingEvent) => {
|
instance.events.on('playing', async (event: PlayerPlayingEvent) => {
|
||||||
|
const locale = await Locale.getGuildLocale(guild.id);
|
||||||
if (!event.instance.queue || !event.instance.queue.track || event.instance.queue.track.length === 0) return;
|
if (!event.instance.queue || !event.instance.queue.track || event.instance.queue.track.length === 0) return;
|
||||||
previousTrack = event.instance.getPreviousTrack();
|
previousTrack = event.instance.getPreviousTrack();
|
||||||
|
|
||||||
if (event.instance.queue.track[0] !== previousTrack) isLoopMessageSent = false;
|
if (event.instance.queue.track[0] !== previousTrack) isLoopMessageSent = false;
|
||||||
else if (event.instance.queue.track[0] === previousTrack && isLoopMessageSent) return;
|
else if (event.instance.queue.track[0] === previousTrack && isLoopMessageSent) return;
|
||||||
|
|
||||||
const row = new MessageActionRow().addComponents(
|
const row = new ActionRowBuilder<ButtonBuilder>();
|
||||||
new MessageButton()
|
if(event.instance.queue.track[0] instanceof SpotifyTrack)
|
||||||
.setEmoji('▶️')
|
row.addComponents([
|
||||||
.setLabel(' Open on YouTube')
|
new ButtonBuilder()
|
||||||
.setURL(encodeURI(`https://www.youtube.com/watch?v=${event.instance.queue.track[0].id}`))
|
.setEmoji('🟢')
|
||||||
.setStyle('LINK')
|
.setLabel(' Open in Spotify')
|
||||||
);
|
.setURL(encodeURI(`https://open.spotify.com/track/${event.instance.queue.track[0].id}`))
|
||||||
|
.setStyle(ButtonStyle.Link)
|
||||||
|
]);
|
||||||
|
if(event.instance.queue.track[0] instanceof YouTubeVideo || event.instance.queue.track[0] instanceof SpotifyTrack) {
|
||||||
|
const actualPlaybackURL = event.instance.getActualPlaybackURL();
|
||||||
|
if(event.instance.queue.track[0] instanceof SpotifyTrack && !actualPlaybackURL) return;
|
||||||
|
row.addComponents([
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setEmoji('🔴')
|
||||||
|
.setLabel(' Open in YouTube')
|
||||||
|
.setURL(event.instance.queue.track[0] instanceof YouTubeVideo ? encodeURI(`https://www.youtube.com/watch?v=${event.instance.queue.track[0].id}`) : encodeURI(event.instance.getActualPlaybackURL()!))
|
||||||
|
.setStyle(ButtonStyle.Link)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
if (event.instance.textChannel) {
|
if (event.instance.textChannel) {
|
||||||
if (event.instance.getLoopMode() === DiscordMusicPlayerLoopMode.Current) {
|
if (event.instance.getLoopMode() === DiscordMusicPlayerLoopMode.Current) {
|
||||||
isLoopMessageSent = true;
|
isLoopMessageSent = true;
|
||||||
await sendMessage(event.instance.textChannel, undefined, {
|
await sendMessage(event.instance.textChannel, undefined, {
|
||||||
embeds: [EMBEDS.NOW_REPEATING(data, locale, event.instance.queue.track[0])],
|
embeds: [await EMBEDS.NOW_REPEATING(data, locale, event.instance.queue.track[0])],
|
||||||
components: [row]
|
components: [row]
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await sendMessage(event.instance.textChannel, undefined, {
|
await sendMessage(event.instance.textChannel, undefined, {
|
||||||
embeds: [EMBEDS.NOW_PLAYING(data, locale, event.instance.queue.track[0])],
|
embeds: [await EMBEDS.NOW_PLAYING(data, locale, event.instance.queue.track[0])],
|
||||||
components: [row]
|
components: [row]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { I18n } from "i18n";
|
import { I18n } from "i18n";
|
||||||
import { Message, CommandInteraction, Interaction, MessageActionRow, ButtonInteraction, MessageSelectMenu, MessageSelectOptionData } from "discord.js";
|
import { Message, CommandInteraction } from "discord.js";
|
||||||
|
|
||||||
import DiscordMusicPlayer, { DiscordMusicPlayerLoopMode } from "../../providers/DiscordMusicPlayer";
|
import DiscordMusicPlayer, { DiscordMusicPlayerLoopMode } from "../../providers/DiscordMusicPlayer";
|
||||||
import Locale from "../../services/Locale";
|
import Locale from "../../services/Locale";
|
||||||
@@ -81,7 +81,7 @@ export default class Loop extends DiscordModule {
|
|||||||
if (args.length !== 0)
|
if (args.length !== 0)
|
||||||
query = args.join(' ');
|
query = args.join(' ');
|
||||||
}
|
}
|
||||||
else if (data.isSlashCommand())
|
else if (data.isApplicationCommand())
|
||||||
query = args.getSubcommand();
|
query = args.getSubcommand();
|
||||||
|
|
||||||
const voiceChannel = member.voice.channel;
|
const voiceChannel = member.voice.channel;
|
||||||
|
|||||||
@@ -1,26 +1,29 @@
|
|||||||
import { Message, CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
|
import { Message, CommandInteraction, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
|
||||||
import { I18n } from "i18n";
|
import { I18n } from "i18n";
|
||||||
|
import { SpotifyTrack, YouTubeVideo } from "play-dl";
|
||||||
|
|
||||||
import DiscordProvider from "../../providers/Discord";
|
import DiscordProvider from "../../providers/Discord";
|
||||||
import DiscordMusicPlayer, { ValidTracks } from "../../providers/DiscordMusicPlayer";
|
import DiscordMusicPlayer, { TrackUtils, ValidTracks } from "../../providers/DiscordMusicPlayer";
|
||||||
import Locale from "../../services/Locale";
|
import Locale from "../../services/Locale";
|
||||||
|
|
||||||
import { makeErrorEmbed, makeInfoEmbed, sendHybridInteractionMessageResponse } from "../../utils/DiscordMessage";
|
import { makeErrorEmbed, makeInfoEmbed, sendHybridInteractionMessageResponse } from "../../utils/DiscordMessage";
|
||||||
import DiscordModule, { HybridInteractionMessage } from "../../utils/DiscordModule";
|
import DiscordModule, { HybridInteractionMessage } from "../../utils/DiscordModule";
|
||||||
|
|
||||||
const EMBEDS = {
|
const EMBEDS = {
|
||||||
NOW_PLAYING: (data: HybridInteractionMessage, locale: I18n, track: ValidTracks) => {
|
NOW_PLAYING: async (data: HybridInteractionMessage, locale: I18n, track: ValidTracks) => {
|
||||||
|
|
||||||
|
const title = TrackUtils.getTitle(track);
|
||||||
|
const thumbnails = await TrackUtils.getThumbnails(track);
|
||||||
|
|
||||||
const embed = makeInfoEmbed({
|
const embed = makeInfoEmbed({
|
||||||
title: locale.__('musicplayer.now_playing'),
|
title: locale.__('musicplayer.now_playing'),
|
||||||
icon: '🎵 ',
|
icon: '🎵 ',
|
||||||
description: track.title,
|
description: title,
|
||||||
user: DiscordProvider.client.user
|
user: DiscordProvider.client.user
|
||||||
});
|
});
|
||||||
|
|
||||||
const highestResolutionThumbnail = track.thumbnails.reduce((prev, current) => (prev.height * prev.width > current.height * current.width) ? prev : current)
|
if (TrackUtils.getHighestResolutionThumbnail(thumbnails))
|
||||||
|
embed.setImage(TrackUtils.getHighestResolutionThumbnail(thumbnails).url);
|
||||||
if(highestResolutionThumbnail)
|
|
||||||
embed.setImage(highestResolutionThumbnail.url);
|
|
||||||
|
|
||||||
return embed;
|
return embed;
|
||||||
},
|
},
|
||||||
@@ -55,15 +58,27 @@ export default class NowPlaying extends DiscordModule {
|
|||||||
const instance = DiscordMusicPlayer.getGuildInstance(guild.id);
|
const instance = DiscordMusicPlayer.getGuildInstance(guild.id);
|
||||||
if(!instance || !instance.queue.track[0]) return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.NO_MUSIC_PLAYING(data, locale)] });
|
if(!instance || !instance.queue.track[0]) return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.NO_MUSIC_PLAYING(data, locale)] });
|
||||||
|
|
||||||
const row = new MessageActionRow()
|
const row = new ActionRowBuilder<ButtonBuilder>();
|
||||||
.addComponents(
|
|
||||||
new MessageButton()
|
|
||||||
.setEmoji('▶️')
|
|
||||||
.setLabel(' Open on YouTube')
|
|
||||||
.setURL(encodeURI(`https://www.youtube.com/watch?v=${instance.queue.track[0].id}`))
|
|
||||||
.setStyle('LINK'),
|
|
||||||
)
|
|
||||||
|
|
||||||
return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.NOW_PLAYING(data, locale, instance.queue.track[0])], components: [row] });
|
if(instance.queue.track[0] instanceof SpotifyTrack)
|
||||||
|
row.addComponents([
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setEmoji('🟢')
|
||||||
|
.setLabel(' Open in Spotify')
|
||||||
|
.setURL(encodeURI(`https://open.spotify.com/track/${instance.queue.track[0].id}`))
|
||||||
|
.setStyle(ButtonStyle.Link),
|
||||||
|
]);
|
||||||
|
if(instance.queue.track[0] instanceof YouTubeVideo || instance.queue.track[0] instanceof SpotifyTrack) {
|
||||||
|
const actualPlaybackURL = instance.getActualPlaybackURL();
|
||||||
|
if(instance.queue.track[0] instanceof SpotifyTrack && !actualPlaybackURL) return;
|
||||||
|
row.addComponents([
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setEmoji('🔴')
|
||||||
|
.setLabel(' Open in YouTube')
|
||||||
|
.setURL(instance.queue.track[0] instanceof YouTubeVideo ? encodeURI(`https://www.youtube.com/watch?v=${instance.queue.track[0].id}`) : encodeURI(instance.getActualPlaybackURL()!))
|
||||||
|
.setStyle(ButtonStyle.Link),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return await sendHybridInteractionMessageResponse(data, { embeds: [await EMBEDS.NOW_PLAYING(data, locale, instance.queue.track[0])], components: [row] });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Message, CommandInteraction, Interaction } from "discord.js";
|
import { Message, CommandInteraction, Interaction } from "discord.js";
|
||||||
import { I18n } from "i18n";
|
import { I18n } from "i18n";
|
||||||
|
|
||||||
import DiscordProvider from "../../providers/Discord";
|
|
||||||
import DiscordMusicPlayer from "../../providers/DiscordMusicPlayer";
|
import DiscordMusicPlayer from "../../providers/DiscordMusicPlayer";
|
||||||
import Locale from "../../services/Locale";
|
import Locale from "../../services/Locale";
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
import {
|
import {
|
||||||
Message,
|
Message,
|
||||||
CommandInteraction,
|
CommandInteraction,
|
||||||
Interaction,
|
|
||||||
VoiceChannel,
|
VoiceChannel,
|
||||||
MessageActionRow,
|
ActionRowBuilder,
|
||||||
MessageButton,
|
ButtonBuilder,
|
||||||
SelectMenuInteraction,
|
SelectMenuInteraction,
|
||||||
ButtonInteraction,
|
ButtonInteraction,
|
||||||
StageChannel
|
StageChannel,
|
||||||
|
ButtonStyle,
|
||||||
|
PermissionsBitField
|
||||||
} from 'discord.js';
|
} from 'discord.js';
|
||||||
import { I18n } from 'i18n';
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
import { joinVoiceChannelProcedure } from './Join';
|
import { joinVoiceChannelProcedure } from './Join';
|
||||||
|
|
||||||
import DiscordProvider from '../../providers/Discord';
|
import DiscordProvider from '../../providers/Discord';
|
||||||
import DiscordMusicPlayer, { ValidTracks } from '../../providers/DiscordMusicPlayer';
|
import DiscordMusicPlayer, { TrackUtils, ValidTracks } from '../../providers/DiscordMusicPlayer';
|
||||||
import Locale from '../../services/Locale';
|
import Locale from '../../services/Locale';
|
||||||
|
|
||||||
import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule';
|
import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule';
|
||||||
@@ -24,6 +25,7 @@ import {
|
|||||||
sendHybridInteractionMessageResponse,
|
sendHybridInteractionMessageResponse,
|
||||||
makeInfoEmbed
|
makeInfoEmbed
|
||||||
} from '../../utils/DiscordMessage';
|
} from '../../utils/DiscordMessage';
|
||||||
|
import { checkBotPermissionsInChannel } from '../../utils/DiscordPermission';
|
||||||
|
|
||||||
const EMBEDS = {
|
const EMBEDS = {
|
||||||
PLAY_INFO: (data: HybridInteractionMessage, locale: I18n) => {
|
PLAY_INFO: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
@@ -33,24 +35,25 @@ const EMBEDS = {
|
|||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: locale.__('common.available_args'),
|
name: locale.__('common.available_args'),
|
||||||
value: locale.__('musicplayer_play.valid_args'),
|
value: locale.__('musicplayer_play.valid_args')
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
user: data.getUser()
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
ADDED_QUEUE: (data: HybridInteractionMessage, locale: I18n, track: ValidTracks) => {
|
ADDED_QUEUE: async (data: HybridInteractionMessage, locale: I18n, track: ValidTracks) => {
|
||||||
|
|
||||||
|
const title = TrackUtils.getTitle(track);
|
||||||
|
const thumbnails = await TrackUtils.getThumbnails(track);
|
||||||
|
|
||||||
let embed = makeSuccessEmbed({
|
let embed = makeSuccessEmbed({
|
||||||
title: locale.__('musicplayer_play.queue_added_song'),
|
title: locale.__('musicplayer_play.queue_added_song'),
|
||||||
description: track.title,
|
description: title,
|
||||||
user: data.getUser()
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
|
|
||||||
const highestResolutionThumbnail = track.thumbnails.reduce((prev, current) =>
|
if (TrackUtils.getHighestResolutionThumbnail(thumbnails))
|
||||||
prev.height * prev.width > current.height * current.width ? prev : current
|
embed.setImage(TrackUtils.getHighestResolutionThumbnail(thumbnails).url);
|
||||||
);
|
|
||||||
|
|
||||||
if (highestResolutionThumbnail) embed.setImage(highestResolutionThumbnail.url);
|
|
||||||
|
|
||||||
return embed;
|
return embed;
|
||||||
},
|
},
|
||||||
@@ -158,6 +161,7 @@ export default class Play extends DiscordModule {
|
|||||||
await joinVoiceChannelProcedure(new HybridInteractionMessage(interaction), null, voiceChannel);
|
await joinVoiceChannelProcedure(new HybridInteractionMessage(interaction), null, voiceChannel);
|
||||||
|
|
||||||
let instance = DiscordMusicPlayer.getGuildInstance(guild.id);
|
let instance = DiscordMusicPlayer.getGuildInstance(guild.id);
|
||||||
|
if (!instance) return;
|
||||||
|
|
||||||
if (instance!.voiceChannel.id !== member.voice.channel.id)
|
if (instance!.voiceChannel.id !== member.voice.channel.id)
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
@@ -222,7 +226,8 @@ export default class Play extends DiscordModule {
|
|||||||
const voiceChannel = DiscordProvider.client.guilds.cache.get(guild.id)?.channels.cache.get(payload.d.v);
|
const voiceChannel = DiscordProvider.client.guilds.cache.get(guild.id)?.channels.cache.get(payload.d.v);
|
||||||
//let member = DiscordProvider.client.guilds.cache.get(guild.id)?.members.cache.get(user.id);
|
//let member = DiscordProvider.client.guilds.cache.get(guild.id)?.members.cache.get(user.id);
|
||||||
|
|
||||||
if (!voiceChannel || !(voiceChannel instanceof VoiceChannel || voiceChannel instanceof StageChannel)) return;
|
if (!voiceChannel || !(voiceChannel instanceof VoiceChannel || voiceChannel instanceof StageChannel))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!member.voice.channel)
|
if (!member.voice.channel)
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
@@ -235,11 +240,16 @@ export default class Play extends DiscordModule {
|
|||||||
await joinVoiceChannelProcedure(new HybridInteractionMessage(interaction), null, voiceChannel);
|
await joinVoiceChannelProcedure(new HybridInteractionMessage(interaction), null, voiceChannel);
|
||||||
|
|
||||||
let instance = DiscordMusicPlayer.getGuildInstance(guild.id);
|
let instance = DiscordMusicPlayer.getGuildInstance(guild.id);
|
||||||
|
if (!instance) return;
|
||||||
|
|
||||||
if (instance!.voiceChannel.id !== member.voice.channel.id)
|
if (instance!.voiceChannel.id !== member.voice.channel.id)
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
hybridData,
|
hybridData,
|
||||||
{ embeds: [EMBEDS.USER_NOT_IN_SAME_VOICECHANNEL(new HybridInteractionMessage(interaction), locale)] },
|
{
|
||||||
|
embeds: [
|
||||||
|
EMBEDS.USER_NOT_IN_SAME_VOICECHANNEL(new HybridInteractionMessage(interaction), locale)
|
||||||
|
]
|
||||||
|
},
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -265,7 +275,7 @@ export default class Play extends DiscordModule {
|
|||||||
instance.addTrackToQueue(result);
|
instance.addTrackToQueue(result);
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
hybridData,
|
hybridData,
|
||||||
{ embeds: [EMBEDS.ADDED_QUEUE(new HybridInteractionMessage(interaction), locale, result)] },
|
{ embeds: [await EMBEDS.ADDED_QUEUE(new HybridInteractionMessage(interaction), locale, result)] },
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -274,7 +284,7 @@ export default class Play extends DiscordModule {
|
|||||||
async run(data: HybridInteractionMessage, args: any) {
|
async run(data: HybridInteractionMessage, args: any) {
|
||||||
let query;
|
let query;
|
||||||
const guild = data.getGuild();
|
const guild = data.getGuild();
|
||||||
const channel = data.getChannel();
|
const channel = data.getGuildChannel();
|
||||||
const member = data.getMember();
|
const member = data.getMember();
|
||||||
|
|
||||||
if (!guild || !channel || !member) return;
|
if (!guild || !channel || !member) return;
|
||||||
@@ -286,8 +296,8 @@ export default class Play extends DiscordModule {
|
|||||||
return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.PLAY_INFO(data, locale)] });
|
return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.PLAY_INFO(data, locale)] });
|
||||||
|
|
||||||
query = args.join(' ');
|
query = args.join(' ');
|
||||||
} else if (data.isSlashCommand()) {
|
} else if (data.isApplicationCommand()) {
|
||||||
query = data.getSlashCommand().options.getString('query');
|
query = data.getSlashCommand().options.get('query', true).value?.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!query) return;
|
if (!query) return;
|
||||||
@@ -304,6 +314,7 @@ export default class Play extends DiscordModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let instance = DiscordMusicPlayer.getGuildInstance(guild.id);
|
let instance = DiscordMusicPlayer.getGuildInstance(guild.id);
|
||||||
|
if (!instance) return;
|
||||||
|
|
||||||
if (instance!.voiceChannel.id !== member.voice.channel.id)
|
if (instance!.voiceChannel.id !== member.voice.channel.id)
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
@@ -343,15 +354,15 @@ export default class Play extends DiscordModule {
|
|||||||
|
|
||||||
if (!result) return;
|
if (!result) return;
|
||||||
|
|
||||||
if (data.isMessage() && data.getMessage().embeds.length > 0) {
|
if (data.isMessage() && data.getMessage().embeds.length > 0 && await checkBotPermissionsInChannel({ guild, channel, permissions: [PermissionsBitField.Flags.ManageMessages]})) {
|
||||||
data.getMessage().suppressEmbeds(true);
|
data.getMessage().suppressEmbeds(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.addTrackToQueue(result);
|
instance.addTrackToQueue(result);
|
||||||
|
|
||||||
if (linkData.list) {
|
if (linkData.list) {
|
||||||
const row = new MessageActionRow().addComponents(
|
const row = new ActionRowBuilder<ButtonBuilder>().addComponents([
|
||||||
new MessageButton()
|
new ButtonBuilder()
|
||||||
.setEmoji('✅')
|
.setEmoji('✅')
|
||||||
.setCustomId(
|
.setCustomId(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
@@ -361,21 +372,70 @@ export default class Play extends DiscordModule {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
.setLabel(' Add the remaining songs in the playlist')
|
.setLabel(' Add the remaining songs in the playlist')
|
||||||
.setStyle('PRIMARY')
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.ADDED_QUEUE(data, locale, result)],
|
embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result)],
|
||||||
components: [row]
|
components: [row]
|
||||||
});
|
});
|
||||||
} else
|
} else
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.ADDED_QUEUE(data, locale, result)]
|
embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result)]
|
||||||
});
|
});
|
||||||
|
} else if (DiscordMusicPlayer.isSpotifyLink(query)) {
|
||||||
|
let linkData = DiscordMusicPlayer.parseSpotifyLink(query);
|
||||||
|
|
||||||
|
if (linkData.type === 'playlist' || linkData.type === 'album') {
|
||||||
|
let playlist = await DiscordMusicPlayer.getSpotifySongsInPlayList(query).catch((err) => {
|
||||||
|
sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.LOOKUP_ERROR(data, locale, err)] }, true);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!playlist) return;
|
||||||
|
const songs = await playlist.all_tracks();
|
||||||
|
|
||||||
|
for (const song of songs) {
|
||||||
|
instance.addTrackToQueue(song);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await sendHybridInteractionMessageResponse(
|
||||||
|
data,
|
||||||
|
{ embeds: [EMBEDS.ADDED_SONGS_QUEUE(data, locale, songs)] },
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = await DiscordMusicPlayer.searchSpotifyBySpotifyLink(linkData).catch((err) => {
|
||||||
|
sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.LOOKUP_ERROR(data, locale, err)] }, true);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result) return;
|
||||||
|
|
||||||
|
if (data.isMessage() && data.getMessage().embeds.length > 0 && await checkBotPermissionsInChannel({ guild, channel, permissions: [PermissionsBitField.Flags.ManageMessages]})) {
|
||||||
|
data.getMessage().suppressEmbeds(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.addTrackToQueue(result);
|
||||||
|
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result)]
|
||||||
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
let result = await DiscordMusicPlayer.searchYouTubeByQuery(query);
|
let result = await DiscordMusicPlayer.searchYouTubeByQuery(query);
|
||||||
|
|
||||||
if (!result) return;
|
if (!result) {
|
||||||
|
// TODO: Send not found embed
|
||||||
|
await sendHybridInteractionMessageResponse(
|
||||||
|
data,
|
||||||
|
{ embeds: [EMBEDS.LOOKUP_ERROR(data, locale, new Error('Cannot find that song'))] },
|
||||||
|
true
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
instance.addTrackToQueue(result[0]);
|
instance.addTrackToQueue(result[0]);
|
||||||
|
|
||||||
if (result.length > 1) {
|
if (result.length > 1) {
|
||||||
@@ -387,8 +447,8 @@ export default class Play extends DiscordModule {
|
|||||||
// The query length is too long to fit in json
|
// The query length is too long to fit in json
|
||||||
if (query.length > 100 - 51) return;
|
if (query.length > 100 - 51) return;
|
||||||
|
|
||||||
const row = new MessageActionRow().addComponents(
|
const row = new ActionRowBuilder<ButtonBuilder>().addComponents([
|
||||||
new MessageButton()
|
new ButtonBuilder()
|
||||||
.setEmoji('🔎')
|
.setEmoji('🔎')
|
||||||
.setCustomId(
|
.setCustomId(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
@@ -400,17 +460,17 @@ export default class Play extends DiscordModule {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
.setLabel(' Not this? Search!')
|
.setLabel(' Not this? Search!')
|
||||||
.setStyle('PRIMARY')
|
.setStyle(ButtonStyle.Primary)
|
||||||
);
|
]);
|
||||||
|
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.ADDED_QUEUE(data, locale, result[0])],
|
embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result[0])],
|
||||||
components: [row]
|
components: [row]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.ADDED_QUEUE(data, locale, result[0])]
|
embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result[0])]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,161 @@
|
|||||||
|
import { I18n } from "i18n";
|
||||||
|
import { Message, CommandInteraction, ActivityType, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
|
||||||
|
|
||||||
|
import DiscordMusicPlayer, { TrackUtils, ValidTracks } from "../../providers/DiscordMusicPlayer";
|
||||||
|
import Locale from "../../services/Locale";
|
||||||
|
|
||||||
|
import { makeSuccessEmbed, makeErrorEmbed, sendHybridInteractionMessageResponse } from "../../utils/DiscordMessage";
|
||||||
|
import DiscordModule, { HybridInteractionMessage } from "../../utils/DiscordModule";
|
||||||
|
import { joinVoiceChannelProcedure } from "./Join";
|
||||||
|
|
||||||
|
const EMBEDS = {
|
||||||
|
NOT_DETECTED: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeErrorEmbed({
|
||||||
|
title: locale.__('musicplayer_playmy.not_detected'),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
USER_NOT_IN_VOICECHANNEL: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeErrorEmbed({
|
||||||
|
title: locale.__('musicplayer.not_in_voice'),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
USER_NOT_IN_SAME_VOICECHANNEL: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeErrorEmbed({
|
||||||
|
title: locale.__('musicplayer.different_voice_channel'),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
ADDED_QUEUE: async (data: HybridInteractionMessage, locale: I18n, track: ValidTracks) => {
|
||||||
|
|
||||||
|
const title = TrackUtils.getTitle(track);
|
||||||
|
const thumbnails = await TrackUtils.getThumbnails(track);
|
||||||
|
|
||||||
|
let embed = makeSuccessEmbed({
|
||||||
|
title: locale.__('musicplayer_play.queue_added_song'),
|
||||||
|
description: title,
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
|
||||||
|
if (TrackUtils.getHighestResolutionThumbnail(thumbnails))
|
||||||
|
embed.setImage(TrackUtils.getHighestResolutionThumbnail(thumbnails).url);
|
||||||
|
|
||||||
|
return embed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class PlayMy extends DiscordModule {
|
||||||
|
|
||||||
|
public id = "Discord_MusicPlayer_PlayMy";
|
||||||
|
public commands = ["playmy"];
|
||||||
|
public commandInteractionName = "playmy";
|
||||||
|
|
||||||
|
async GuildOnModuleCommand(args: any, message: Message) {
|
||||||
|
await this.run(new HybridInteractionMessage(message), args);
|
||||||
|
}
|
||||||
|
|
||||||
|
async GuildModuleCommandInteractionCreate(interaction: CommandInteraction) {
|
||||||
|
await this.run(new HybridInteractionMessage(interaction), interaction.options);
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(data: HybridInteractionMessage, args: any) {
|
||||||
|
|
||||||
|
const guild = data.getGuild();
|
||||||
|
const member = data.getMember();
|
||||||
|
|
||||||
|
if(!guild || !member) return;
|
||||||
|
|
||||||
|
const locale = await Locale.getGuildLocale(guild.id);
|
||||||
|
|
||||||
|
if (!member.voice.channel)
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.USER_NOT_IN_VOICECHANNEL(data, locale)]
|
||||||
|
});
|
||||||
|
|
||||||
|
const voiceChannel = member.voice.channel;
|
||||||
|
|
||||||
|
if (!DiscordMusicPlayer.isGuildInstanceExists(guild.id)) {
|
||||||
|
await joinVoiceChannelProcedure(data, null, voiceChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
let instance = DiscordMusicPlayer.getGuildInstance(guild.id);
|
||||||
|
if (!instance) return;
|
||||||
|
|
||||||
|
if (instance!.voiceChannel.id !== member.voice.channel.id)
|
||||||
|
return await sendHybridInteractionMessageResponse(
|
||||||
|
data,
|
||||||
|
{ embeds: [EMBEDS.USER_NOT_IN_SAME_VOICECHANNEL(data, locale)] },
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!instance!.isConnected()) {
|
||||||
|
await joinVoiceChannelProcedure(data, instance!, voiceChannel);
|
||||||
|
instance = DiscordMusicPlayer.getGuildInstance(guild.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!instance) return;
|
||||||
|
if(!member.presence) return;
|
||||||
|
if(!member.presence.activities) return;
|
||||||
|
|
||||||
|
let query;
|
||||||
|
let found = false;
|
||||||
|
for (const activity of member.presence.activities) {
|
||||||
|
if(activity.type === ActivityType.Listening) {
|
||||||
|
if(!activity.details) continue;
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
if(activity.name == "Spotify")
|
||||||
|
query = `${activity.state} - ${activity.details}`
|
||||||
|
else
|
||||||
|
query = `${activity.state} - ${activity.details}` // TODO: Find better query formula
|
||||||
|
|
||||||
|
const result = await DiscordMusicPlayer.searchYouTubeByQuery(query);
|
||||||
|
if (!result) continue;
|
||||||
|
instance.addTrackToQueue(result[0]);
|
||||||
|
|
||||||
|
let row;
|
||||||
|
if (result.length > 1) {
|
||||||
|
// TODO: Find a better logic than this
|
||||||
|
// If the first result title is exact match with the query or first title contains half the space of the query, it's probably a sentence
|
||||||
|
// then we don't need to show the search results
|
||||||
|
// if(result[0].title === query || result[0].title && (Math.ceil((result[0].title.split(" ").length - 1) / 2) === Math.ceil((query.split(" ").length - 1) / 2))) return;
|
||||||
|
|
||||||
|
// The query length is too long to fit in json
|
||||||
|
if (query.length > 100 - 51) return;
|
||||||
|
|
||||||
|
row = new ActionRowBuilder<ButtonBuilder>().addComponents([
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setEmoji('🔎')
|
||||||
|
.setCustomId(
|
||||||
|
JSON.stringify({
|
||||||
|
m: 'MP_S',
|
||||||
|
a: 'search',
|
||||||
|
d: {
|
||||||
|
q: query
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.setLabel(' Not this? Search!')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!row)
|
||||||
|
await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result[0])]
|
||||||
|
});
|
||||||
|
else
|
||||||
|
await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result[0])],
|
||||||
|
components: [row]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found)
|
||||||
|
await sendHybridInteractionMessageResponse(data, { embeds:[EMBEDS.NOT_DETECTED(data, locale)] });
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,20 @@
|
|||||||
import { Message, CommandInteraction, Interaction, TextChannel } from 'discord.js';
|
import { Message, CommandInteraction } from 'discord.js';
|
||||||
import { I18n } from 'i18n';
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
import DiscordMusicPlayer, {
|
import DiscordMusicPlayer, {
|
||||||
DiscordMusicPlayerInstance,
|
DiscordMusicPlayerInstance,
|
||||||
DiscordMusicPlayerLoopMode
|
DiscordMusicPlayerLoopMode,
|
||||||
|
TrackUtils
|
||||||
} from '../../providers/DiscordMusicPlayer';
|
} from '../../providers/DiscordMusicPlayer';
|
||||||
import Locale from '../../services/Locale';
|
import Locale from '../../services/Locale';
|
||||||
|
|
||||||
import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule';
|
import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule';
|
||||||
import { makeErrorEmbed, sendHybridInteractionMessageResponse, makeInfoEmbed } from '../../utils/DiscordMessage';
|
import {
|
||||||
|
makeErrorEmbed,
|
||||||
|
sendHybridInteractionMessageResponse,
|
||||||
|
makeSuccessEmbed,
|
||||||
|
makeInfoEmbed
|
||||||
|
} from '../../utils/DiscordMessage';
|
||||||
|
|
||||||
const EMBEDS = {
|
const EMBEDS = {
|
||||||
QUEUE: (data: HybridInteractionMessage, locale: I18n, instance: DiscordMusicPlayerInstance) => {
|
QUEUE: (data: HybridInteractionMessage, locale: I18n, instance: DiscordMusicPlayerInstance) => {
|
||||||
@@ -25,45 +31,58 @@ const EMBEDS = {
|
|||||||
instance.getLoopMode() === DiscordMusicPlayerLoopMode.Current
|
instance.getLoopMode() === DiscordMusicPlayerLoopMode.Current
|
||||||
? ` ${locale.__('musicplayer_queue.looping_current')}`
|
? ` ${locale.__('musicplayer_queue.looping_current')}`
|
||||||
: ''
|
: ''
|
||||||
}: [${queue.track[0].title}](${queue.track[0].url})`;
|
}: [${TrackUtils.getTitle(queue.track[0])}](${queue.track[0].url})`;
|
||||||
|
|
||||||
|
let description;
|
||||||
if (queue.track.length == 1) {
|
if (queue.track.length == 1) {
|
||||||
let queueString = `1. [${queue.track[0].title}](${queue.track[0].url})`;
|
let queueString = `1. [${TrackUtils.getTitle(queue.track[0])}](${queue.track[0].url})`;
|
||||||
return makeInfoEmbed({
|
description = `${locale.__('musicplayer_queue.now_playing')}${nowPlayingText}\n
|
||||||
title: locale.__('musicplayer_queue.title'),
|
There are ${queue.track.length} song in the queue!\n${queueString}`;
|
||||||
description: `${locale.__('musicplayer_queue.now_playing')}${nowPlayingText}\n
|
|
||||||
There are ${queue.track.length} song in the queue!\n${queueString}`,
|
|
||||||
user: data.getUser()
|
|
||||||
});
|
|
||||||
} else if (queue.track.length >= 10) {
|
} else if (queue.track.length >= 10) {
|
||||||
const upcomingText = `[${queue.track[1].title}](${queue.track[1].url})`;
|
const upcomingText = `[${TrackUtils.getTitle(queue.track[1])}](${queue.track[1].url})`;
|
||||||
const first10 = queue.track.slice(0, 10);
|
const first10 = queue.track.slice(0, 10);
|
||||||
let queueString = first10
|
let queueString = first10
|
||||||
.map((track, index) => `${index + 1}. [${track.title}](${track.url})`)
|
.map((track, index) => `${index + 1}. [${TrackUtils.getTitle(track)}](${track.url})`)
|
||||||
.join('\n');
|
.join('\n');
|
||||||
return makeInfoEmbed({
|
description = `${locale.__('musicplayer_queue.now_playing')}${nowPlayingText}
|
||||||
title: locale.__('musicplayer_queue.title'),
|
|
||||||
description: `${locale.__('musicplayer_queue.now_playing')}${nowPlayingText}
|
|
||||||
${locale.__('musicplayer_queue.upcoming_song')} ${upcomingText}\n
|
${locale.__('musicplayer_queue.upcoming_song')} ${upcomingText}\n
|
||||||
${locale.__('musicplayer_queue.song_x_in_queue', { COUNT: queue.track.length.toString() })}
|
${locale.__('musicplayer_queue.song_x_in_queue', { COUNT: queue.track.length.toString() })}
|
||||||
${queueString}\n${queue.track.length > 10 ? `...${queue.track.length - 10} more songs` : ''}`,
|
${queueString}\n${queue.track.length > 10 ? `...${queue.track.length - 10} more songs` : ''}`;
|
||||||
user: data.getUser()
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
const upcomingText = `[${queue.track[1].title}](${queue.track[1].url})`;
|
const upcomingText = `[${TrackUtils.getTitle(queue.track[1])}](${queue.track[1].url})`;
|
||||||
const queueString = queue.track
|
const queueString = queue.track
|
||||||
.map((track, index) => `${index + 1}. [${track.title}](${track.url})`)
|
.map((track, index) => `${index + 1}. [${TrackUtils.getTitle(track)}](${track.url})`)
|
||||||
.join('\n');
|
.join('\n');
|
||||||
return makeInfoEmbed({
|
description = `${locale.__('musicplayer_queue.now_playing')}${nowPlayingText}
|
||||||
title: locale.__('musicplayer_queue.title'),
|
|
||||||
description: `${locale.__('musicplayer_queue.now_playing')}${nowPlayingText}
|
|
||||||
${locale.__('musicplayer_queue.upcoming_song')} ${upcomingText}\n
|
${locale.__('musicplayer_queue.upcoming_song')} ${upcomingText}\n
|
||||||
${locale.__('musicplayer_queue.song_x_in_queue', { COUNT: queue.track.length.toString() })}
|
${locale.__('musicplayer_queue.song_x_in_queue', { COUNT: queue.track.length.toString() })}
|
||||||
${queueString}`,
|
${queueString}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return makeInfoEmbed({
|
||||||
|
title: locale.__('musicplayer_queue.title'),
|
||||||
|
description: description,
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: locale.__('common.available_args'),
|
||||||
|
value: locale.__('musicplayer_queue.valid_args')
|
||||||
|
}
|
||||||
|
],
|
||||||
user: data.getUser()
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
QUEUE_CLEARED: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeSuccessEmbed({
|
||||||
|
title: locale.__('musicplayer_queue.cleared'),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
QUEUE_SHUFFLED: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeSuccessEmbed({
|
||||||
|
title: locale.__('musicplayer_queue.shuffled'),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
},
|
},
|
||||||
NO_MUSIC_PLAYING: (data: HybridInteractionMessage, locale: I18n) => {
|
NO_MUSIC_PLAYING: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
@@ -88,9 +107,9 @@ export default class QueueCommand extends DiscordModule {
|
|||||||
|
|
||||||
async run(data: HybridInteractionMessage, args: any) {
|
async run(data: HybridInteractionMessage, args: any) {
|
||||||
const guild = data.getGuild();
|
const guild = data.getGuild();
|
||||||
|
|
||||||
if (!guild) return;
|
if (!guild) return;
|
||||||
|
|
||||||
|
let query;
|
||||||
const locale = await Locale.getGuildLocale(guild.id);
|
const locale = await Locale.getGuildLocale(guild.id);
|
||||||
|
|
||||||
const instance = DiscordMusicPlayer.getGuildInstance(guild.id);
|
const instance = DiscordMusicPlayer.getGuildInstance(guild.id);
|
||||||
@@ -99,8 +118,25 @@ export default class QueueCommand extends DiscordModule {
|
|||||||
embeds: [EMBEDS.NO_MUSIC_PLAYING(data, locale)]
|
embeds: [EMBEDS.NO_MUSIC_PLAYING(data, locale)]
|
||||||
});
|
});
|
||||||
|
|
||||||
await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.QUEUE(data, locale, instance)] });
|
if (data.isMessage()) {
|
||||||
|
if (args.length === 0)
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.QUEUE(data, locale, instance)]
|
||||||
|
});
|
||||||
|
|
||||||
return;
|
query = args.join(' ');
|
||||||
|
} else if (data.isApplicationCommand()) {
|
||||||
|
//query = data.getSlashCommand().options.get('query', true).value?.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query) return;
|
||||||
|
switch (query.toLowerCase()) {
|
||||||
|
case 'clear':
|
||||||
|
instance.clearQueue();
|
||||||
|
return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.QUEUE_CLEARED(data, locale)] });
|
||||||
|
case 'shuffle':
|
||||||
|
instance.shuffleQueue();
|
||||||
|
return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.QUEUE_SHUFFLED(data, locale)] });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Message, CommandInteraction, Interaction } from "discord.js";
|
import { Message, CommandInteraction, Interaction } from "discord.js";
|
||||||
import { I18n } from "i18n";
|
import { I18n } from "i18n";
|
||||||
|
|
||||||
import DiscordProvider from "../../providers/Discord";
|
|
||||||
import DiscordMusicPlayer from "../../providers/DiscordMusicPlayer";
|
import DiscordMusicPlayer from "../../providers/DiscordMusicPlayer";
|
||||||
|
|
||||||
import DiscordModule, { HybridInteractionMessage } from "../../utils/DiscordModule";
|
import DiscordModule, { HybridInteractionMessage } from "../../utils/DiscordModule";
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { Message, CommandInteraction, Interaction, MessageActionRow, ButtonInteraction, MessageSelectMenu, MessageSelectOptionData } from "discord.js";
|
import { Message, CommandInteraction, ActionRowBuilder, ButtonInteraction, SelectMenuBuilder, SelectMenuComponentOptionData } from "discord.js";
|
||||||
import { I18n } from "i18n";
|
import { I18n } from "i18n";
|
||||||
|
|
||||||
import { joinVoiceChannelProcedure } from "./Join";
|
import { joinVoiceChannelProcedure } from "./Join";
|
||||||
|
|
||||||
import DiscordMusicPlayer, { ValidTracks } from "../../providers/DiscordMusicPlayer";
|
import DiscordMusicPlayer, { TrackUtils, ValidTracks } from "../../providers/DiscordMusicPlayer";
|
||||||
import Locale from "../../services/Locale";
|
import Locale from "../../services/Locale";
|
||||||
|
|
||||||
import DiscordModule, { HybridInteractionMessage } from "../../utils/DiscordModule";
|
import DiscordModule, { HybridInteractionMessage } from "../../utils/DiscordModule";
|
||||||
import { makeErrorEmbed, makeSuccessEmbed, sendHybridInteractionMessageResponse, makeInfoEmbed } from "../../utils/DiscordMessage";
|
import { makeErrorEmbed, sendHybridInteractionMessageResponse, makeInfoEmbed } from "../../utils/DiscordMessage";
|
||||||
|
|
||||||
const EMBEDS = {
|
const EMBEDS = {
|
||||||
SEARCH_INFO: (data: HybridInteractionMessage, locale: I18n) => {
|
SEARCH_INFO: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
@@ -28,7 +28,7 @@ const EMBEDS = {
|
|||||||
title: locale.__('musicplayer_search.title_result'),
|
title: locale.__('musicplayer_search.title_result'),
|
||||||
description: `${locale.__('musicplayer_search.x_results_found', {
|
description: `${locale.__('musicplayer_search.x_results_found', {
|
||||||
COUNT: result.length.toString()
|
COUNT: result.length.toString()
|
||||||
})}\n\n${result.map(track => `- [${track.title}](${track.url})`).join('\n')}`,
|
})}\n\n${result.map(track => `- [${TrackUtils.getTitle(track)}](${track.url})`).join('\n')}`,
|
||||||
user: data.getUser()
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -96,8 +96,8 @@ export default class Search extends DiscordModule {
|
|||||||
|
|
||||||
query = args.join(' ');
|
query = args.join(' ');
|
||||||
}
|
}
|
||||||
else if (data.isSlashCommand())
|
else if (data.isApplicationCommand())
|
||||||
query = data.getSlashCommand().options.getString('query');
|
query = data.getSlashCommand().options.get('query', true).value?.toString();
|
||||||
else if (data.isButton())
|
else if (data.isButton())
|
||||||
query = args;
|
query = args;
|
||||||
|
|
||||||
@@ -126,9 +126,9 @@ export default class Search extends DiscordModule {
|
|||||||
let result = await DiscordMusicPlayer.searchYouTubeByQuery(query);
|
let result = await DiscordMusicPlayer.searchYouTubeByQuery(query);
|
||||||
if (!result) return; // TODO: Handle when search returned nothing
|
if (!result) return; // TODO: Handle when search returned nothing
|
||||||
|
|
||||||
const menuOptions: MessageSelectOptionData[] = [];
|
const menuOptions: SelectMenuComponentOptionData[] = [];
|
||||||
|
|
||||||
const messageSelectMenu = new MessageSelectMenu();
|
const messageSelectMenu = new SelectMenuBuilder();
|
||||||
/*
|
/*
|
||||||
Discord have 100 char custom id char limit
|
Discord have 100 char custom id char limit
|
||||||
So we need to shorten our json.
|
So we need to shorten our json.
|
||||||
@@ -157,8 +157,8 @@ export default class Search extends DiscordModule {
|
|||||||
|
|
||||||
messageSelectMenu.addOptions(menuOptions);
|
messageSelectMenu.addOptions(menuOptions);
|
||||||
|
|
||||||
const row = new MessageActionRow();
|
const row = new ActionRowBuilder<SelectMenuBuilder>();
|
||||||
row.addComponents(messageSelectMenu);
|
row.addComponents([messageSelectMenu]);
|
||||||
|
|
||||||
return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.SEARCH_RESULT(data, locale, result)], components: [row] });
|
return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.SEARCH_RESULT(data, locale, result)], components: [row] });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import DiscordModule, { HybridInteractionMessage } from "../../utils/DiscordModule";
|
import DiscordModule, { HybridInteractionMessage } from "../../utils/DiscordModule";
|
||||||
|
|
||||||
import { Message, CommandInteraction, Interaction } from "discord.js";
|
import { Message, CommandInteraction } from "discord.js";
|
||||||
import { makeSuccessEmbed, makeErrorEmbed, sendHybridInteractionMessageResponse } from "../../utils/DiscordMessage";
|
import { makeSuccessEmbed, makeErrorEmbed, sendHybridInteractionMessageResponse } from "../../utils/DiscordMessage";
|
||||||
import DiscordProvider from "../../providers/Discord";
|
|
||||||
import DiscordMusicPlayer from "../../providers/DiscordMusicPlayer";
|
import DiscordMusicPlayer from "../../providers/DiscordMusicPlayer";
|
||||||
import { I18n } from "i18n";
|
import { I18n } from "i18n";
|
||||||
import Locale from "../../services/Locale";
|
import Locale from "../../services/Locale";
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
import { CommandInteraction, Message, Interaction } from 'discord.js';
|
import { CommandInteraction, Message } from 'discord.js';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
import NodePing from 'ping';
|
import NodePing from 'ping';
|
||||||
import { Promise } from 'bluebird';
|
import { Promise } from 'bluebird';
|
||||||
@@ -123,7 +123,7 @@ export default class Ping extends DiscordModule {
|
|||||||
}`
|
}`
|
||||||
);
|
);
|
||||||
|
|
||||||
if (data.isSlashCommand())
|
if (data.isApplicationCommand())
|
||||||
return await data
|
return await data
|
||||||
.getMessageComponentInteraction()
|
.getMessageComponentInteraction()
|
||||||
.editReply({ embeds: [EMBEDS.PING_INFO(data, locale, finalString.join('\n'))] });
|
.editReply({ embeds: [EMBEDS.PING_INFO(data, locale, finalString.join('\n'))] });
|
||||||
|
|||||||
+8
-8
@@ -1,4 +1,4 @@
|
|||||||
import { Message, Permissions, Interaction, CommandInteraction } from 'discord.js';
|
import { Message, CommandInteraction, PermissionsBitField } from 'discord.js';
|
||||||
import { I18n } from 'i18n';
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
import DiscordModule, { HybridInteractionMessage } from '../utils/DiscordModule';
|
import DiscordModule, { HybridInteractionMessage } from '../utils/DiscordModule';
|
||||||
@@ -78,9 +78,9 @@ export default class Say extends DiscordModule {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
!message.member.permissions.has([
|
!message.member.permissions.has([
|
||||||
Permissions.FLAGS.VIEW_CHANNEL,
|
PermissionsBitField.Flags.ViewChannel,
|
||||||
Permissions.FLAGS.SEND_MESSAGES,
|
PermissionsBitField.Flags.SendMessages,
|
||||||
Permissions.FLAGS.MANAGE_CHANNELS
|
PermissionsBitField.Flags.ManageChannels,
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
@@ -93,22 +93,22 @@ export default class Say extends DiscordModule {
|
|||||||
});
|
});
|
||||||
|
|
||||||
query = args.join(' ');
|
query = args.join(' ');
|
||||||
} else if (data.isSlashCommand()) {
|
} else if (data.isApplicationCommand()) {
|
||||||
const interaction = data.getSlashCommand();
|
const interaction = data.getSlashCommand();
|
||||||
if (
|
if (
|
||||||
!data
|
!data
|
||||||
.getGuild()!
|
.getGuild()!
|
||||||
.members.cache.get(interaction.user.id)
|
.members.cache.get(interaction.user.id)
|
||||||
?.permissions.has([Permissions.FLAGS.ADMINISTRATOR])
|
?.permissions.has([PermissionsBitField.Flags.Administrator])
|
||||||
)
|
)
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.NO_PERMISSION(data, locale)]
|
embeds: [EMBEDS.NO_PERMISSION(data, locale)]
|
||||||
});
|
});
|
||||||
|
|
||||||
query = interaction.options.getString('message');
|
query = interaction.options.get('message', true).value?.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.isSlashCommand() && data.getChannel()) {
|
if (data.isApplicationCommand() && data.getChannel()) {
|
||||||
try {
|
try {
|
||||||
await data.getChannel()!.send({ content: query });
|
await data.getChannel()!.send({ content: query });
|
||||||
await data
|
await data
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
import { Guild, PermissionsBitField } from 'discord.js';
|
||||||
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
|
import Prisma from '../../providers/Prisma';
|
||||||
|
import Cache from '../../providers/Cache';
|
||||||
|
|
||||||
|
import { HybridInteractionMessage } from '../../utils/DiscordModule';
|
||||||
|
import {
|
||||||
|
makeInfoEmbed,
|
||||||
|
makeErrorEmbed,
|
||||||
|
makeSuccessEmbed,
|
||||||
|
sendHybridInteractionMessageResponse
|
||||||
|
} from '../../utils/DiscordMessage';
|
||||||
|
|
||||||
|
import { COMMON_EMBEDS } from '.';
|
||||||
|
import Locale from '../../providers/Locale';
|
||||||
|
import { checkMemberPermissionsInGuild } from '../../utils/DiscordPermission';
|
||||||
|
|
||||||
|
const EMBEDS = {
|
||||||
|
LANGUAGE_INFO: (data: HybridInteractionMessage, locale: I18n, currentLocale: string) => {
|
||||||
|
return makeInfoEmbed({
|
||||||
|
title: locale.__('settings_language.info', { LANGUAGE: currentLocale }),
|
||||||
|
description: locale.__('settings_language.info_description', {
|
||||||
|
LANGUAGES: Locale.getLocaleProvider('en').getLocales().join(', ')
|
||||||
|
}),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
LANGUAGE_INVALID: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeErrorEmbed({
|
||||||
|
title: locale.__('settings_language.language_invalid'),
|
||||||
|
description: locale.__('settings_language.language_invalid_description'),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
LANGUAGE_UPDATED: (data: HybridInteractionMessage, locale: I18n, newLanguage: string) => {
|
||||||
|
return makeSuccessEmbed({
|
||||||
|
title: locale.__({ phrase: 'settings_language.language_updated', locale: newLanguage }),
|
||||||
|
description: locale.__(
|
||||||
|
{ phrase: 'settings_language.language_updated_description', locale: newLanguage },
|
||||||
|
{ LANGUAGE: newLanguage }
|
||||||
|
),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async (data: HybridInteractionMessage, args: any, guild: Guild, locale: I18n) => {
|
||||||
|
let member = data.getMember();
|
||||||
|
if (!member) return;
|
||||||
|
|
||||||
|
const GuildCache = await Cache.getCachedGuild(guild.id);
|
||||||
|
if (!GuildCache) return;
|
||||||
|
const language = GuildCache.locale;
|
||||||
|
|
||||||
|
if (!(await checkMemberPermissionsInGuild({ member, data, locale, permissions: [PermissionsBitField.Flags.ManageGuild] })))
|
||||||
|
return;
|
||||||
|
|
||||||
|
let newLanguage: string | null | undefined;
|
||||||
|
if (data.isMessage()) {
|
||||||
|
let _name: string;
|
||||||
|
if (typeof args[1] === 'undefined')
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.LANGUAGE_INFO(data, locale, language)]
|
||||||
|
});
|
||||||
|
|
||||||
|
let __name = args;
|
||||||
|
__name.shift();
|
||||||
|
_name = __name.join(' ');
|
||||||
|
newLanguage = _name;
|
||||||
|
} else if (data.isApplicationCommand())
|
||||||
|
newLanguage = data.getSlashCommand().options.get('language', true).value?.toString();
|
||||||
|
|
||||||
|
if (!newLanguage)
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.LANGUAGE_INFO(data, locale, language)]
|
||||||
|
});
|
||||||
|
|
||||||
|
newLanguage = newLanguage.toLowerCase();
|
||||||
|
|
||||||
|
if (!Locale.getLocaleProvider('en').getLocales().includes(newLanguage))
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.LANGUAGE_INVALID(data, locale)]
|
||||||
|
});
|
||||||
|
|
||||||
|
let placeholder: HybridInteractionMessage | undefined;
|
||||||
|
|
||||||
|
let _placeholder = await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [COMMON_EMBEDS.PROCESSING(data, locale)]
|
||||||
|
});
|
||||||
|
if (_placeholder) placeholder = new HybridInteractionMessage(_placeholder);
|
||||||
|
|
||||||
|
await Prisma.client.guild.update({
|
||||||
|
where: { id: guild.id },
|
||||||
|
data: { locale: newLanguage }
|
||||||
|
});
|
||||||
|
Cache.updateGuildCache(guild.id);
|
||||||
|
|
||||||
|
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
||||||
|
return placeholder.getMessage().edit({ embeds: [EMBEDS.LANGUAGE_UPDATED(data, locale, newLanguage)] });
|
||||||
|
else if (data.isApplicationCommand())
|
||||||
|
return await sendHybridInteractionMessageResponse(
|
||||||
|
data,
|
||||||
|
{ embeds: [EMBEDS.LANGUAGE_UPDATED(data, locale, newLanguage)] },
|
||||||
|
true
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Permissions, Guild } from 'discord.js';
|
import { Guild, PermissionsBitField } from 'discord.js';
|
||||||
import { I18n } from 'i18n';
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
import DiscordProvider from '../../providers/Discord';
|
import DiscordProvider from '../../providers/Discord';
|
||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
} from '../../utils/DiscordMessage';
|
} from '../../utils/DiscordMessage';
|
||||||
|
|
||||||
import { COMMON_EMBEDS } from '.';
|
import { COMMON_EMBEDS } from '.';
|
||||||
|
import { checkMemberPermissionsInGuild } from '../../utils/DiscordPermission';
|
||||||
|
|
||||||
const EMBEDS = {
|
const EMBEDS = {
|
||||||
PREFIX_INFO: (data: HybridInteractionMessage, locale: I18n, currentPrefix: string) => {
|
PREFIX_INFO: (data: HybridInteractionMessage, locale: I18n, currentPrefix: string) => {
|
||||||
@@ -54,10 +55,8 @@ export default async (data: HybridInteractionMessage, args: any, guild: Guild, l
|
|||||||
if (!GuildCache) return;
|
if (!GuildCache) return;
|
||||||
const prefix = GuildCache.prefix;
|
const prefix = GuildCache.prefix;
|
||||||
|
|
||||||
if (!member.permissions.has([Permissions.FLAGS.ADMINISTRATOR]))
|
if (!(await checkMemberPermissionsInGuild({ member, data, locale, permissions: [PermissionsBitField.Flags.ManageGuild] })))
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return;
|
||||||
embeds: [COMMON_EMBEDS.NO_PERMISSION(data, locale)]
|
|
||||||
});
|
|
||||||
|
|
||||||
let newPrefix: string | null | undefined;
|
let newPrefix: string | null | undefined;
|
||||||
if (data.isMessage()) {
|
if (data.isMessage()) {
|
||||||
@@ -71,7 +70,7 @@ export default async (data: HybridInteractionMessage, args: any, guild: Guild, l
|
|||||||
__name.shift();
|
__name.shift();
|
||||||
_name = __name.join(' ');
|
_name = __name.join(' ');
|
||||||
newPrefix = _name;
|
newPrefix = _name;
|
||||||
} else if (data.isSlashCommand()) newPrefix = data.getSlashCommand().options.getString('prefix');
|
} else if (data.isApplicationCommand()) newPrefix = data.getSlashCommand().options.get('prefix', true).value?.toString();
|
||||||
|
|
||||||
if (!newPrefix)
|
if (!newPrefix)
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
@@ -103,7 +102,7 @@ export default async (data: HybridInteractionMessage, args: any, guild: Guild, l
|
|||||||
|
|
||||||
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
||||||
return placeholder.getMessage().edit({ embeds: [EMBEDS.PREFIX_UPDATED(data, locale, newPrefix)] });
|
return placeholder.getMessage().edit({ embeds: [EMBEDS.PREFIX_UPDATED(data, locale, newPrefix)] });
|
||||||
else if (data.isSlashCommand())
|
else if (data.isApplicationCommand())
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
data,
|
data,
|
||||||
{ embeds: [EMBEDS.PREFIX_UPDATED(data, locale, newPrefix)] },
|
{ embeds: [EMBEDS.PREFIX_UPDATED(data, locale, newPrefix)] },
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Permissions, Guild, GuildChannel, ThreadChannel, Message } from 'discord.js';
|
import { Guild, GuildChannel, ThreadChannel, Message, PermissionsBitField } from 'discord.js';
|
||||||
import { I18n } from 'i18n';
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
import DiscordProvider from '../../providers/Discord';
|
|
||||||
import Prisma from '../../providers/Prisma';
|
import Prisma from '../../providers/Prisma';
|
||||||
import Cache from '../../providers/Cache';
|
import Cache from '../../providers/Cache';
|
||||||
|
|
||||||
@@ -14,6 +13,7 @@ import {
|
|||||||
} from '../../utils/DiscordMessage';
|
} from '../../utils/DiscordMessage';
|
||||||
|
|
||||||
import { COMMON_EMBEDS } from '.';
|
import { COMMON_EMBEDS } from '.';
|
||||||
|
import { checkMemberPermissionsInGuild } from '../../utils/DiscordPermission';
|
||||||
|
|
||||||
const EMBEDS = {
|
const EMBEDS = {
|
||||||
SERVICE_ANNOUNCEMENT_INVALID_STATUS: (data: HybridInteractionMessage, locale: I18n) => {
|
SERVICE_ANNOUNCEMENT_INVALID_STATUS: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
@@ -104,10 +104,8 @@ export const setEnableServiceAnnouncement = async (
|
|||||||
let member = data.getMember();
|
let member = data.getMember();
|
||||||
if (!member) return;
|
if (!member) return;
|
||||||
|
|
||||||
if (!member.permissions.has([Permissions.FLAGS.ADMINISTRATOR]))
|
if (!(await checkMemberPermissionsInGuild({ member, data, locale, permissions: [PermissionsBitField.Flags.Administrator] })))
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return;
|
||||||
embeds: [COMMON_EMBEDS.NO_PERMISSION(data, locale)]
|
|
||||||
});
|
|
||||||
|
|
||||||
let GuildCache = await Cache.getCachedGuild(guild.id);
|
let GuildCache = await Cache.getCachedGuild(guild.id);
|
||||||
if(!GuildCache) return;
|
if(!GuildCache) return;
|
||||||
@@ -124,7 +122,7 @@ export const setEnableServiceAnnouncement = async (
|
|||||||
__name.shift();
|
__name.shift();
|
||||||
_name = __name.join(' ');
|
_name = __name.join(' ');
|
||||||
newStatus = _name;
|
newStatus = _name;
|
||||||
} else if (data.isSlashCommand()) newStatus = data.getSlashCommand().options.getString('status')!;
|
} else if (data.isApplicationCommand()) newStatus = data.getSlashCommand().options.get('status', true).value?.toString();
|
||||||
|
|
||||||
if (!newStatus)
|
if (!newStatus)
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
@@ -165,7 +163,7 @@ export const setEnableServiceAnnouncement = async (
|
|||||||
return await (placeholder as Message).edit({
|
return await (placeholder as Message).edit({
|
||||||
embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_STATUS_UPDATED(data, locale, newStatusBool)]
|
embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_STATUS_UPDATED(data, locale, newStatusBool)]
|
||||||
});
|
});
|
||||||
else if (data.isSlashCommand())
|
else if (data.isApplicationCommand())
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
data,
|
data,
|
||||||
{
|
{
|
||||||
@@ -184,10 +182,8 @@ export const setServiceAnnouncementChannel = async (
|
|||||||
let member = data.getMember();
|
let member = data.getMember();
|
||||||
if (!member) return;
|
if (!member) return;
|
||||||
|
|
||||||
if (!member.permissions.has([Permissions.FLAGS.ADMINISTRATOR]))
|
if (!(await checkMemberPermissionsInGuild({ member, data, locale, permissions: [PermissionsBitField.Flags.Administrator] })))
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return;
|
||||||
embeds: [COMMON_EMBEDS.NO_PERMISSION(data, locale)]
|
|
||||||
});
|
|
||||||
|
|
||||||
let channel;
|
let channel;
|
||||||
if (data.isMessage()) {
|
if (data.isMessage()) {
|
||||||
@@ -196,7 +192,7 @@ export const setServiceAnnouncementChannel = async (
|
|||||||
embeds: [EMBEDS.NO_CHANNEL_MENTIONED(data, locale)]
|
embeds: [EMBEDS.NO_CHANNEL_MENTIONED(data, locale)]
|
||||||
});
|
});
|
||||||
channel = data.getMessage().mentions.channels.first();
|
channel = data.getMessage().mentions.channels.first();
|
||||||
} else if (data.isSlashCommand()) channel = data.getSlashCommand().options.getChannel('channel');
|
} else if (data.isApplicationCommand()) channel = data.getSlashCommand().options.get('channel', true).channel;
|
||||||
|
|
||||||
if (!channel)
|
if (!channel)
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
@@ -211,16 +207,14 @@ export const setServiceAnnouncementChannel = async (
|
|||||||
embeds: [EMBEDS.INVALID_CHANNEL_THREAD(data, locale, TargetChannel)]
|
embeds: [EMBEDS.INVALID_CHANNEL_THREAD(data, locale, TargetChannel)]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!TargetChannel.isText())
|
if (!TargetChannel.isTextBased())
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.INVALID_CHANNEL(data, locale, TargetChannel)]
|
embeds: [EMBEDS.INVALID_CHANNEL(data, locale, TargetChannel)]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!data
|
!data.getGuild()?.members.me?.permissionsIn(TargetChannel)
|
||||||
.getGuild()!
|
.has([PermissionsBitField.Flags.SendMessages, PermissionsBitField.Flags.ViewChannel])
|
||||||
.me?.permissionsIn(TargetChannel)
|
|
||||||
.has([Permissions.FLAGS.SEND_MESSAGES, Permissions.FLAGS.VIEW_CHANNEL])
|
|
||||||
)
|
)
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.BOT_NO_PERMISSION(data, locale, TargetChannel)]
|
embeds: [EMBEDS.BOT_NO_PERMISSION(data, locale, TargetChannel)]
|
||||||
@@ -239,7 +233,7 @@ export const setServiceAnnouncementChannel = async (
|
|||||||
return await (placeholder as Message).edit({
|
return await (placeholder as Message).edit({
|
||||||
embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_CONFIGURED_CHANNEL(data, locale, TargetChannel)]
|
embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_CONFIGURED_CHANNEL(data, locale, TargetChannel)]
|
||||||
});
|
});
|
||||||
else if (data.isSlashCommand())
|
else if (data.isApplicationCommand())
|
||||||
return await sendHybridInteractionMessageResponse(
|
return await sendHybridInteractionMessageResponse(
|
||||||
data,
|
data,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,36 +1,49 @@
|
|||||||
import {
|
import {
|
||||||
Message,
|
Message,
|
||||||
Interaction,
|
|
||||||
CommandInteraction,
|
CommandInteraction,
|
||||||
Permissions,
|
Guild,
|
||||||
ThreadChannel,
|
PermissionsBitField,
|
||||||
GuildChannel,
|
PermissionResolvable
|
||||||
Guild
|
|
||||||
} from 'discord.js';
|
} from 'discord.js';
|
||||||
import { I18n } from 'i18n';
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
import DiscordProvider from '../../providers/Discord';
|
import DiscordProvider from '../../providers/Discord';
|
||||||
import Prisma from '../../providers/Prisma';
|
|
||||||
import Cache from '../../providers/Cache';
|
|
||||||
import Locale from '../../services/Locale';
|
import Locale from '../../services/Locale';
|
||||||
|
|
||||||
import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule';
|
import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule';
|
||||||
import {
|
import {
|
||||||
makeInfoEmbed,
|
makeInfoEmbed,
|
||||||
makeErrorEmbed,
|
makeErrorEmbed,
|
||||||
makeSuccessEmbed,
|
|
||||||
makeProcessingEmbed,
|
makeProcessingEmbed,
|
||||||
sendHybridInteractionMessageResponse
|
sendHybridInteractionMessageResponse
|
||||||
} from '../../utils/DiscordMessage';
|
} from '../../utils/DiscordMessage';
|
||||||
|
|
||||||
import * as PrefixModule from './Prefix';
|
import * as PrefixModule from './Prefix';
|
||||||
|
import * as LanguageModule from './Language';
|
||||||
import * as ServiceAnnouncementModule from './ServiceAnnouncement';
|
import * as ServiceAnnouncementModule from './ServiceAnnouncement';
|
||||||
|
|
||||||
export const COMMON_EMBEDS = {
|
export const COMMON_EMBEDS = {
|
||||||
NO_PERMISSION: (data: HybridInteractionMessage, locale: I18n) => {
|
MEMBER_NO_PERMISSION: (data: HybridInteractionMessage, locale: I18n, permissions: PermissionResolvable[]) => {
|
||||||
|
|
||||||
|
let allPermissions = [];
|
||||||
|
for(const value of permissions) {
|
||||||
|
allPermissions.push(new PermissionsBitField(value).toArray());
|
||||||
|
}
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: locale.__('common.no_permissions'),
|
title: locale.__('common.member_no_permissions'),
|
||||||
description: locale.__('common.no_permissions_description', { PERMISSIONS: 'ADMINISTRATOR'}),
|
description: locale.__('common.member_no_permissions_description', { PERMISSIONS: allPermissions.join(', ')}),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
BOT_NO_PERMISSION: (data: HybridInteractionMessage, locale: I18n, permissions: PermissionResolvable[]) => {
|
||||||
|
|
||||||
|
let allPermissions = [];
|
||||||
|
for(const value of permissions) {
|
||||||
|
allPermissions.push(new PermissionsBitField(value).toArray());
|
||||||
|
}
|
||||||
|
return makeErrorEmbed({
|
||||||
|
title: locale.__('common.bot_no_permissions'),
|
||||||
|
description: locale.__('common.bot_no_permissions_description', { PERMISSIONS: allPermissions.join(', ')}),
|
||||||
user: data.getUser()
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -91,7 +104,7 @@ export default class Settings extends DiscordModule {
|
|||||||
});
|
});
|
||||||
|
|
||||||
query = args[0].toLowerCase();
|
query = args[0].toLowerCase();
|
||||||
} else if (data.isSlashCommand()) {
|
} else if (data.isApplicationCommand()) {
|
||||||
query = args.getSubcommand();
|
query = args.getSubcommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,6 +115,8 @@ export default class Settings extends DiscordModule {
|
|||||||
});
|
});
|
||||||
case 'prefix':
|
case 'prefix':
|
||||||
return await PrefixModule.default(data, args, guild, locale);
|
return await PrefixModule.default(data, args, guild, locale);
|
||||||
|
case 'language':
|
||||||
|
return await LanguageModule.default(data, args, guild, locale);
|
||||||
case 'enableserviceannouncement':
|
case 'enableserviceannouncement':
|
||||||
return await ServiceAnnouncementModule.setEnableServiceAnnouncement(data, args, guild, locale);
|
return await ServiceAnnouncementModule.setEnableServiceAnnouncement(data, args, guild, locale);
|
||||||
case 'serviceannouncementchannel':
|
case 'serviceannouncementchannel':
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
import { Message, CommandInteraction } from 'discord.js';
|
||||||
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
|
import Environment from '../providers/Environment';
|
||||||
|
import DiscordProvider from '../providers/Discord';
|
||||||
|
import Locale from '../services/Locale';
|
||||||
|
|
||||||
|
import DiscordModule, { HybridInteractionMessage } from '../utils/DiscordModule';
|
||||||
|
import { sendHybridInteractionMessageResponse, makeInfoEmbed } from '../utils/DiscordMessage';
|
||||||
|
|
||||||
|
const EMBEDS = {
|
||||||
|
SUPPORT_INFO: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
const user = data.getUser();
|
||||||
|
let message;
|
||||||
|
if (Environment.get().SUPPORT_URL)
|
||||||
|
message = locale.__('support.info', { BOT_NAME: DiscordProvider.client.user!.username, LINK: Environment.get().SUPPORT_URL});
|
||||||
|
|
||||||
|
return makeInfoEmbed({
|
||||||
|
title: locale.__('support.title'),
|
||||||
|
description: message || locale.__('support.not_available', { BOT_NAME: DiscordProvider.client.user!.username}),
|
||||||
|
user
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class Support extends DiscordModule {
|
||||||
|
public id: string = 'Discord_Support';
|
||||||
|
public commands = ['support'];
|
||||||
|
public commandInteractionName = 'support';
|
||||||
|
|
||||||
|
async GuildOnModuleCommand(args: any, message: Message) {
|
||||||
|
await this.run(new HybridInteractionMessage(message), args);
|
||||||
|
}
|
||||||
|
|
||||||
|
async GuildModuleCommandInteractionCreate(interaction: CommandInteraction) {
|
||||||
|
await this.run(new HybridInteractionMessage(interaction), interaction.options);
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(data: HybridInteractionMessage, args: any) {
|
||||||
|
const guild = data.getGuild();
|
||||||
|
if (!guild) return;
|
||||||
|
|
||||||
|
const locale = await Locale.getGuildLocale(guild.id);
|
||||||
|
|
||||||
|
await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.SUPPORT_INFO(data, locale)]
|
||||||
|
});
|
||||||
|
|
||||||
|
if(Environment.get().SUPPORT_URL)
|
||||||
|
await sendHybridInteractionMessageResponse(data, {
|
||||||
|
content: Environment.get().SUPPORT_URL
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
-28
@@ -1,4 +1,4 @@
|
|||||||
import { Message, CommandInteraction, Presence, PresenceStatus } from 'discord.js';
|
import { Message, CommandInteraction, Presence, PresenceStatus, ActivityType } from 'discord.js';
|
||||||
import { getColorFromURL, Palette } from 'color-thief-node';
|
import { getColorFromURL, Palette } from 'color-thief-node';
|
||||||
import { I18n } from 'i18n';
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ const EMBEDS = {
|
|||||||
|
|
||||||
if (user.presence?.activities) {
|
if (user.presence?.activities) {
|
||||||
for (let activity of user.presence?.activities) {
|
for (let activity of user.presence?.activities) {
|
||||||
if (activity.type === 'CUSTOM')
|
if (activity.type === ActivityType.Custom)
|
||||||
embed.addField(
|
embed.addFields([{
|
||||||
`✨ ${locale.__('userinfo.custom_status')}`,
|
name: `✨ ${locale.__('userinfo.custom_status')}`,
|
||||||
`${
|
value: `${
|
||||||
!activity.emoji
|
!activity.emoji
|
||||||
? ''
|
? ''
|
||||||
: `${
|
: `${
|
||||||
@@ -88,49 +88,61 @@ const EMBEDS = {
|
|||||||
}`
|
}`
|
||||||
} ${activity.state === null ? '' : activity.state}
|
} ${activity.state === null ? '' : activity.state}
|
||||||
\u200b`,
|
\u200b`,
|
||||||
false
|
inline: false
|
||||||
);
|
}]);
|
||||||
else {
|
else {
|
||||||
let title = '';
|
let title = '';
|
||||||
switch (activity.type) {
|
switch (activity.type) {
|
||||||
case 'PLAYING':
|
case ActivityType.Playing:
|
||||||
title = `'🕹 ${locale.__('userinfo.playing_x', {NAME: activity.name})}`;
|
title = `🕹 ${locale.__('userinfo.playing_x', { NAME: activity.name })}`;
|
||||||
break;
|
break;
|
||||||
case 'STREAMING':
|
case ActivityType.Streaming:
|
||||||
title = `'🔴 ${locale.__('userinfo.streaming_x', {NAME: activity.name})}`;
|
title = `🔴 ${locale.__('userinfo.streaming_x', { NAME: activity.name })}`;
|
||||||
break;
|
break;
|
||||||
case 'LISTENING':
|
case ActivityType.Listening:
|
||||||
title = `🎵 ${locale.__('userinfo.listening_x', { NAME: activity.name })}`;
|
title = `🎵 ${locale.__('userinfo.listening_x', { NAME: activity.name })}`;
|
||||||
break;
|
break;
|
||||||
case 'WATCHING':
|
case ActivityType.Watching:
|
||||||
title = `📺 ${locale.__('userinfo.watching_x', { NAME: activity.name })}`;
|
title = `📺 ${locale.__('userinfo.watching_x', { NAME: activity.name })}`;
|
||||||
break;
|
break;
|
||||||
case 'COMPETING':
|
case ActivityType.Competing:
|
||||||
title = `'🌠 ${locale.__('userinfo.competing_x', {NAME: activity.name})}`;
|
title = `🌠 ${locale.__('userinfo.competing_x', { NAME: activity.name })}`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
embed.addField(
|
const startTime = activity.timestamps?.start;
|
||||||
`${title}`,
|
const endTime = activity.timestamps?.end;
|
||||||
`${activity.details === null ? '' : activity.details}
|
embed.addFields([{
|
||||||
|
name: `${title}`,
|
||||||
|
value: `${activity.details === null ? '' : activity.details}
|
||||||
${activity.state === null ? '' : activity.state}
|
${activity.state === null ? '' : activity.state}
|
||||||
Since <t:${Math.round(new Date(activity.createdAt).getTime() / 1000)}:R>
|
${
|
||||||
|
startTime
|
||||||
|
? `${locale.__('userinfo.since', {TIME: `<t:${Math.round(startTime.getTime() / 1000)}:R>` })}`
|
||||||
|
: ''
|
||||||
|
}${
|
||||||
|
endTime
|
||||||
|
? `\n${locale.__('userinfo.end', {TIME: `<t:${Math.round(endTime.getTime() / 1000)}:R>` })}`
|
||||||
|
: ''
|
||||||
|
}
|
||||||
\u200b`,
|
\u200b`,
|
||||||
false
|
inline: false
|
||||||
);
|
}]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
embed.addField(
|
embed.addFields([{
|
||||||
`📰 ${locale.__('userinfo.user_guild_info')}`,
|
name: `📰 ${locale.__('userinfo.user_guild_info')}`,
|
||||||
`${
|
value: `${
|
||||||
user.joinedAt === null
|
user.joinedAt === null
|
||||||
? locale.__('userinfo.join_date_unknown')
|
? locale.__('userinfo.join_date_unknown')
|
||||||
: locale.__('userinfo.join_date', {TIME: `<t:${Math.round(user.joinedAt.getTime() / 1000).toString()}:R>`})
|
: locale.__('userinfo.join_date', {
|
||||||
|
TIME: `<t:${Math.round(user.joinedAt.getTime() / 1000).toString()}:R>`
|
||||||
|
})
|
||||||
}
|
}
|
||||||
${user.isGuildOwner ? `${locale.__('userinfo.guild_owner')}` : ''}
|
${user.isGuildOwner ? `${locale.__('userinfo.guild_owner')}` : ''}
|
||||||
`
|
`
|
||||||
);
|
}]);
|
||||||
|
|
||||||
embed.setThumbnail(user.displayAvatarURL + '?size=4096');
|
embed.setThumbnail(user.displayAvatarURL + '?size=4096');
|
||||||
embed.setAuthor({
|
embed.setAuthor({
|
||||||
@@ -172,7 +184,7 @@ export default class UserInfo extends DiscordModule {
|
|||||||
if (typeof data.getMessage().mentions.users.first() !== 'undefined')
|
if (typeof data.getMessage().mentions.users.first() !== 'undefined')
|
||||||
query = data.getMessage().mentions.users.first()?.id;
|
query = data.getMessage().mentions.users.first()?.id;
|
||||||
else query = args[0];
|
else query = args[0];
|
||||||
} else if (data.isSlashCommand()) query = data.getSlashCommand().options.getUser('user')?.id;
|
} else if (data.isApplicationCommand()) query = data.getSlashCommand().options.getUser('user')?.id;
|
||||||
|
|
||||||
// Find the user want to look up
|
// Find the user want to look up
|
||||||
let TargetMember = (await guild.members.fetch()).get(query);
|
let TargetMember = (await guild.members.fetch()).get(query);
|
||||||
@@ -181,7 +193,7 @@ export default class UserInfo extends DiscordModule {
|
|||||||
embeds: [EMBEDS.USER_NOT_FOUND(data, locale)]
|
embeds: [EMBEDS.USER_NOT_FOUND(data, locale)]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (data.isSlashCommand()) await data.getMessageComponentInteraction().deferReply();
|
if (data.isApplicationCommand()) await data.getMessageComponentInteraction().deferReply();
|
||||||
|
|
||||||
let colorthief = null;
|
let colorthief = null;
|
||||||
try {
|
try {
|
||||||
|
|||||||
+46
-49
@@ -1,9 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
Message,
|
Message,
|
||||||
MessageActionRow,
|
ActionRowBuilder,
|
||||||
MessageButton,
|
ButtonBuilder,
|
||||||
Interaction,
|
CommandInteraction,
|
||||||
CommandInteraction
|
BaseInteraction,
|
||||||
|
ButtonStyle
|
||||||
} from 'discord.js';
|
} from 'discord.js';
|
||||||
import validator from 'validator';
|
import validator from 'validator';
|
||||||
import countryLookup from 'country-code-lookup';
|
import countryLookup from 'country-code-lookup';
|
||||||
@@ -20,7 +21,7 @@ import {
|
|||||||
} from '../utils/DiscordMessage';
|
} from '../utils/DiscordMessage';
|
||||||
|
|
||||||
const EMBEDS = {
|
const EMBEDS = {
|
||||||
osu_INFO: (data: Message | Interaction) => {
|
osu_INFO: (data: HybridInteractionMessage) => {
|
||||||
return makeInfoEmbed({
|
return makeInfoEmbed({
|
||||||
title: 'osu!',
|
title: 'osu!',
|
||||||
description: `[osu!](https://osu.ppy.sh/home) is a free-to-play rhythm game primarily developed, published, and created by Dean "peppy" Herbert`,
|
description: `[osu!](https://osu.ppy.sh/home) is a free-to-play rhythm game primarily developed, published, and created by Dean "peppy" Herbert`,
|
||||||
@@ -34,43 +35,43 @@ const EMBEDS = {
|
|||||||
value: '``user``'
|
value: '``user``'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
NO_USER_FOUND: (data: Message | Interaction) => {
|
NO_USER_FOUND: (data: HybridInteractionMessage) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: `That user doesn't exists on osu!`,
|
title: `That user doesn't exists on osu!`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
NO_USER_MENTIONED: (data: Message | Interaction) => {
|
NO_USER_MENTIONED: (data: HybridInteractionMessage) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: `No osu! username or user id provided`,
|
title: `No osu! username or user id provided`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
INVALID_USER_MENTIONED: (data: Message | Interaction) => {
|
INVALID_USER_MENTIONED: (data: HybridInteractionMessage) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: `Not a valid osu username or id`,
|
title: `Not a valid osu username or id`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
INVALID_BEATMAP_ID_MENTIONED: (data: Message | Interaction) => {
|
INVALID_BEATMAP_ID_MENTIONED: (data: HybridInteractionMessage) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: `Not a valid osu beatmap id`,
|
title: `Not a valid osu beatmap id`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
NO_BEATMAP_FOUND: (data: Message | Interaction) => {
|
NO_BEATMAP_FOUND: (data: HybridInteractionMessage) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: `That beatmap doesn't exists on osu!`,
|
title: `That beatmap doesn't exists on osu!`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
NO_BEATMAP_MENTIONED: (data: Message | Interaction) => {
|
NO_BEATMAP_MENTIONED: (data: HybridInteractionMessage) => {
|
||||||
return makeErrorEmbed({
|
return makeErrorEmbed({
|
||||||
title: `No osu! beatmap id provided`,
|
title: `No osu! beatmap id provided`,
|
||||||
user: data instanceof Interaction ? data.user : data.author
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -98,26 +99,26 @@ export default class osu extends DiscordModule {
|
|||||||
if (data.isMessage()) {
|
if (data.isMessage()) {
|
||||||
if (typeof args[1] === 'undefined')
|
if (typeof args[1] === 'undefined')
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.NO_USER_MENTIONED(data.getRaw())]
|
embeds: [EMBEDS.NO_USER_MENTIONED(data)]
|
||||||
});
|
});
|
||||||
const [removed, ...newArgs] = args;
|
const [removed, ...newArgs] = args;
|
||||||
user = newArgs.join(' ');
|
user = newArgs.join(' ');
|
||||||
} else if (data.isSlashCommand())
|
} else if (data.isApplicationCommand())
|
||||||
user = data.getSlashCommand().options.getString('user');
|
user = data.getSlashCommand().options.get('user')?.value?.toString();
|
||||||
|
|
||||||
if (!validator.isNumeric(user) && !this.validate_osu_username(user))
|
if (!validator.isNumeric(user) && !this.validate_osu_username(user))
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.INVALID_USER_MENTIONED(data.getRaw())]
|
embeds: [EMBEDS.INVALID_USER_MENTIONED(data)]
|
||||||
});
|
});
|
||||||
|
|
||||||
let result = await osuAPI.client.getUser({ u: user });
|
let result = await osuAPI.client.getUser({ u: user });
|
||||||
|
|
||||||
if (result instanceof Array && result.length === 0)
|
if (result instanceof Array && result.length === 0)
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.NO_USER_FOUND(data.getRaw())]
|
embeds: [EMBEDS.NO_USER_FOUND(data)]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (data.isSlashCommand()) {
|
if (data.isApplicationCommand()) {
|
||||||
await data.getSlashCommand().deferReply();
|
await data.getSlashCommand().deferReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,13 +259,13 @@ export default class osu extends DiscordModule {
|
|||||||
'https://osu.ppy.sh/images/layout/avatar-guest.png'
|
'https://osu.ppy.sh/images/layout/avatar-guest.png'
|
||||||
);
|
);
|
||||||
|
|
||||||
const row = new MessageActionRow().addComponents(
|
const row = new ActionRowBuilder<ButtonBuilder>().addComponents([
|
||||||
new MessageButton()
|
new ButtonBuilder()
|
||||||
.setEmoji('🔗')
|
.setEmoji('🔗')
|
||||||
.setLabel(' Open Profile')
|
.setLabel(' Open Profile')
|
||||||
.setURL(`https://osu.ppy.sh/users/${result.id}`)
|
.setURL(`https://osu.ppy.sh/users/${result.id}`)
|
||||||
.setStyle('LINK')
|
.setStyle(ButtonStyle.Link)
|
||||||
);
|
]);
|
||||||
|
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [embed],
|
embeds: [embed],
|
||||||
@@ -276,26 +277,26 @@ export default class osu extends DiscordModule {
|
|||||||
if (data.isMessage()) {
|
if (data.isMessage()) {
|
||||||
if (typeof args[1] === 'undefined')
|
if (typeof args[1] === 'undefined')
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.NO_BEATMAP_MENTIONED(data.getRaw())]
|
embeds: [EMBEDS.NO_BEATMAP_MENTIONED(data)]
|
||||||
});
|
});
|
||||||
const [removed, ...newArgs] = args;
|
const [removed, ...newArgs] = args;
|
||||||
beatmap = newArgs.join(' ');
|
beatmap = newArgs.join(' ');
|
||||||
} else if (data.isSlashCommand())
|
} else if (data.isApplicationCommand())
|
||||||
beatmap = data.getSlashCommand().options.getString('beatmap');
|
beatmap = data.getSlashCommand().options.get('beatmap')?.value?.toString();
|
||||||
|
|
||||||
if (!validator.isNumeric(beatmap))
|
if (!validator.isNumeric(beatmap))
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.INVALID_BEATMAP_ID_MENTIONED(data.getRaw())]
|
embeds: [EMBEDS.INVALID_BEATMAP_ID_MENTIONED(data)]
|
||||||
});
|
});
|
||||||
|
|
||||||
let result = await osuAPI.client.getBeatmaps({ b: beatmap });
|
let result = await osuAPI.client.getBeatmaps({ b: beatmap });
|
||||||
|
|
||||||
if (result instanceof Array && result.length === 0)
|
if (result instanceof Array && result.length === 0)
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.NO_BEATMAP_FOUND(data.getRaw())]
|
embeds: [EMBEDS.NO_BEATMAP_FOUND(data)]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (data.isSlashCommand()) await data.getSlashCommand().deferReply();
|
if (data.isApplicationCommand()) await data.getSlashCommand().deferReply();
|
||||||
|
|
||||||
const bm_result = result[0];
|
const bm_result = result[0];
|
||||||
|
|
||||||
@@ -436,33 +437,29 @@ export default class osu extends DiscordModule {
|
|||||||
`https://assets.ppy.sh/beatmaps/${bm_result.beatmapSetId}/covers/cover.jpg`
|
`https://assets.ppy.sh/beatmaps/${bm_result.beatmapSetId}/covers/cover.jpg`
|
||||||
);
|
);
|
||||||
|
|
||||||
const row = new MessageActionRow();
|
const row = new ActionRowBuilder<ButtonBuilder>();
|
||||||
if (bm_result.hasDownload)
|
if (bm_result.hasDownload)
|
||||||
row.addComponents(
|
row.addComponents([
|
||||||
new MessageButton()
|
new ButtonBuilder()
|
||||||
.setEmoji('🌎')
|
.setEmoji('🌎')
|
||||||
.setLabel(' Download (Beatconnect)')
|
.setLabel(' Download (Beatconnect)')
|
||||||
.setURL(`https://beatconnect.io/b/${bm_result.beatmapSetId}/`)
|
.setURL(`https://beatconnect.io/b/${bm_result.beatmapSetId}/`)
|
||||||
.setStyle('LINK')
|
.setStyle(ButtonStyle.Link),
|
||||||
);
|
new ButtonBuilder()
|
||||||
row.addComponents(
|
|
||||||
new MessageButton()
|
|
||||||
.setEmoji('🔗')
|
.setEmoji('🔗')
|
||||||
.setLabel(' Open listing')
|
.setLabel(' Open listing')
|
||||||
.setURL(
|
.setURL(
|
||||||
`https://osu.ppy.sh/beatmapsets/${bm_result.beatmapSetId}${url_mode}/${bm_result.id}`
|
`https://osu.ppy.sh/beatmapsets/${bm_result.beatmapSetId}${url_mode}/${bm_result.id}`
|
||||||
)
|
)
|
||||||
.setStyle('LINK')
|
.setStyle(ButtonStyle.Link),
|
||||||
);
|
new ButtonBuilder()
|
||||||
row.addComponents(
|
|
||||||
new MessageButton()
|
|
||||||
.setEmoji('💬')
|
.setEmoji('💬')
|
||||||
.setLabel(' Open discussion')
|
.setLabel(' Open discussion')
|
||||||
.setURL(
|
.setURL(
|
||||||
`https://osu.ppy.sh/beatmapsets/${bm_result.beatmapSetId}/discussion`
|
`https://osu.ppy.sh/beatmapsets/${bm_result.beatmapSetId}/discussion`
|
||||||
)
|
)
|
||||||
.setStyle('LINK')
|
.setStyle(ButtonStyle.Link)
|
||||||
);
|
]);
|
||||||
|
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [embed2],
|
embeds: [embed2],
|
||||||
@@ -476,11 +473,11 @@ export default class osu extends DiscordModule {
|
|||||||
if (data.isMessage()) {
|
if (data.isMessage()) {
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
return await sendHybridInteractionMessageResponse(data, {
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
embeds: [EMBEDS.osu_INFO(data.getRaw())]
|
embeds: [EMBEDS.osu_INFO(data)]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
query = args[0].toLowerCase();
|
query = args[0].toLowerCase();
|
||||||
} else if (data.isSlashCommand()) {
|
} else if (data.isApplicationCommand()) {
|
||||||
query = args.getSubcommand();
|
query = args.getSubcommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,5 +10,4 @@ App.loadLocale();
|
|||||||
App.loadDiscord();
|
App.loadDiscord();
|
||||||
App.load_osu();
|
App.load_osu();
|
||||||
|
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import osu from './osuAPI';
|
|||||||
import Logger from '../libs/Logger';
|
import Logger from '../libs/Logger';
|
||||||
import Locale from './Locale';
|
import Locale from './Locale';
|
||||||
class App {
|
class App {
|
||||||
public readonly versionNumber = `0.09`;
|
public readonly versionNumber = `0.11`;
|
||||||
public readonly version = `${this.versionNumber}${
|
public readonly version = `${this.versionNumber}${
|
||||||
Environment.get().NODE_ENV === 'development' ? ' / Development Build' : ''
|
Environment.get().NODE_ENV === 'development' ? ' / Development Build' : ''
|
||||||
}`;
|
}`;
|
||||||
|
|||||||
+14
-10
@@ -1,4 +1,4 @@
|
|||||||
import { Guild, Client, GuildMember, Intents, Interaction, Message, TextChannel, BaseGuildTextChannel } from 'discord.js';
|
import { Guild, Client, GuildMember, IntentsBitField, Interaction, Message, TextChannel, BaseGuildTextChannel, TextBasedChannelMixin, ChannelType, BaseGuildVoiceChannel, InteractionType } from 'discord.js';
|
||||||
|
|
||||||
import Logger from '../libs/Logger';
|
import Logger from '../libs/Logger';
|
||||||
import Environment from './Environment';
|
import Environment from './Environment';
|
||||||
@@ -14,8 +14,10 @@ import Discord_MembershipScreening from '../discord/MembershipScreening';
|
|||||||
import Discord_osu from '../discord/osu';
|
import Discord_osu from '../discord/osu';
|
||||||
import Discord_UserInfo from '../discord/UserInfo';
|
import Discord_UserInfo from '../discord/UserInfo';
|
||||||
import Discord_Stats from '../discord/Stats';
|
import Discord_Stats from '../discord/Stats';
|
||||||
|
import Discord_Support from '../discord/Support';
|
||||||
|
|
||||||
import Discord_MusicPlayer_Play from '../discord/MusicPlayer/Play';
|
import Discord_MusicPlayer_Play from '../discord/MusicPlayer/Play';
|
||||||
|
import Discord_MusicPlayer_PlayMy from '../discord/MusicPlayer/PlayMy';
|
||||||
import Discord_MusicPlayer_Skip from '../discord/MusicPlayer/Skip';
|
import Discord_MusicPlayer_Skip from '../discord/MusicPlayer/Skip';
|
||||||
import Discord_MusicPlayer_Join from '../discord/MusicPlayer/Join';
|
import Discord_MusicPlayer_Join from '../discord/MusicPlayer/Join';
|
||||||
import Discord_MusicPlayer_Leave from '../discord/MusicPlayer/Leave';
|
import Discord_MusicPlayer_Leave from '../discord/MusicPlayer/Leave';
|
||||||
@@ -38,13 +40,13 @@ class Discord {
|
|||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.client = new Client({
|
this.client = new Client({
|
||||||
//partials: ['MESSAGE', 'CHANNEL', 'REACTION'],
|
|
||||||
intents: [
|
intents: [
|
||||||
Intents.FLAGS.GUILDS,
|
IntentsBitField.Flags.MessageContent,
|
||||||
Intents.FLAGS.GUILD_MESSAGES,
|
IntentsBitField.Flags.Guilds,
|
||||||
Intents.FLAGS.GUILD_MEMBERS,
|
IntentsBitField.Flags.GuildMessages,
|
||||||
Intents.FLAGS.GUILD_PRESENCES,
|
IntentsBitField.Flags.GuildMembers,
|
||||||
Intents.FLAGS.GUILD_VOICE_STATES
|
IntentsBitField.Flags.GuildPresences,
|
||||||
|
IntentsBitField.Flags.GuildVoiceStates
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -64,8 +66,10 @@ class Discord {
|
|||||||
new Discord_InteractionManager(),
|
new Discord_InteractionManager(),
|
||||||
new Discord_osu(),
|
new Discord_osu(),
|
||||||
new Discord_Settings(),
|
new Discord_Settings(),
|
||||||
|
new Discord_Support(),
|
||||||
|
|
||||||
new Discord_MusicPlayer_Play(),
|
new Discord_MusicPlayer_Play(),
|
||||||
|
new Discord_MusicPlayer_PlayMy(),
|
||||||
new Discord_MusicPlayer_NowPlaying(),
|
new Discord_MusicPlayer_NowPlaying(),
|
||||||
new Discord_MusicPlayer_Skip(),
|
new Discord_MusicPlayer_Skip(),
|
||||||
new Discord_MusicPlayer_Join(),
|
new Discord_MusicPlayer_Join(),
|
||||||
@@ -127,7 +131,7 @@ class Discord {
|
|||||||
if (interaction.guild) {
|
if (interaction.guild) {
|
||||||
thisModule.GuildInteractionCreate(interaction);
|
thisModule.GuildInteractionCreate(interaction);
|
||||||
|
|
||||||
if (interaction.isCommand() && interaction.commandName && thisModule.commandInteractionName) {
|
if (interaction.type === InteractionType.ApplicationCommand && interaction.commandName && thisModule.commandInteractionName) {
|
||||||
thisModule.GuildCommandInteractionCreate(interaction);
|
thisModule.GuildCommandInteractionCreate(interaction);
|
||||||
if (interaction.commandName.toLowerCase() === thisModule.commandInteractionName)
|
if (interaction.commandName.toLowerCase() === thisModule.commandInteractionName)
|
||||||
thisModule.GuildModuleCommandInteractionCreate(interaction);
|
thisModule.GuildModuleCommandInteractionCreate(interaction);
|
||||||
@@ -160,7 +164,7 @@ class Discord {
|
|||||||
|
|
||||||
// Handling guild commands
|
// Handling guild commands
|
||||||
this.client.on('messageCreate', async (message: Message) => {
|
this.client.on('messageCreate', async (message: Message) => {
|
||||||
if (!(message.channel instanceof BaseGuildTextChannel)) return;
|
if (!(message.channel instanceof BaseGuildTextChannel || message.channel instanceof BaseGuildVoiceChannel)) return;
|
||||||
if (message.author.bot) return;
|
if (message.author.bot) return;
|
||||||
if (typeof message.guild?.id === 'undefined') return;
|
if (typeof message.guild?.id === 'undefined') return;
|
||||||
|
|
||||||
@@ -261,7 +265,7 @@ class Discord {
|
|||||||
// Handling mentions
|
// Handling mentions
|
||||||
this.client.on('messageCreate', async (message: Message) => {
|
this.client.on('messageCreate', async (message: Message) => {
|
||||||
// TODO: Handle DMs commands soon
|
// TODO: Handle DMs commands soon
|
||||||
if (!(message.channel instanceof TextChannel)) return;
|
if (!(message.channel instanceof BaseGuildTextChannel || message.channel instanceof BaseGuildVoiceChannel)) return;
|
||||||
if (message.author.bot) return;
|
if (message.author.bot) return;
|
||||||
|
|
||||||
if (typeof message.guild?.id === 'undefined') return;
|
if (typeof message.guild?.id === 'undefined') return;
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
import { VoiceChannel, Snowflake, TextChannel, StageChannel, Guild } from 'discord.js';
|
import {
|
||||||
|
VoiceChannel,
|
||||||
|
Snowflake,
|
||||||
|
StageChannel,
|
||||||
|
Guild,
|
||||||
|
PermissionsBitField,
|
||||||
|
BaseGuildVoiceChannel,
|
||||||
|
BaseGuildTextChannel
|
||||||
|
} from 'discord.js';
|
||||||
import {
|
import {
|
||||||
AudioPlayer,
|
AudioPlayer,
|
||||||
VoiceConnection,
|
VoiceConnection,
|
||||||
@@ -7,27 +15,113 @@ import {
|
|||||||
createAudioResource,
|
createAudioResource,
|
||||||
VoiceConnectionStatus,
|
VoiceConnectionStatus,
|
||||||
AudioPlayerStatus,
|
AudioPlayerStatus,
|
||||||
AudioPlayerState,
|
|
||||||
NoSubscriberBehavior,
|
NoSubscriberBehavior,
|
||||||
VoiceConnectionState,
|
VoiceConnectionState,
|
||||||
AudioPlayerError,
|
AudioPlayerError,
|
||||||
DiscordGatewayAdapterCreator
|
DiscordGatewayAdapterCreator
|
||||||
} from '@discordjs/voice';
|
} from '@discordjs/voice';
|
||||||
import playdl, { YouTubeVideo } from 'play-dl';
|
import playdl, { Spotify, SpotifyPlaylist, SpotifyTrack, YouTubeVideo } from 'play-dl';
|
||||||
import { EventEmitter } from 'stream';
|
import { EventEmitter } from 'stream';
|
||||||
|
|
||||||
import DiscordProvider from './Discord';
|
import DiscordProvider from './Discord';
|
||||||
import Environment from './Environment';
|
import Environment from './Environment';
|
||||||
|
import Logger from '../libs/Logger';
|
||||||
|
|
||||||
export type ValidTracks = YouTubeVideo;
|
export type ValidTracks = YouTubeVideo | SpotifyTrack;
|
||||||
|
declare class YouTubeThumbnail {
|
||||||
|
url: string;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
constructor(data: any);
|
||||||
|
toJSON(): {
|
||||||
|
url: string;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SpotifyThumbnail {
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TokenOptions {
|
||||||
|
spotify?: {
|
||||||
|
client_id: string;
|
||||||
|
client_secret: string;
|
||||||
|
refresh_token: string;
|
||||||
|
market: string;
|
||||||
|
};
|
||||||
|
soundcloud?: {
|
||||||
|
client_id: string;
|
||||||
|
};
|
||||||
|
youtube?: {
|
||||||
|
cookie: string;
|
||||||
|
};
|
||||||
|
useragent?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
let tokenObject: TokenOptions = {};
|
||||||
|
|
||||||
if (Environment.get().YOUTUBE_COOKIE_BASE64) {
|
if (Environment.get().YOUTUBE_COOKIE_BASE64) {
|
||||||
playdl.setToken({
|
tokenObject.youtube = {
|
||||||
youtube: {
|
|
||||||
cookie: Buffer.from(Environment.get().YOUTUBE_COOKIE_BASE64, 'base64').toString()
|
cookie: Buffer.from(Environment.get().YOUTUBE_COOKIE_BASE64, 'base64').toString()
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Environment.get().SPOTIFY_CLIENT_ID && Environment.get().SPOTIFY_CLIENT_SECRET && Environment.get().SPOTIFY_REFRESH_TOKEN && Environment.get().SPOTIFY_CLIENT_MARKET) {
|
||||||
|
tokenObject.spotify = {
|
||||||
|
client_id: Environment.get().SPOTIFY_CLIENT_ID,
|
||||||
|
client_secret: Environment.get().SPOTIFY_CLIENT_SECRET,
|
||||||
|
refresh_token: Environment.get().SPOTIFY_REFRESH_TOKEN,
|
||||||
|
market: Environment.get().SPOTIFY_CLIENT_MARKET
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
playdl.setToken(tokenObject);
|
||||||
|
|
||||||
|
export class TrackUtils {
|
||||||
|
public static getTitle(track: ValidTracks) {
|
||||||
|
if (track instanceof YouTubeVideo) {
|
||||||
|
return track.title;
|
||||||
|
} else if (track instanceof SpotifyTrack) {
|
||||||
|
let artistNames = "";
|
||||||
|
for(let artist of track.artists)
|
||||||
|
artistNames += artist.name + " ";
|
||||||
|
|
||||||
|
return `${artistNames} - ${track.name}`;;
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid track type');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static async getThumbnails(track: ValidTracks) {
|
||||||
|
if (track instanceof YouTubeVideo) {
|
||||||
|
return track.thumbnails;
|
||||||
|
} else if (track instanceof SpotifyTrack) {
|
||||||
|
if (track.thumbnail)
|
||||||
|
return [track.thumbnail];
|
||||||
|
else {
|
||||||
|
// Try to find the thumbnail again
|
||||||
|
const result = await DiscordMusicPlayer_Instance.searchSpotifyBySpotifyLink(track);
|
||||||
|
if(!result) return null;
|
||||||
|
if(result.thumbnail)
|
||||||
|
return [result.thumbnail];
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid track type');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static getHighestResolutionThumbnail(thumbnails: (YouTubeThumbnail[] | SpotifyThumbnail[] | null)) {
|
||||||
|
if(!thumbnails) return null;
|
||||||
|
|
||||||
|
return (thumbnails as any[]).reduce((prev: any, current: any) =>
|
||||||
|
prev.height * prev.width > current.height * current.width ? prev : current
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class Queue {
|
export class Queue {
|
||||||
public track: ValidTracks[] = [];
|
public track: ValidTracks[] = [];
|
||||||
}
|
}
|
||||||
@@ -42,6 +136,18 @@ export class YouTubeLink {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class SpotifyLink {
|
||||||
|
public id: string;
|
||||||
|
public type: 'track' | 'playlist' | 'album';
|
||||||
|
public url: string;
|
||||||
|
|
||||||
|
constructor(id: string, type: ('track' | 'playlist' | 'album'), url: string) {
|
||||||
|
this.id = id;
|
||||||
|
this.type = type;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class PlayerPlayingEvent {
|
export class PlayerPlayingEvent {
|
||||||
public instance: DiscordMusicPlayerInstance;
|
public instance: DiscordMusicPlayerInstance;
|
||||||
|
|
||||||
@@ -75,7 +181,7 @@ export enum DiscordMusicPlayerLoopMode {
|
|||||||
export class DiscordMusicPlayerInstance {
|
export class DiscordMusicPlayerInstance {
|
||||||
public queue: Queue;
|
public queue: Queue;
|
||||||
public player: AudioPlayer;
|
public player: AudioPlayer;
|
||||||
public textChannel?: TextChannel;
|
public textChannel?: BaseGuildTextChannel | BaseGuildVoiceChannel;
|
||||||
public voiceChannel: VoiceChannel | StageChannel;
|
public voiceChannel: VoiceChannel | StageChannel;
|
||||||
public voiceConnection?: VoiceConnection;
|
public voiceConnection?: VoiceConnection;
|
||||||
public previousTrack?: ValidTracks;
|
public previousTrack?: ValidTracks;
|
||||||
@@ -83,6 +189,8 @@ export class DiscordMusicPlayerInstance {
|
|||||||
public paused: boolean = false;
|
public paused: boolean = false;
|
||||||
public loopMode: DiscordMusicPlayerLoopMode = DiscordMusicPlayerLoopMode.None;
|
public loopMode: DiscordMusicPlayerLoopMode = DiscordMusicPlayerLoopMode.None;
|
||||||
|
|
||||||
|
public actualPlaybackURL?: string;
|
||||||
|
|
||||||
public readonly events: EventEmitter;
|
public readonly events: EventEmitter;
|
||||||
|
|
||||||
constructor({ voiceChannel }: { voiceChannel: VoiceChannel | StageChannel }) {
|
constructor({ voiceChannel }: { voiceChannel: VoiceChannel | StageChannel }) {
|
||||||
@@ -98,10 +206,7 @@ export class DiscordMusicPlayerInstance {
|
|||||||
|
|
||||||
this.player.on(AudioPlayerStatus.Idle, async (oldStage, newStage) => {
|
this.player.on(AudioPlayerStatus.Idle, async (oldStage, newStage) => {
|
||||||
//The player stopped
|
//The player stopped
|
||||||
if (
|
if (newStage.status === AudioPlayerStatus.Idle && oldStage.status !== AudioPlayerStatus.Idle) {
|
||||||
newStage.status === AudioPlayerStatus.Idle &&
|
|
||||||
oldStage.status !== AudioPlayerStatus.Idle
|
|
||||||
) {
|
|
||||||
// Loop mode is set to current song
|
// Loop mode is set to current song
|
||||||
if (this.loopMode === DiscordMusicPlayerLoopMode.Current) {
|
if (this.loopMode === DiscordMusicPlayerLoopMode.Current) {
|
||||||
if (this.queue.track.length !== 0) {
|
if (this.queue.track.length !== 0) {
|
||||||
@@ -132,24 +237,10 @@ export class DiscordMusicPlayerInstance {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public isReady() {
|
public joinVoiceChannel(voiceChannel: VoiceChannel | StageChannel, textChannel?: BaseGuildTextChannel | BaseGuildVoiceChannel) {
|
||||||
if (!this.voiceConnection) return false;
|
|
||||||
return this.voiceConnection.state.status === VoiceConnectionStatus.Ready;
|
|
||||||
}
|
|
||||||
|
|
||||||
public isConnected() {
|
|
||||||
if (!this.voiceConnection) return false;
|
|
||||||
|
|
||||||
if (this.voiceConnection.state.status === VoiceConnectionStatus.Destroyed) return false;
|
|
||||||
if (this.voiceConnection.state.status === VoiceConnectionStatus.Disconnected) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public joinVoiceChannel(voiceChannel: VoiceChannel | StageChannel, textChannel?: TextChannel) {
|
|
||||||
const permissions = voiceChannel.permissionsFor(DiscordProvider.client.user!);
|
const permissions = voiceChannel.permissionsFor(DiscordProvider.client.user!);
|
||||||
|
|
||||||
if (!permissions || !voiceChannel.joinable || !permissions.has('CONNECT'))
|
if (!permissions || !voiceChannel.joinable || !permissions.has(PermissionsBitField.Flags.Connect))
|
||||||
throw new Error('No permissions');
|
throw new Error('No permissions');
|
||||||
|
|
||||||
if (textChannel) this.textChannel = textChannel;
|
if (textChannel) this.textChannel = textChannel;
|
||||||
@@ -157,31 +248,32 @@ export class DiscordMusicPlayerInstance {
|
|||||||
this.voiceConnection = joinVoiceChannel({
|
this.voiceConnection = joinVoiceChannel({
|
||||||
channelId: this.voiceChannel.id,
|
channelId: this.voiceChannel.id,
|
||||||
guildId: this.voiceChannel.guild.id,
|
guildId: this.voiceChannel.guild.id,
|
||||||
adapterCreator: this.voiceChannel.guild
|
adapterCreator: this.voiceChannel.guild.voiceAdapterCreator as DiscordGatewayAdapterCreator
|
||||||
.voiceAdapterCreator as DiscordGatewayAdapterCreator
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.voiceConnection.on(
|
this.voiceConnection.on(
|
||||||
VoiceConnectionStatus.Ready,
|
VoiceConnectionStatus.Ready,
|
||||||
(oldState: VoiceConnectionState, newState: VoiceConnectionState) => {
|
async (oldState: VoiceConnectionState, newState: VoiceConnectionState) => {
|
||||||
let currentVC = DiscordProvider.client.guilds.cache.get(voiceChannel.guild.id)?.me
|
let guild = DiscordProvider.client.guilds.cache.get(voiceChannel.guild.id);
|
||||||
?.voice.channel;
|
if (guild) {
|
||||||
|
let currentVC = guild?.members.me?.voice.channel;
|
||||||
if (currentVC && currentVC.id !== this.voiceChannel.id) {
|
if (currentVC && currentVC.id !== this.voiceChannel.id) {
|
||||||
this.voiceChannel = currentVC;
|
this.voiceChannel = currentVC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
this.voiceConnection.on(
|
this.voiceConnection.on(
|
||||||
VoiceConnectionStatus.Disconnected,
|
VoiceConnectionStatus.Disconnected,
|
||||||
(oldState: VoiceConnectionState, newState: VoiceConnectionState) => {
|
(oldState: VoiceConnectionState, newState: VoiceConnectionState) => {
|
||||||
setTimeout(() => {
|
setTimeout(async () => {
|
||||||
if (
|
let guild = DiscordProvider.client.guilds.cache.get(voiceChannel.guildId);
|
||||||
!DiscordProvider.client.guilds.cache.get(voiceChannel.guildId!)!.me!.voice
|
if(guild) {
|
||||||
.channelId
|
if (!guild?.members.me?.voice.channelId) {
|
||||||
) {
|
|
||||||
this.events.emit('disconnect', new VoiceDisconnectedEvent(this));
|
this.events.emit('disconnect', new VoiceDisconnectedEvent(this));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -190,9 +282,10 @@ export class DiscordMusicPlayerInstance {
|
|||||||
public async leaveVoiceChannel() {
|
public async leaveVoiceChannel() {
|
||||||
if (this.player) this.player.pause();
|
if (this.player) this.player.pause();
|
||||||
|
|
||||||
if (DiscordProvider.client.guilds.cache.get(this.voiceChannel.guild.id)?.me?.voice) {
|
const guild = DiscordProvider.client.guilds.cache.get(this.voiceChannel.guild.id);
|
||||||
this.voiceConnection?.disconnect();
|
if (!guild) return;
|
||||||
}
|
|
||||||
|
if (guild.members.me?.voice) this.voiceConnection?.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async pausePlayer() {
|
public async pausePlayer() {
|
||||||
@@ -221,10 +314,25 @@ export class DiscordMusicPlayerInstance {
|
|||||||
if (!this.voiceConnection) throw new Error('No voice connection');
|
if (!this.voiceConnection) throw new Error('No voice connection');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
let resource;
|
||||||
|
if(track instanceof YouTubeVideo) {
|
||||||
const stream = await playdl.stream(track.url);
|
const stream = await playdl.stream(track.url);
|
||||||
const resource = createAudioResource(stream.stream, {
|
resource = createAudioResource(stream.stream, {
|
||||||
inputType: stream.type
|
inputType: stream.type
|
||||||
});
|
});
|
||||||
|
this.actualPlaybackURL = track.url;
|
||||||
|
} else {
|
||||||
|
const search = await DiscordMusicPlayer_Instance.searchYouTubeBySpotifyLink(track);
|
||||||
|
if(!search)
|
||||||
|
throw new Error('Unable to find Spotify track on YouTube');
|
||||||
|
|
||||||
|
const stream = await playdl.stream(search.url);
|
||||||
|
resource = createAudioResource(stream.stream, {
|
||||||
|
inputType: stream.type
|
||||||
|
});
|
||||||
|
this.actualPlaybackURL = search.url;
|
||||||
|
}
|
||||||
|
|
||||||
this.player.play(resource);
|
this.player.play(resource);
|
||||||
this.voiceConnection.subscribe(this.player);
|
this.voiceConnection.subscribe(this.player);
|
||||||
@@ -248,6 +356,31 @@ export class DiscordMusicPlayerInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public clearQueue() {
|
||||||
|
if (!this.voiceConnection) throw new Error('No voice connection');
|
||||||
|
|
||||||
|
if(!this.queue.track || this.queue.track.length === 0) return;
|
||||||
|
this.queue.track = [this.queue.track[0]];
|
||||||
|
}
|
||||||
|
|
||||||
|
public shuffleQueue() {
|
||||||
|
if (!this.voiceConnection) throw new Error('No voice connection');
|
||||||
|
|
||||||
|
const shuffleFixedFirst = (queue: ValidTracks[]) => {
|
||||||
|
if(queue.length <= 2) return queue;
|
||||||
|
|
||||||
|
const fixedFirst = queue.shift();
|
||||||
|
if(!fixedFirst) return queue;
|
||||||
|
|
||||||
|
queue.sort(() => Math.random() - 0.5);
|
||||||
|
queue.unshift(fixedFirst);
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!this.queue.track || this.queue.track.length === 0) return;
|
||||||
|
this.queue.track = shuffleFixedFirst(this.queue.track);
|
||||||
|
}
|
||||||
|
|
||||||
public setLoopMode(mode: DiscordMusicPlayerLoopMode) {
|
public setLoopMode(mode: DiscordMusicPlayerLoopMode) {
|
||||||
this.loopMode = mode;
|
this.loopMode = mode;
|
||||||
}
|
}
|
||||||
@@ -260,6 +393,24 @@ export class DiscordMusicPlayerInstance {
|
|||||||
return this.previousTrack;
|
return this.previousTrack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getActualPlaybackURL() {
|
||||||
|
return this.actualPlaybackURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public isReady() {
|
||||||
|
if (!this.voiceConnection) return false;
|
||||||
|
return this.voiceConnection.state.status === VoiceConnectionStatus.Ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
public isConnected() {
|
||||||
|
if (!this.voiceConnection) return false;
|
||||||
|
|
||||||
|
if (this.voiceConnection.state.status === VoiceConnectionStatus.Destroyed) return false;
|
||||||
|
if (this.voiceConnection.state.status === VoiceConnectionStatus.Disconnected) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public isPaused() {
|
public isPaused() {
|
||||||
return this.paused;
|
return this.paused;
|
||||||
}
|
}
|
||||||
@@ -286,10 +437,7 @@ export class DiscordMusicPlayerInstance {
|
|||||||
const stream = 'https://fakestream:42069/fake/stream/fake/audio/fake.mp3';
|
const stream = 'https://fakestream:42069/fake/stream/fake/audio/fake.mp3';
|
||||||
const resource = createAudioResource(stream);
|
const resource = createAudioResource(stream);
|
||||||
this.player.play(resource);
|
this.player.play(resource);
|
||||||
this.player.emit(
|
this.player.emit('error', new AudioPlayerError(new Error('Music player was manually crashed'), null!));
|
||||||
'error',
|
|
||||||
new AudioPlayerError(new Error('Music player was manually crashed'), null!)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,12 +474,44 @@ class DiscordMusicPlayer {
|
|||||||
return searched;
|
return searched;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async searchYouTubeBySpotifyLink(spotifyLink: SpotifyLink) {
|
||||||
|
|
||||||
|
const track = await this.searchSpotifyBySpotifyLink(spotifyLink);
|
||||||
|
if(!track) return;
|
||||||
|
|
||||||
|
let artistNames = "";
|
||||||
|
for(let artist of track.artists)
|
||||||
|
artistNames += artist.name + " ";
|
||||||
|
|
||||||
|
const ytSearchResult = await this.searchYouTubeByQuery(`${artistNames} ${track.name}`);
|
||||||
|
if(!ytSearchResult) return null;
|
||||||
|
|
||||||
|
return ytSearchResult[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public async searchSpotifyBySpotifyLink(spotifyLink: SpotifyLink) {
|
||||||
|
if(playdl.is_expired())
|
||||||
|
await playdl.refreshToken();
|
||||||
|
|
||||||
|
if(spotifyLink.type != 'track') return;
|
||||||
|
|
||||||
|
// Fetch data from spotify
|
||||||
|
const searched: Spotify = await playdl.spotify("https://open.spotify.com/track/" + spotifyLink.id).catch((err) => {
|
||||||
|
Logger.error(err.message);
|
||||||
|
throw new Error('Error while searching on Spotify');
|
||||||
|
});
|
||||||
|
if(!(searched instanceof SpotifyTrack)) return;
|
||||||
|
|
||||||
|
if (!searched) return null;
|
||||||
|
const track = searched as unknown as SpotifyTrack;
|
||||||
|
return track;
|
||||||
|
}
|
||||||
|
|
||||||
public async searchYouTubeByYouTubeLink(youtubeLink: YouTubeLink) {
|
public async searchYouTubeByYouTubeLink(youtubeLink: YouTubeLink) {
|
||||||
// Search the url
|
// Search the url
|
||||||
const searched: YouTubeVideo[] = await playdl.search(
|
const searched: YouTubeVideo[] = await playdl.search('https://www.youtube.com/watch?v=' + youtubeLink.videoId, {
|
||||||
'https://www.youtube.com/watch?v=' + youtubeLink.videoId,
|
source: { youtube: 'video' }
|
||||||
{ source: { youtube: 'video' } }
|
});
|
||||||
);
|
|
||||||
for (let video of searched) {
|
for (let video of searched) {
|
||||||
if (video.id === youtubeLink.videoId) return video;
|
if (video.id === youtubeLink.videoId) return video;
|
||||||
}
|
}
|
||||||
@@ -345,9 +525,7 @@ class DiscordMusicPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Last resort, search the title
|
// Last resort, search the title
|
||||||
const videoInfo = await playdl.video_basic_info(
|
const videoInfo = await playdl.video_basic_info('https://www.youtube.com/watch?v=' + youtubeLink.videoId);
|
||||||
'https://www.youtube.com/watch?v=' + youtubeLink.videoId
|
|
||||||
);
|
|
||||||
if (videoInfo?.video_details?.title) {
|
if (videoInfo?.video_details?.title) {
|
||||||
const searched: YouTubeVideo[] = await playdl.search(videoInfo.video_details.title, {
|
const searched: YouTubeVideo[] = await playdl.search(videoInfo.video_details.title, {
|
||||||
source: { youtube: 'video' }
|
source: { youtube: 'video' }
|
||||||
@@ -357,9 +535,7 @@ class DiscordMusicPlayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let yt_info = await playdl.video_info(
|
let yt_info = await playdl.video_info('https://www.youtube.com/watch?v=' + youtubeLink.videoId);
|
||||||
'https://www.youtube.com/watch?v=' + youtubeLink.videoId
|
|
||||||
);
|
|
||||||
if (yt_info) {
|
if (yt_info) {
|
||||||
return new YouTubeVideo({
|
return new YouTubeVideo({
|
||||||
id: yt_info.video_details.id,
|
id: yt_info.video_details.id,
|
||||||
@@ -393,6 +569,21 @@ class DiscordMusicPlayer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getSpotifySongsInPlayList(spotifyLink: string) {
|
||||||
|
if(playdl.is_expired())
|
||||||
|
await playdl.refreshToken();
|
||||||
|
|
||||||
|
const result = await playdl.spotify(spotifyLink).catch((err) => {
|
||||||
|
Logger.error(err.message);
|
||||||
|
throw new Error('Error while searching on Spotify');
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!(result.type == 'playlist' || result.type == 'album'))
|
||||||
|
throw new Error("Not a spotify playlist");
|
||||||
|
|
||||||
|
return result as unknown as SpotifyPlaylist;
|
||||||
|
}
|
||||||
|
|
||||||
public isYouTubeLink(link: string): boolean {
|
public isYouTubeLink(link: string): boolean {
|
||||||
try {
|
try {
|
||||||
this.parseYouTubeLink(link);
|
this.parseYouTubeLink(link);
|
||||||
@@ -402,10 +593,21 @@ class DiscordMusicPlayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isSpotifyLink(link: string): boolean {
|
||||||
|
try {
|
||||||
|
this.parseSpotifyLink(link);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public parseYouTubeLink(query: string): YouTubeLink {
|
public parseYouTubeLink(query: string): YouTubeLink {
|
||||||
if (
|
if (
|
||||||
query.startsWith('https://www.youtube.com/watch?v=') ||
|
query.startsWith('https://www.youtube.com/watch?v=') ||
|
||||||
query.startsWith('http://www.youtube.com/watch?v=')
|
query.startsWith('http://www.youtube.com/watch?v=') ||
|
||||||
|
query.startsWith('https://music.youtube.com/watch?v=') ||
|
||||||
|
query.startsWith('https://music.youtube.com/watch?v=')
|
||||||
) {
|
) {
|
||||||
let data = this.parseURLQuery(query);
|
let data = this.parseURLQuery(query);
|
||||||
if (!data.v) throw new Error('YouTube link is invalid');
|
if (!data.v) throw new Error('YouTube link is invalid');
|
||||||
@@ -437,6 +639,36 @@ class DiscordMusicPlayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public parseSpotifyLink(query: string): SpotifyLink {
|
||||||
|
if (query.startsWith('https://open.spotify.com/track/')) {
|
||||||
|
let id = query.split('/')[4].split(/[?#]/)[0];
|
||||||
|
return {
|
||||||
|
id: id,
|
||||||
|
type: 'track',
|
||||||
|
url: query.split(/[?#]/)[0]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (query.startsWith('https://open.spotify.com/album/')) {
|
||||||
|
let id = query.split('/')[4].split(/[?#]/)[0];
|
||||||
|
return {
|
||||||
|
id: id,
|
||||||
|
type: 'album',
|
||||||
|
url: query.split(/[?#]/)[0]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (query.startsWith('https://open.spotify.com/playlist/')) {
|
||||||
|
let id = query.split('/')[4].split(/[?#]/)[0];
|
||||||
|
return {
|
||||||
|
id: id,
|
||||||
|
type: 'playlist',
|
||||||
|
url: query.split(/[?#]/)[0]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new Error('Spotify link is invalid');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private parseURLQuery(query: string) {
|
private parseURLQuery(query: string) {
|
||||||
let queryObject: any = {};
|
let queryObject: any = {};
|
||||||
if (query.indexOf('?') >= 0) {
|
if (query.indexOf('?') >= 0) {
|
||||||
|
|||||||
@@ -29,19 +29,31 @@ class Environment {
|
|||||||
const DISCORD_TOKEN = process.env.DISCORD_TOKEN;
|
const DISCORD_TOKEN = process.env.DISCORD_TOKEN;
|
||||||
const DEVELOPER_IDS = process.env.DEVELOPER_IDS;
|
const DEVELOPER_IDS = process.env.DEVELOPER_IDS;
|
||||||
const PRIVATE_BOT = process.env.PRIVATE_BOT;
|
const PRIVATE_BOT = process.env.PRIVATE_BOT;
|
||||||
|
const SUPPORT_URL = process.env.SUPPORT_URL;
|
||||||
|
|
||||||
const OSU_API_KEY = process.env.OSU_API_KEY;
|
const OSU_API_KEY = process.env.OSU_API_KEY;
|
||||||
const YOUTUBE_COOKIE_BASE64 = process.env.YOUTUBE_COOKIE_BASE64;
|
const YOUTUBE_COOKIE_BASE64 = process.env.YOUTUBE_COOKIE_BASE64;
|
||||||
|
|
||||||
|
const SPOTIFY_CLIENT_ID = process.env.SPOTIFY_CLIENT_ID;
|
||||||
|
const SPOTIFY_CLIENT_SECRET= process.env.SPOTIFY_CLIENT_SECRET;
|
||||||
|
const SPOTIFY_REFRESH_TOKEN= process.env.SPOTIFY_REFRESH_TOKEN;
|
||||||
|
const SPOTIFY_CLIENT_MARKET= process.env.SPOTIFY_CLIENT_MARKET;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
NODE_ENV,
|
NODE_ENV,
|
||||||
|
|
||||||
DISCORD_TOKEN,
|
DISCORD_TOKEN,
|
||||||
DEVELOPER_IDS,
|
DEVELOPER_IDS,
|
||||||
PRIVATE_BOT,
|
PRIVATE_BOT,
|
||||||
|
SUPPORT_URL,
|
||||||
|
|
||||||
OSU_API_KEY,
|
OSU_API_KEY,
|
||||||
YOUTUBE_COOKIE_BASE64
|
YOUTUBE_COOKIE_BASE64,
|
||||||
|
|
||||||
|
SPOTIFY_CLIENT_ID,
|
||||||
|
SPOTIFY_CLIENT_SECRET,
|
||||||
|
SPOTIFY_REFRESH_TOKEN,
|
||||||
|
SPOTIFY_CLIENT_MARKET
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ export const GLOBAL_COMMANDS: Object[] = [
|
|||||||
.setName('search')
|
.setName('search')
|
||||||
.setDescription('Search for music')
|
.setDescription('Search for music')
|
||||||
.addStringOption((option) => option.setName('query').setDescription('Search query').setRequired(true)),
|
.addStringOption((option) => option.setName('query').setDescription('Search query').setRequired(true)),
|
||||||
|
new SlashCommandBuilder().setName('playmy').setDescription('Play the detected songs you are listening to'),
|
||||||
new SlashCommandBuilder().setName('skip').setDescription('Skip the current song'),
|
new SlashCommandBuilder().setName('skip').setDescription('Skip the current song'),
|
||||||
new SlashCommandBuilder().setName('pause').setDescription('Pause the current music'),
|
new SlashCommandBuilder().setName('pause').setDescription('Pause the current music'),
|
||||||
new SlashCommandBuilder().setName('resume').setDescription('Resume paused music'),
|
new SlashCommandBuilder().setName('resume').setDescription('Resume paused music'),
|
||||||
|
|||||||
+16
-11
@@ -1,5 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
MessageEmbed,
|
EmbedBuilder,
|
||||||
User,
|
User,
|
||||||
MessagePayload,
|
MessagePayload,
|
||||||
MessageOptions,
|
MessageOptions,
|
||||||
@@ -10,8 +10,10 @@ import {
|
|||||||
BaseGuildTextChannel,
|
BaseGuildTextChannel,
|
||||||
Message,
|
Message,
|
||||||
ColorResolvable,
|
ColorResolvable,
|
||||||
Interaction,
|
InteractionReplyOptions,
|
||||||
InteractionReplyOptions
|
BaseInteraction,
|
||||||
|
BaseGuildVoiceChannel,
|
||||||
|
VoiceChannel
|
||||||
} from 'discord.js';
|
} from 'discord.js';
|
||||||
|
|
||||||
import App from '..';
|
import App from '..';
|
||||||
@@ -43,7 +45,7 @@ interface EmbedDataPresets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function makeEmbed(data: EmbedData) {
|
export function makeEmbed(data: EmbedData) {
|
||||||
const embed = new MessageEmbed();
|
const embed = new EmbedBuilder();
|
||||||
embed.setColor(data.color || '#FFFFFF');
|
embed.setColor(data.color || '#FFFFFF');
|
||||||
|
|
||||||
if (!data.icon) embed.setTitle(data.title);
|
if (!data.icon) embed.setTitle(data.title);
|
||||||
@@ -54,14 +56,14 @@ export function makeEmbed(data: EmbedData) {
|
|||||||
if (data.setTimestamp) embed.setTimestamp();
|
if (data.setTimestamp) embed.setTimestamp();
|
||||||
|
|
||||||
if (data.user)
|
if (data.user)
|
||||||
embed.footer = {
|
embed.setFooter({
|
||||||
text: `${data.user.username} | v${App.version}`,
|
text: `${data.user.username} | v${App.version}`,
|
||||||
iconURL: `${data.user.displayAvatarURL()}?size=4096`
|
iconURL: `${data.user.displayAvatarURL()}?size=4096`
|
||||||
};
|
});
|
||||||
else
|
else
|
||||||
embed.footer = {
|
embed.setFooter({
|
||||||
text: `v${App.version}`
|
text: `v${App.version}`
|
||||||
};
|
});
|
||||||
|
|
||||||
if (data.fields) embed.addFields(data.fields);
|
if (data.fields) embed.addFields(data.fields);
|
||||||
|
|
||||||
@@ -129,13 +131,16 @@ export function makeProcessingEmbed(data: EmbedDataPresets) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function sendMessage(
|
export async function sendMessage(
|
||||||
channel: TextChannel | DMChannel | BaseGuildTextChannel | GuildTextBasedChannel | PartialDMChannel,
|
channel: TextChannel | DMChannel | BaseGuildTextChannel | GuildTextBasedChannel | PartialDMChannel | BaseGuildTextChannel | BaseGuildVoiceChannel,
|
||||||
user: User | undefined,
|
user: User | undefined,
|
||||||
options: string | MessagePayload | MessageOptions
|
options: string | MessagePayload | MessageOptions
|
||||||
) {
|
) {
|
||||||
let message;
|
let message;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if(channel instanceof BaseGuildVoiceChannel)
|
||||||
|
message = await (channel as VoiceChannel).send(options);
|
||||||
|
else
|
||||||
message = await channel.send(options);
|
message = await channel.send(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (typeof user === 'undefined') {
|
if (typeof user === 'undefined') {
|
||||||
@@ -160,8 +165,8 @@ export async function sendHybridInteractionMessageResponse(
|
|||||||
data: HybridInteractionMessage,
|
data: HybridInteractionMessage,
|
||||||
payload: MessageOptions | InteractionReplyOptions,
|
payload: MessageOptions | InteractionReplyOptions,
|
||||||
replace = false
|
replace = false
|
||||||
): Promise<Message | Interaction | undefined> {
|
): Promise<Message | BaseInteraction | undefined> {
|
||||||
if (data.isSlashCommand() || data.isButton() || data.isSelectMenu()) {
|
if (data.isApplicationCommand() || data.isButton() || data.isSelectMenu()) {
|
||||||
const messageComponent = data.getMessageComponentInteraction();
|
const messageComponent = data.getMessageComponentInteraction();
|
||||||
|
|
||||||
if (!messageComponent.replied) {
|
if (!messageComponent.replied) {
|
||||||
|
|||||||
@@ -8,7 +8,11 @@ import {
|
|||||||
TextBasedChannel,
|
TextBasedChannel,
|
||||||
MessageComponentInteraction,
|
MessageComponentInteraction,
|
||||||
User,
|
User,
|
||||||
SelectMenuInteraction
|
SelectMenuInteraction,
|
||||||
|
InteractionType,
|
||||||
|
BaseInteraction,
|
||||||
|
GuildBasedChannel,
|
||||||
|
ChannelType
|
||||||
} from 'discord.js';
|
} from 'discord.js';
|
||||||
|
|
||||||
export default class DiscordModule {
|
export default class DiscordModule {
|
||||||
@@ -56,17 +60,17 @@ export default class DiscordModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class HybridInteractionMessage {
|
export class HybridInteractionMessage {
|
||||||
public data: Interaction | Message;
|
public data: BaseInteraction | Message;
|
||||||
constructor(data: Interaction | Message) {
|
constructor(data: BaseInteraction | Message) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public isInteraction(): boolean {
|
public isInteraction(): boolean {
|
||||||
return this.data instanceof Interaction;
|
return this.data instanceof BaseInteraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public isSlashCommand(): boolean {
|
public isApplicationCommand(): boolean {
|
||||||
return this.data instanceof CommandInteraction && this.data.isCommand();
|
return this.data instanceof CommandInteraction && this.data.type === InteractionType.ApplicationCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
public isButton(): boolean {
|
public isButton(): boolean {
|
||||||
@@ -85,6 +89,13 @@ export class HybridInteractionMessage {
|
|||||||
return this.data.channel;
|
return this.data.channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getGuildChannel(): GuildBasedChannel | null {
|
||||||
|
if (this.data.channel && this.data.channel.type !== ChannelType.DM) {
|
||||||
|
return this.getChannel() as GuildBasedChannel;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public getGuild(): Guild | null {
|
public getGuild(): Guild | null {
|
||||||
return this.data.guild;
|
return this.data.guild;
|
||||||
}
|
}
|
||||||
@@ -130,7 +141,7 @@ export class HybridInteractionMessage {
|
|||||||
return this.data as Message;
|
return this.data as Message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getRaw(): Interaction | Message {
|
public getRaw(): BaseInteraction | Message {
|
||||||
return this.data;
|
return this.data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
import { Guild, GuildChannelResolvable, GuildMember } from 'discord.js';
|
||||||
|
import { I18n } from 'i18n';
|
||||||
|
import { COMMON_EMBEDS } from '../discord/Settings';
|
||||||
|
import { sendHybridInteractionMessageResponse } from './DiscordMessage';
|
||||||
|
import { HybridInteractionMessage } from './DiscordModule';
|
||||||
|
|
||||||
|
export async function checkMemberPermissionsInGuild({
|
||||||
|
member,
|
||||||
|
permissions,
|
||||||
|
data,
|
||||||
|
locale
|
||||||
|
}: {
|
||||||
|
member: GuildMember;
|
||||||
|
permissions: bigint[];
|
||||||
|
data?: HybridInteractionMessage;
|
||||||
|
locale?: I18n;
|
||||||
|
}): Promise<boolean> {
|
||||||
|
const hasPermissions = member.permissions.has(permissions);
|
||||||
|
|
||||||
|
if (!hasPermissions && data && locale)
|
||||||
|
await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [COMMON_EMBEDS.MEMBER_NO_PERMISSION(data, locale, permissions)]
|
||||||
|
});
|
||||||
|
|
||||||
|
return hasPermissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function checkMemberPermissionsInChannel({
|
||||||
|
member,
|
||||||
|
channel,
|
||||||
|
permissions,
|
||||||
|
data,
|
||||||
|
locale
|
||||||
|
}: {
|
||||||
|
member: GuildMember;
|
||||||
|
channel: GuildChannelResolvable;
|
||||||
|
permissions: bigint[];
|
||||||
|
data?: HybridInteractionMessage;
|
||||||
|
locale?: I18n;
|
||||||
|
}): Promise<boolean> {
|
||||||
|
const hasPermissions = member.permissionsIn(channel).has(permissions);
|
||||||
|
|
||||||
|
if (!hasPermissions && data && locale)
|
||||||
|
await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [COMMON_EMBEDS.MEMBER_NO_PERMISSION(data, locale, permissions)]
|
||||||
|
});
|
||||||
|
|
||||||
|
return hasPermissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function checkBotPermissionsInGuild({
|
||||||
|
guild,
|
||||||
|
permissions,
|
||||||
|
data,
|
||||||
|
locale
|
||||||
|
}: {
|
||||||
|
guild: Guild;
|
||||||
|
permissions: bigint[];
|
||||||
|
data?: HybridInteractionMessage;
|
||||||
|
locale?: I18n;
|
||||||
|
}): Promise<boolean> {
|
||||||
|
const member = guild.members.me;
|
||||||
|
if(!member) return false;
|
||||||
|
|
||||||
|
const hasPermissions = member.permissions.has(permissions);
|
||||||
|
|
||||||
|
if (!hasPermissions && data && locale)
|
||||||
|
await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [COMMON_EMBEDS.BOT_NO_PERMISSION(data, locale, permissions)]
|
||||||
|
});
|
||||||
|
|
||||||
|
return hasPermissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function checkBotPermissionsInChannel({
|
||||||
|
guild,
|
||||||
|
channel,
|
||||||
|
permissions,
|
||||||
|
data,
|
||||||
|
locale
|
||||||
|
}: {
|
||||||
|
guild: Guild;
|
||||||
|
channel: GuildChannelResolvable;
|
||||||
|
permissions: bigint[];
|
||||||
|
data?: HybridInteractionMessage;
|
||||||
|
locale?: I18n;
|
||||||
|
}): Promise<boolean> {
|
||||||
|
const member = guild.members.me;
|
||||||
|
if(!member) return false;
|
||||||
|
|
||||||
|
const hasPermissions = member.permissionsIn(channel).has(permissions);
|
||||||
|
|
||||||
|
if (!hasPermissions && data && locale)
|
||||||
|
await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [COMMON_EMBEDS.BOT_NO_PERMISSION(data, locale, permissions)]
|
||||||
|
});
|
||||||
|
|
||||||
|
return hasPermissions;
|
||||||
|
}
|
||||||
@@ -23,26 +23,13 @@
|
|||||||
enabled "2.0.x"
|
enabled "2.0.x"
|
||||||
kuler "^2.0.0"
|
kuler "^2.0.0"
|
||||||
|
|
||||||
"@discordjs/builders@^0.14.0":
|
"@discordjs/builders@^1.0.0":
|
||||||
version "0.14.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-0.14.0.tgz#1915af10fa1c30d738b08b1ed0ae3c224fd491d7"
|
resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-1.0.0.tgz#1ddc5a7f9d20977e7414c02989169bb7f55294ba"
|
||||||
integrity sha512-+fqLIqa9wN3R+kvlld8sgG0nt04BAZxdCDP4t2qZ9TJsquLWA+xMtT8Waibb3d4li4AQS+IOfjiHAznv/dhHgQ==
|
integrity sha512-8y91ZfpOHubiGJu5tVyGI9tQCEyHZDTeqUWVcJd0dq7B96xIf84S0L4fwmD1k9zTe1eqEFSk0gc7BpY+FKn7Ww==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@sapphire/shapeshift" "^3.1.0"
|
"@sapphire/shapeshift" "^3.5.1"
|
||||||
"@sindresorhus/is" "^4.6.0"
|
discord-api-types "^0.36.2"
|
||||||
discord-api-types "^0.33.3"
|
|
||||||
fast-deep-equal "^3.1.3"
|
|
||||||
ts-mixer "^6.0.1"
|
|
||||||
tslib "^2.4.0"
|
|
||||||
|
|
||||||
"@discordjs/builders@^0.15.0":
|
|
||||||
version "0.15.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-0.15.0.tgz#f76318f2de0b057c21bb25bb010ef2317039793d"
|
|
||||||
integrity sha512-w1UfCPzx2iKycn6qh/f0c+PcDpcTHzHr7TXALXu/a4gKHGamiSg3lP8GhYswweSJk/Q5cbFLHZUsnoY3MVKNAg==
|
|
||||||
dependencies:
|
|
||||||
"@sapphire/shapeshift" "^3.1.0"
|
|
||||||
"@sindresorhus/is" "^4.6.0"
|
|
||||||
discord-api-types "^0.33.3"
|
|
||||||
fast-deep-equal "^3.1.3"
|
fast-deep-equal "^3.1.3"
|
||||||
ts-mixer "^6.0.1"
|
ts-mixer "^6.0.1"
|
||||||
tslib "^2.4.0"
|
tslib "^2.4.0"
|
||||||
@@ -52,28 +39,33 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.7.0.tgz#1a6c00198b744ba2b73a64442145da637ac073b8"
|
resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.7.0.tgz#1a6c00198b744ba2b73a64442145da637ac073b8"
|
||||||
integrity sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA==
|
integrity sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA==
|
||||||
|
|
||||||
"@discordjs/node-pre-gyp@^0.4.2":
|
"@discordjs/collection@^1.0.0":
|
||||||
version "0.4.2"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@discordjs/node-pre-gyp/-/node-pre-gyp-0.4.2.tgz#37dd27f8d353eeb87372fcce059c5249550b37ab"
|
resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-1.0.0.tgz#4d777d87e56640a200200e7f5605c0fba05ac1b8"
|
||||||
integrity sha512-V239Czn+DXFGLhhuccwEDBoTdgMGrRu30dOlzm1GzrSIjwFj01ZJerNX7x+CEX1NG1Q/1gGfOOkeZFNHjycrRA==
|
integrity sha512-nAxDQYE5dNAzEGQ7HU20sujDsG5vLowUKCEqZkKUIlrXERZFTt/60zKUj/g4+AVCGeq+pXC5hivMaNtiC+PY5Q==
|
||||||
|
|
||||||
|
"@discordjs/node-pre-gyp@^0.4.4":
|
||||||
|
version "0.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@discordjs/node-pre-gyp/-/node-pre-gyp-0.4.4.tgz#33eea1038784ffc5715ef775e4f9d6cffaa96c73"
|
||||||
|
integrity sha512-x569MMtdk6jdGo2S58iiZoyv4p/N2Ju8Nh6vvzZb1wyouV7IE3VuU0hg2kqUmTfD0z6r4uD6acvMTuc+iA3f8g==
|
||||||
dependencies:
|
dependencies:
|
||||||
detect-libc "^1.0.3"
|
detect-libc "^2.0.0"
|
||||||
https-proxy-agent "^5.0.0"
|
https-proxy-agent "^5.0.0"
|
||||||
make-dir "^3.1.0"
|
make-dir "^3.1.0"
|
||||||
node-fetch "^2.6.5"
|
node-fetch "^2.6.7"
|
||||||
nopt "^5.0.0"
|
nopt "^5.0.0"
|
||||||
npmlog "^5.0.1"
|
npmlog "^5.0.1"
|
||||||
rimraf "^3.0.2"
|
rimraf "^3.0.2"
|
||||||
semver "^7.3.5"
|
semver "^7.3.5"
|
||||||
tar "^6.1.11"
|
tar "^6.1.11"
|
||||||
|
|
||||||
"@discordjs/opus@^0.7.0":
|
"@discordjs/opus@^0.8.0":
|
||||||
version "0.7.0"
|
version "0.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/@discordjs/opus/-/opus-0.7.0.tgz#69e9611a6412ea470f8e640f54478da89326ca3b"
|
resolved "https://registry.yarnpkg.com/@discordjs/opus/-/opus-0.8.0.tgz#dae2d220a7942736343021f9af2b2b921d482c46"
|
||||||
integrity sha512-3Xxa3dh7taSDwBAR5fLALZ/KTxvbMmHCMxYLYve6NlPO7Ms1CLmKqp/R4ZoVzkRGQVUVWEhaB1s0v9jfa2tfDg==
|
integrity sha512-uHE7OmHEmP8YM0yvsH3iSdacdeghO0qTkF0CIkV07Tg0qdyOLUVkoZHj5Zcpge9rC4qb/JvTS2xRgttSZLM43Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@discordjs/node-pre-gyp" "^0.4.2"
|
"@discordjs/node-pre-gyp" "^0.4.4"
|
||||||
node-addon-api "^4.2.0"
|
node-addon-api "^5.0.0"
|
||||||
|
|
||||||
"@discordjs/rest@^0.5.0":
|
"@discordjs/rest@^0.5.0":
|
||||||
version "0.5.0"
|
version "0.5.0"
|
||||||
@@ -87,6 +79,19 @@
|
|||||||
tslib "^2.4.0"
|
tslib "^2.4.0"
|
||||||
undici "^5.4.0"
|
undici "^5.4.0"
|
||||||
|
|
||||||
|
"@discordjs/rest@^1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@discordjs/rest/-/rest-1.0.0.tgz#624ac48cf8f66f46d47371323963a0c0617ddd63"
|
||||||
|
integrity sha512-uDAvnE0P2a8axMdD4C51EGjvCRQ2HZk2Yxf6vHWZgIqG87D8DGKMPwmquIxrrB07MjV+rwci2ObU+mGhGP+bJg==
|
||||||
|
dependencies:
|
||||||
|
"@discordjs/collection" "^1.0.0"
|
||||||
|
"@sapphire/async-queue" "^1.3.2"
|
||||||
|
"@sapphire/snowflake" "^3.2.2"
|
||||||
|
discord-api-types "^0.36.2"
|
||||||
|
file-type "^17.1.2"
|
||||||
|
tslib "^2.4.0"
|
||||||
|
undici "^5.7.0"
|
||||||
|
|
||||||
"@discordjs/voice@^0.10.0":
|
"@discordjs/voice@^0.10.0":
|
||||||
version "0.10.0"
|
version "0.10.0"
|
||||||
resolved "https://registry.yarnpkg.com/@discordjs/voice/-/voice-0.10.0.tgz#5c911b5ce276233b232a98c92141e07f1f52168b"
|
resolved "https://registry.yarnpkg.com/@discordjs/voice/-/voice-0.10.0.tgz#5c911b5ce276233b232a98c92141e07f1f52168b"
|
||||||
@@ -100,14 +105,14 @@
|
|||||||
ws "^8.7.0"
|
ws "^8.7.0"
|
||||||
|
|
||||||
"@jridgewell/resolve-uri@^3.0.3":
|
"@jridgewell/resolve-uri@^3.0.3":
|
||||||
version "3.0.7"
|
version "3.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz#30cd49820a962aff48c8fffc5cd760151fca61fe"
|
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.8.tgz#687cc2bbf243f4e9a868ecf2262318e2658873a1"
|
||||||
integrity sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==
|
integrity sha512-YK5G9LaddzGbcucK4c8h5tWFmMPBvRZ/uyWmN1/SbBdIvqGUdWGkJ5BAaccgs6XbzVLsqbPJrBSFwKv3kT9i7w==
|
||||||
|
|
||||||
"@jridgewell/sourcemap-codec@^1.4.10":
|
"@jridgewell/sourcemap-codec@^1.4.10":
|
||||||
version "1.4.13"
|
version "1.4.14"
|
||||||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz#b6461fb0c2964356c469e115f504c95ad97ab88c"
|
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
|
||||||
integrity sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==
|
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
|
||||||
|
|
||||||
"@jridgewell/trace-mapping@0.3.9":
|
"@jridgewell/trace-mapping@0.3.9":
|
||||||
version "0.3.9"
|
version "0.3.9"
|
||||||
@@ -168,62 +173,70 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
make-plural "^7.0.0"
|
make-plural "^7.0.0"
|
||||||
|
|
||||||
"@prisma/client@^3.15.2":
|
"@prisma/client@^4.0.0":
|
||||||
version "3.15.2"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-3.15.2.tgz#2181398147afc79bfe0d83c03a88dc45b49bd365"
|
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-4.0.0.tgz#ed2f46930a1da0d8ae88d7965485973576b04270"
|
||||||
integrity sha512-ErqtwhX12ubPhU4d++30uFY/rPcyvjk+mdifaZO5SeM21zS3t4jQrscy8+6IyB0GIYshl5ldTq6JSBo1d63i8w==
|
integrity sha512-g1h2OGoRo7anBVQ9Cw3gsbjwPtvf7i0pkGxKeZICtwkvE5CZXW+xZF4FZdmrViYkKaAShbISL0teNpu9ecpf4g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@prisma/engines-version" "3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e"
|
"@prisma/engines-version" "3.16.0-49.da41d2bb3406da22087b849f0e911199ba4fbf11"
|
||||||
|
|
||||||
"@prisma/engines-version@3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e":
|
"@prisma/engines-version@3.16.0-49.da41d2bb3406da22087b849f0e911199ba4fbf11":
|
||||||
version "3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e"
|
version "3.16.0-49.da41d2bb3406da22087b849f0e911199ba4fbf11"
|
||||||
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e.tgz#bf5e2373ca68ce7556b967cb4965a7095e93fe53"
|
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-3.16.0-49.da41d2bb3406da22087b849f0e911199ba4fbf11.tgz#4b5efe5eee2feef12910e4627a572cd96ed83236"
|
||||||
integrity sha512-e3k2Vd606efd1ZYy2NQKkT4C/pn31nehyLhVug6To/q8JT8FpiMrDy7zmm3KLF0L98NOQQcutaVtAPhzKhzn9w==
|
integrity sha512-PiZhdD624SrYEjyLboI0X7OugNbxUzDJx9v/6ldTKuqNDVUCmRH/Z00XwDi/dgM4FlqOSO+YiUsSiSKjxxG8cw==
|
||||||
|
|
||||||
"@prisma/engines@3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e":
|
"@prisma/engines@3.16.0-49.da41d2bb3406da22087b849f0e911199ba4fbf11":
|
||||||
version "3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e"
|
version "3.16.0-49.da41d2bb3406da22087b849f0e911199ba4fbf11"
|
||||||
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e.tgz#f691893df506b93e3cb1ccc15ec6e5ac64e8e570"
|
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-3.16.0-49.da41d2bb3406da22087b849f0e911199ba4fbf11.tgz#82f0018153cffa05d61422f9c0c7b0479b180f75"
|
||||||
integrity sha512-NHlojO1DFTsSi3FtEleL9QWXeSF/UjhCW0fgpi7bumnNZ4wj/eQ+BJJ5n2pgoOliTOGv9nX2qXvmHap7rJMNmg==
|
integrity sha512-u/rG4lDHALolWBLr3yebZ+N2qImp3SDMcu7bHNJuRDaYvYEXy/MqfNRNEgd9GoPsXL3gofYf0VzJf2AmCG3YVw==
|
||||||
|
|
||||||
"@sapphire/async-queue@^1.3.1":
|
"@sapphire/async-queue@^1.3.1":
|
||||||
version "1.3.1"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.3.1.tgz#9d861e626dbffae02d808e13f823d4510e450a78"
|
resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.3.1.tgz#9d861e626dbffae02d808e13f823d4510e450a78"
|
||||||
integrity sha512-FFTlPOWZX1kDj9xCAsRzH5xEJfawg1lNoYAA+ecOWJMHOfiZYb1uXOI3ne9U4UILSEPwfE68p3T9wUHwIQfR0g==
|
integrity sha512-FFTlPOWZX1kDj9xCAsRzH5xEJfawg1lNoYAA+ecOWJMHOfiZYb1uXOI3ne9U4UILSEPwfE68p3T9wUHwIQfR0g==
|
||||||
|
|
||||||
"@sapphire/shapeshift@^3.1.0":
|
"@sapphire/async-queue@^1.3.2":
|
||||||
version "3.1.0"
|
version "1.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/@sapphire/shapeshift/-/shapeshift-3.1.0.tgz#e4719fd03ab1d3ea01170f9c37b9cb64f5794759"
|
resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.3.2.tgz#befe5f5025e2e317a9eba2d1a24ca5d2e4576f86"
|
||||||
integrity sha512-PkxFXd3QJ1qAPS05Dy2UkVGYPm/asF1Ugt2Xyzmv4DHzO3+G7l+873C4XFFcJ9M5Je+eCMC7SSifgPTSur5QuA==
|
integrity sha512-rUpMLATsoAMnlN3gecAcr9Ecnw1vG7zi5Xr+IX22YzRzi1k9PF9vKzoT8RuEJbiIszjcimu3rveqUnvwDopz8g==
|
||||||
|
|
||||||
|
"@sapphire/shapeshift@^3.5.1":
|
||||||
|
version "3.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@sapphire/shapeshift/-/shapeshift-3.5.1.tgz#3bfd0e6bcfdced4ac26a6f450b5f7b8e49f4f2cc"
|
||||||
|
integrity sha512-7JFsW5IglyOIUQI1eE0g6h06D/Far6HqpcowRScgCiLSqTf3hhkPWCWotVTtVycnDCMYIwPeaw6IEPBomKC8pA==
|
||||||
|
dependencies:
|
||||||
|
fast-deep-equal "^3.1.3"
|
||||||
|
lodash.uniqwith "^4.5.0"
|
||||||
|
|
||||||
"@sapphire/snowflake@^3.2.2":
|
"@sapphire/snowflake@^3.2.2":
|
||||||
version "3.2.2"
|
version "3.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/@sapphire/snowflake/-/snowflake-3.2.2.tgz#faacdc1b5f7c43145a71eddba917de2b707ef780"
|
resolved "https://registry.yarnpkg.com/@sapphire/snowflake/-/snowflake-3.2.2.tgz#faacdc1b5f7c43145a71eddba917de2b707ef780"
|
||||||
integrity sha512-ula2O0kpSZtX9rKXNeQMrHwNd7E4jPDJYUXmEGTFdMRfyfMw+FPyh04oKMjAiDuOi64bYgVkOV3MjK+loImFhQ==
|
integrity sha512-ula2O0kpSZtX9rKXNeQMrHwNd7E4jPDJYUXmEGTFdMRfyfMw+FPyh04oKMjAiDuOi64bYgVkOV3MjK+loImFhQ==
|
||||||
|
|
||||||
"@sindresorhus/is@^4.6.0":
|
"@tokenizer/token@^0.3.0":
|
||||||
version "4.6.0"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f"
|
resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276"
|
||||||
integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==
|
integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==
|
||||||
|
|
||||||
"@tsconfig/node10@^1.0.7":
|
"@tsconfig/node10@^1.0.7":
|
||||||
version "1.0.8"
|
version "1.0.9"
|
||||||
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9"
|
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2"
|
||||||
integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==
|
integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==
|
||||||
|
|
||||||
"@tsconfig/node12@^1.0.7":
|
"@tsconfig/node12@^1.0.7":
|
||||||
version "1.0.9"
|
version "1.0.11"
|
||||||
resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c"
|
resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d"
|
||||||
integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==
|
integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
|
||||||
|
|
||||||
"@tsconfig/node14@^1.0.0":
|
"@tsconfig/node14@^1.0.0":
|
||||||
version "1.0.1"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2"
|
resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
|
||||||
integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==
|
integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
|
||||||
|
|
||||||
"@tsconfig/node16@^1.0.2":
|
"@tsconfig/node16@^1.0.2":
|
||||||
version "1.0.2"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e"
|
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e"
|
||||||
integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==
|
integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==
|
||||||
|
|
||||||
"@types/bluebird@^3.5.36":
|
"@types/bluebird@^3.5.36":
|
||||||
version "3.5.36"
|
version "3.5.36"
|
||||||
@@ -235,29 +248,21 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/color-thief-node/-/color-thief-node-1.0.1.tgz#851a82b48a5560e4d2c051324e42c21a25e5802c"
|
resolved "https://registry.yarnpkg.com/@types/color-thief-node/-/color-thief-node-1.0.1.tgz#851a82b48a5560e4d2c051324e42c21a25e5802c"
|
||||||
integrity sha512-UU2pvvjtxvugMdCpoG7If9EqbaeITyczSXymIA/h/Quzbf4HwvT1uBKDG0R42jzHlHGOsRqCRb+RP5Kj1RIBaQ==
|
integrity sha512-UU2pvvjtxvugMdCpoG7If9EqbaeITyczSXymIA/h/Quzbf4HwvT1uBKDG0R42jzHlHGOsRqCRb+RP5Kj1RIBaQ==
|
||||||
|
|
||||||
"@types/i18n@^0.13.3":
|
"@types/i18n@^0.13.4":
|
||||||
version "0.13.3"
|
version "0.13.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/i18n/-/i18n-0.13.3.tgz#88db5b33ccbbd57de54c8c2da01002e8fb48efc3"
|
resolved "https://registry.yarnpkg.com/@types/i18n/-/i18n-0.13.4.tgz#fe3d27d08337f9d4a972d1f460d1471d6f79e163"
|
||||||
integrity sha512-o6MlrxjGUDANSmMmQ6p/f7ea3+kJFeNWebxylKE3pLjWbIa0Npr/DT2Qf941oqovdopadAfV+PuBMTKg4p37NA==
|
integrity sha512-PN4ZsplbpHZ2eaYixFNWkZKN51pcB02K2UKvqHVbrzq2jTO0sChPMuKKYAW1ZbElyHUvPgFeYsz9rqktChGyMw==
|
||||||
|
|
||||||
"@types/node-fetch@^2.6.1":
|
|
||||||
version "2.6.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.1.tgz#8f127c50481db65886800ef496f20bbf15518975"
|
|
||||||
integrity sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==
|
|
||||||
dependencies:
|
|
||||||
"@types/node" "*"
|
|
||||||
form-data "^3.0.0"
|
|
||||||
|
|
||||||
"@types/node@*":
|
"@types/node@*":
|
||||||
version "17.0.40"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.40.tgz#76ee88ae03650de8064a6cf75b8d95f9f4a16090"
|
|
||||||
integrity sha512-UXdBxNGqTMtm7hCwh9HtncFVLrXoqA3oJW30j6XWp5BH/wu3mVeaxo7cq5benFdBw34HB3XDT2TRPI7rXZ+mDg==
|
|
||||||
|
|
||||||
"@types/node@^18.0.0":
|
|
||||||
version "18.0.0"
|
version "18.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a"
|
||||||
integrity sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==
|
integrity sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==
|
||||||
|
|
||||||
|
"@types/node@^18.0.4":
|
||||||
|
version "18.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.4.tgz#48aedbf35efb3af1248e4cd4d792c730290cd5d6"
|
||||||
|
integrity sha512-M0+G6V0Y4YV8cqzHssZpaNCqvYwlCiulmm0PwpNLF55r/+cT8Ol42CHRU1SEaYFH2rTwiiE1aYg/2g2rrtGdPA==
|
||||||
|
|
||||||
"@types/os-utils@^0.0.1":
|
"@types/os-utils@^0.0.1":
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/os-utils/-/os-utils-0.0.1.tgz#f1ec7830c60be563d6e9566a0ae3b23ea5497493"
|
resolved "https://registry.yarnpkg.com/@types/os-utils/-/os-utils-0.0.1.tgz#f1ec7830c60be563d6e9566a0ae3b23ea5497493"
|
||||||
@@ -278,10 +283,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1"
|
resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1"
|
||||||
integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==
|
integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==
|
||||||
|
|
||||||
"@types/validator@^13.7.3":
|
"@types/validator@^13.7.4":
|
||||||
version "13.7.3"
|
version "13.7.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.7.3.tgz#3193c0a3c03a7d1189016c62b4fba4b149ef5e33"
|
resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.7.4.tgz#33cc949ee87dd47c63e35ba4ad94f6888852be04"
|
||||||
integrity sha512-DNviAE5OUcZ5s+XEQHRhERLg8fOp8gSgvyJ4aaFASx5wwaObm+PBwTIMXiOFm1QrSee5oYwEAYb7LMzX2O88gA==
|
integrity sha512-uAaSWegu2lymY18l+s5nmcXu3sFeeTOl1zhSGoYzcr6T3wz1M+3OcW4UjfPhIhHGd13tIMRDsEpR+d8w/MexwQ==
|
||||||
|
|
||||||
"@types/ws@^8.5.3":
|
"@types/ws@^8.5.3":
|
||||||
version "8.5.3"
|
version "8.5.3"
|
||||||
@@ -416,9 +421,9 @@ call-bind@^1.0.0:
|
|||||||
get-intrinsic "^1.0.2"
|
get-intrinsic "^1.0.2"
|
||||||
|
|
||||||
canvas@^2.5.0:
|
canvas@^2.5.0:
|
||||||
version "2.9.1"
|
version "2.9.3"
|
||||||
resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.9.1.tgz#58ec841cba36cef0675bc7a74ebd1561f0b476b0"
|
resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.9.3.tgz#8723c4f970442d4cdcedba5221579f9660a58bdb"
|
||||||
integrity sha512-vSQti1uG/2gjv3x6QLOZw7TctfufaerTWbVe+NSduHxxLGB+qf3kFgQ6n66DSnuoINtVUjrLLIK2R+lxrBG07A==
|
integrity sha512-WOUM7ghii5TV2rbhaZkh1youv/vW1/Canev6Yx6BG2W+1S07w8jKZqKkPnbiPpQEDsnJdN8ouDd7OvQEGXDcUw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@mapbox/node-pre-gyp" "^1.0.0"
|
"@mapbox/node-pre-gyp" "^1.0.0"
|
||||||
nan "^2.15.0"
|
nan "^2.15.0"
|
||||||
@@ -597,11 +602,6 @@ delegates@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
|
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
|
||||||
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
|
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
|
||||||
|
|
||||||
detect-libc@^1.0.3:
|
|
||||||
version "1.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
|
|
||||||
integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==
|
|
||||||
|
|
||||||
detect-libc@^2.0.0:
|
detect-libc@^2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd"
|
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd"
|
||||||
@@ -613,29 +613,31 @@ diff@^4.0.1:
|
|||||||
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
||||||
|
|
||||||
discord-api-types@^0.33.3:
|
discord-api-types@^0.33.3:
|
||||||
version "0.33.3"
|
version "0.33.5"
|
||||||
resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.33.3.tgz#882c39331871f619035917a1f80d486f605b3e7a"
|
resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.33.5.tgz#6548b70520f7b944c60984dca4ab58654d664a12"
|
||||||
integrity sha512-P3A1RJXKEDmGPHrFTN5+gYLsBPGUVGj+D3+fa3m0K/umc+LMfqGuEad+p7cNq7ry/icReVhS3bz9jvBvne/BRA==
|
integrity sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg==
|
||||||
|
|
||||||
discord-api-types@^0.35.0:
|
discord-api-types@^0.36.2:
|
||||||
version "0.35.0"
|
version "0.36.2"
|
||||||
resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.35.0.tgz#85c6ea95f27580ad13b7a08444b16cb31d41e5e2"
|
resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.36.2.tgz#2362bc544837be965ec99a5919f900c9699a7028"
|
||||||
integrity sha512-aaIbVgPk7OA3y/HdG00tRM2nB8B3sSPH6KXgamBLRrcAJEQ8XZJNNKeRr0WVzw/lprdpKHKuTNX1DNrYnD5cOw==
|
integrity sha512-TunPAvzwneK/m5fr4hxH3bMsrtI22nr9yjfHyo5NBGMjpsAauGNiGCmwoFf0oO3jSd2mZiKUvZwCKDaB166u2Q==
|
||||||
|
|
||||||
discord.js@^13.8.1:
|
discord.js@14.0.1:
|
||||||
version "13.8.1"
|
version "14.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-13.8.1.tgz#37627154a887ac395ca72dd814bc7366776bb90a"
|
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-14.0.1.tgz#2de95035294b361689ec1c9de935f0b6c21923b1"
|
||||||
integrity sha512-jOsD+4tEZWWx0RHVyH+FBcqoTrsL+d5Mm5p+ULQOdU0qSaxhLNkWYig+yDHNZoND7nlkXX3qi+BW+gO5erWylg==
|
integrity sha512-MZ2cvvk1WCpTUCLcchX5e/mBM22JCPAYle76qEuAfQfVTFdxE2YoKgRWMwWm6s/OJdkXyzglRWj405hg4vikEg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@discordjs/builders" "^0.14.0"
|
"@discordjs/builders" "^1.0.0"
|
||||||
"@discordjs/collection" "^0.7.0"
|
"@discordjs/collection" "^1.0.0"
|
||||||
"@sapphire/async-queue" "^1.3.1"
|
"@discordjs/rest" "^1.0.0"
|
||||||
"@types/node-fetch" "^2.6.1"
|
"@sapphire/snowflake" "^3.2.2"
|
||||||
"@types/ws" "^8.5.3"
|
"@types/ws" "^8.5.3"
|
||||||
discord-api-types "^0.33.3"
|
discord-api-types "^0.36.2"
|
||||||
form-data "^4.0.0"
|
fast-deep-equal "^3.1.3"
|
||||||
node-fetch "^2.6.1"
|
lodash.snakecase "^4.1.1"
|
||||||
ws "^8.7.0"
|
tslib "^2.4.0"
|
||||||
|
undici "^5.7.0"
|
||||||
|
ws "^8.8.1"
|
||||||
|
|
||||||
dotenv@^16.0.1:
|
dotenv@^16.0.1:
|
||||||
version "16.0.1"
|
version "16.0.1"
|
||||||
@@ -686,6 +688,15 @@ fecha@^4.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd"
|
resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd"
|
||||||
integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==
|
integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==
|
||||||
|
|
||||||
|
file-type@^17.1.2:
|
||||||
|
version "17.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/file-type/-/file-type-17.1.2.tgz#9257437a64e0c3623f70d9f27430522d978b1384"
|
||||||
|
integrity sha512-3thBUSfa9YEUEGO/NAAiQGvjujZxZiJTF6xNwyDn6kB0NcEtwMn5ttkGG9jGwm/Nt/t8U1bpBNqyBNZCz4F4ig==
|
||||||
|
dependencies:
|
||||||
|
readable-web-to-node-stream "^3.0.2"
|
||||||
|
strtok3 "^7.0.0-alpha.7"
|
||||||
|
token-types "^5.0.0-alpha.2"
|
||||||
|
|
||||||
fill-range@^7.0.1:
|
fill-range@^7.0.1:
|
||||||
version "7.0.1"
|
version "7.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||||
@@ -707,15 +718,6 @@ form-data@^3.0.0:
|
|||||||
combined-stream "^1.0.8"
|
combined-stream "^1.0.8"
|
||||||
mime-types "^2.1.12"
|
mime-types "^2.1.12"
|
||||||
|
|
||||||
form-data@^4.0.0:
|
|
||||||
version "4.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
|
|
||||||
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
|
|
||||||
dependencies:
|
|
||||||
asynckit "^0.4.0"
|
|
||||||
combined-stream "^1.0.8"
|
|
||||||
mime-types "^2.1.12"
|
|
||||||
|
|
||||||
formidable@^1.2.2:
|
formidable@^1.2.2:
|
||||||
version "1.2.6"
|
version "1.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.6.tgz#d2a51d60162bbc9b4a055d8457a7c75315d1a168"
|
resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.6.tgz#d2a51d60162bbc9b4a055d8457a7c75315d1a168"
|
||||||
@@ -764,13 +766,13 @@ get-caller-file@^2.0.5:
|
|||||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||||
|
|
||||||
get-intrinsic@^1.0.2:
|
get-intrinsic@^1.0.2:
|
||||||
version "1.1.1"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
|
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598"
|
||||||
integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==
|
integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==
|
||||||
dependencies:
|
dependencies:
|
||||||
function-bind "^1.1.1"
|
function-bind "^1.1.1"
|
||||||
has "^1.0.3"
|
has "^1.0.3"
|
||||||
has-symbols "^1.0.1"
|
has-symbols "^1.0.3"
|
||||||
|
|
||||||
glob-parent@~5.1.2:
|
glob-parent@~5.1.2:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
@@ -791,7 +793,7 @@ glob@^7.0.5, glob@^7.1.3:
|
|||||||
once "^1.3.0"
|
once "^1.3.0"
|
||||||
path-is-absolute "^1.0.0"
|
path-is-absolute "^1.0.0"
|
||||||
|
|
||||||
has-symbols@^1.0.1:
|
has-symbols@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
|
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
|
||||||
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
|
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
|
||||||
@@ -828,6 +830,11 @@ i18n@^0.15.0:
|
|||||||
math-interval-parser "^2.0.1"
|
math-interval-parser "^2.0.1"
|
||||||
mustache "^4.2.0"
|
mustache "^4.2.0"
|
||||||
|
|
||||||
|
ieee754@^1.2.1:
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||||
|
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||||
|
|
||||||
inflight@^1.0.4:
|
inflight@^1.0.4:
|
||||||
version "1.0.6"
|
version "1.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||||
@@ -853,7 +860,7 @@ is-binary-path@~2.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
binary-extensions "^2.0.0"
|
binary-extensions "^2.0.0"
|
||||||
|
|
||||||
is-core-module@^2.8.1:
|
is-core-module@^2.9.0:
|
||||||
version "2.9.0"
|
version "2.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69"
|
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69"
|
||||||
integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==
|
integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==
|
||||||
@@ -914,10 +921,20 @@ libsodium@^0.7.0:
|
|||||||
resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.10.tgz#c2429a7e4c0836f879d701fec2c8a208af024159"
|
resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.10.tgz#c2429a7e4c0836f879d701fec2c8a208af024159"
|
||||||
integrity sha512-eY+z7hDrDKxkAK+QKZVNv92A5KYkxfvIshtBJkmg5TSiCnYqZP3i9OO9whE79Pwgm4jGaoHgkM4ao/b9Cyu4zQ==
|
integrity sha512-eY+z7hDrDKxkAK+QKZVNv92A5KYkxfvIshtBJkmg5TSiCnYqZP3i9OO9whE79Pwgm4jGaoHgkM4ao/b9Cyu4zQ==
|
||||||
|
|
||||||
|
lodash.snakecase@^4.1.1:
|
||||||
|
version "4.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d"
|
||||||
|
integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==
|
||||||
|
|
||||||
|
lodash.uniqwith@^4.5.0:
|
||||||
|
version "4.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.uniqwith/-/lodash.uniqwith-4.5.0.tgz#7a0cbf65f43b5928625a9d4d0dc54b18cadc7ef3"
|
||||||
|
integrity sha512-7lYL8bLopMoy4CTICbxygAUq6CdRJ36vFc80DucPueUee+d5NBRxz3FdT9Pes/HEx5mPoT9jwnsEJWz1N7uq7Q==
|
||||||
|
|
||||||
logform@^2.2.0:
|
logform@^2.2.0:
|
||||||
version "2.4.1"
|
version "2.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/logform/-/logform-2.4.1.tgz#512c9eaef738044d1c619790ba0f806c80d9d3a9"
|
resolved "https://registry.yarnpkg.com/logform/-/logform-2.4.2.tgz#a617983ac0334d0c3b942c34945380062795b47c"
|
||||||
integrity sha512-7XB/tqc3VRbri9pRjU6E97mQ8vC27ivJ3lct4jhyT+n0JNDd4YKldFl0D75NqDp46hk8RC7Ma1Vjv/UPf67S+A==
|
integrity sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@colors/colors" "1.5.0"
|
"@colors/colors" "1.5.0"
|
||||||
fecha "^4.2.0"
|
fecha "^4.2.0"
|
||||||
@@ -926,9 +943,9 @@ logform@^2.2.0:
|
|||||||
triple-beam "^1.3.0"
|
triple-beam "^1.3.0"
|
||||||
|
|
||||||
logform@^2.3.2:
|
logform@^2.3.2:
|
||||||
version "2.4.0"
|
version "2.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/logform/-/logform-2.4.0.tgz#131651715a17d50f09c2a2c1a524ff1a4164bcfe"
|
resolved "https://registry.yarnpkg.com/logform/-/logform-2.4.1.tgz#512c9eaef738044d1c619790ba0f806c80d9d3a9"
|
||||||
integrity sha512-CPSJw4ftjf517EhXZGGvTHHkYobo7ZCc0kvwUoOYcjfR2UVrI66RHj8MCrfAdEitdmFqbu2BYdYs8FHHZSb6iw==
|
integrity sha512-7XB/tqc3VRbri9pRjU6E97mQ8vC27ivJ3lct4jhyT+n0JNDd4YKldFl0D75NqDp46hk8RC7Ma1Vjv/UPf67S+A==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@colors/colors" "1.5.0"
|
"@colors/colors" "1.5.0"
|
||||||
fecha "^4.2.0"
|
fecha "^4.2.0"
|
||||||
@@ -1005,9 +1022,9 @@ minimist@^1.2.6:
|
|||||||
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||||
|
|
||||||
minipass@^3.0.0:
|
minipass@^3.0.0:
|
||||||
version "3.1.6"
|
version "3.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee"
|
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.4.tgz#ca99f95dd77c43c7a76bf51e6d200025eee0ffae"
|
||||||
integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==
|
integrity sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==
|
||||||
dependencies:
|
dependencies:
|
||||||
yallist "^4.0.0"
|
yallist "^4.0.0"
|
||||||
|
|
||||||
@@ -1049,12 +1066,12 @@ nan@^2.14.0, nan@^2.15.0:
|
|||||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916"
|
resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916"
|
||||||
integrity sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==
|
integrity sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==
|
||||||
|
|
||||||
node-addon-api@^4.2.0:
|
node-addon-api@^5.0.0:
|
||||||
version "4.3.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f"
|
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.0.0.tgz#7d7e6f9ef89043befdb20c1989c905ebde18c501"
|
||||||
integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==
|
integrity sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==
|
||||||
|
|
||||||
node-fetch@^2.6.1, node-fetch@^2.6.5, node-fetch@^2.6.7:
|
node-fetch@^2.6.7:
|
||||||
version "2.6.7"
|
version "2.6.7"
|
||||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
|
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
|
||||||
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
|
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
|
||||||
@@ -1142,6 +1159,11 @@ path-parse@^1.0.7:
|
|||||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||||
|
|
||||||
|
peek-readable@^5.0.0-alpha.5:
|
||||||
|
version "5.0.0-alpha.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.0.0-alpha.5.tgz#ace5dfedf7bc33f17c9b5170b9d54f69a4fba79b"
|
||||||
|
integrity sha512-pJohF/tDwV3ntnT5+EkUo4E700q/j/OCDuPxtM+5/kFGjyOai/sK4/We4Cy1MB2OiTQliWU5DxPvYIKQAdPqAA==
|
||||||
|
|
||||||
picomatch@^2.0.4, picomatch@^2.2.1:
|
picomatch@^2.0.4, picomatch@^2.2.1:
|
||||||
version "2.3.1"
|
version "2.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
||||||
@@ -1172,12 +1194,12 @@ prism-media@^1.3.2:
|
|||||||
resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-1.3.2.tgz#a1f04423ec15d22f3d62b1987b6a25dc49aad13b"
|
resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-1.3.2.tgz#a1f04423ec15d22f3d62b1987b6a25dc49aad13b"
|
||||||
integrity sha512-L6UsGHcT6i4wrQhFF1aPK+MNYgjRqR2tUoIqEY+CG1NqVkMjPRKzS37j9f8GiYPlD6wG9ruBj+q5Ax+bH8Ik1g==
|
integrity sha512-L6UsGHcT6i4wrQhFF1aPK+MNYgjRqR2tUoIqEY+CG1NqVkMjPRKzS37j9f8GiYPlD6wG9ruBj+q5Ax+bH8Ik1g==
|
||||||
|
|
||||||
prisma@^3.15.2:
|
prisma@^4.0.0:
|
||||||
version "3.15.2"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/prisma/-/prisma-3.15.2.tgz#4ebe32fb284da3ac60c49fbc16c75e56ecf32067"
|
resolved "https://registry.yarnpkg.com/prisma/-/prisma-4.0.0.tgz#4ddb8fcd4f64d33aff8c198a6986dcce66dc8152"
|
||||||
integrity sha512-nMNSMZvtwrvoEQ/mui8L/aiCLZRCj5t6L3yujKpcDhIPk7garp8tL4nMx2+oYsN0FWBacevJhazfXAbV1kfBzA==
|
integrity sha512-Dtsar03XpCBkcEb2ooGWO/WcgblDTLzGhPcustbehwlFXuTMliMDRzXsfygsgYwQoZnAUKRd1rhpvBNEUziOVw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@prisma/engines" "3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e"
|
"@prisma/engines" "3.16.0-49.da41d2bb3406da22087b849f0e911199ba4fbf11"
|
||||||
|
|
||||||
process-nextick-args@~2.0.0:
|
process-nextick-args@~2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
@@ -1190,9 +1212,9 @@ q@1.x:
|
|||||||
integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==
|
integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==
|
||||||
|
|
||||||
qs@^6.9.4:
|
qs@^6.9.4:
|
||||||
version "6.10.3"
|
version "6.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e"
|
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
|
||||||
integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==
|
integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
side-channel "^1.0.4"
|
side-channel "^1.0.4"
|
||||||
|
|
||||||
@@ -1208,7 +1230,7 @@ readable-stream@^3.4.0, readable-stream@^3.6.0:
|
|||||||
readable-stream@~1.0.31:
|
readable-stream@~1.0.31:
|
||||||
version "1.0.34"
|
version "1.0.34"
|
||||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
|
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
|
||||||
integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=
|
integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==
|
||||||
dependencies:
|
dependencies:
|
||||||
core-util-is "~1.0.0"
|
core-util-is "~1.0.0"
|
||||||
inherits "~2.0.1"
|
inherits "~2.0.1"
|
||||||
@@ -1228,6 +1250,13 @@ readable-stream@~2.3.6:
|
|||||||
string_decoder "~1.1.1"
|
string_decoder "~1.1.1"
|
||||||
util-deprecate "~1.0.1"
|
util-deprecate "~1.0.1"
|
||||||
|
|
||||||
|
readable-web-to-node-stream@^3.0.2:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb"
|
||||||
|
integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==
|
||||||
|
dependencies:
|
||||||
|
readable-stream "^3.6.0"
|
||||||
|
|
||||||
readdirp@~3.6.0:
|
readdirp@~3.6.0:
|
||||||
version "3.6.0"
|
version "3.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
||||||
@@ -1238,14 +1267,14 @@ readdirp@~3.6.0:
|
|||||||
require-directory@^2.1.1:
|
require-directory@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||||
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
|
||||||
|
|
||||||
resolve@^1.0.0:
|
resolve@^1.0.0:
|
||||||
version "1.22.0"
|
version "1.22.1"
|
||||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
|
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
|
||||||
integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
|
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
|
||||||
dependencies:
|
dependencies:
|
||||||
is-core-module "^2.8.1"
|
is-core-module "^2.9.0"
|
||||||
path-parse "^1.0.7"
|
path-parse "^1.0.7"
|
||||||
supports-preserve-symlinks-flag "^1.0.0"
|
supports-preserve-symlinks-flag "^1.0.0"
|
||||||
|
|
||||||
@@ -1298,7 +1327,7 @@ semver@^7.3.2, semver@^7.3.5:
|
|||||||
set-blocking@^2.0.0:
|
set-blocking@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||||
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
|
||||||
|
|
||||||
side-channel@^1.0.4:
|
side-channel@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
@@ -1331,7 +1360,7 @@ simple-get@^3.0.3:
|
|||||||
simple-swizzle@^0.2.2:
|
simple-swizzle@^0.2.2:
|
||||||
version "0.2.2"
|
version "0.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
|
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
|
||||||
integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=
|
integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==
|
||||||
dependencies:
|
dependencies:
|
||||||
is-arrayish "^0.3.1"
|
is-arrayish "^0.3.1"
|
||||||
|
|
||||||
@@ -1351,7 +1380,7 @@ source-map@^0.6.0:
|
|||||||
stack-trace@0.0.x:
|
stack-trace@0.0.x:
|
||||||
version "0.0.10"
|
version "0.0.10"
|
||||||
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
|
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
|
||||||
integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=
|
integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==
|
||||||
|
|
||||||
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||||
version "4.2.3"
|
version "4.2.3"
|
||||||
@@ -1372,7 +1401,7 @@ string_decoder@^1.1.1:
|
|||||||
string_decoder@~0.10.x:
|
string_decoder@~0.10.x:
|
||||||
version "0.10.31"
|
version "0.10.31"
|
||||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
|
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
|
||||||
integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
|
integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==
|
||||||
|
|
||||||
string_decoder@~1.1.1:
|
string_decoder@~1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
@@ -1391,12 +1420,20 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
|||||||
strip-bom@^3.0.0:
|
strip-bom@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||||
integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
|
integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
|
||||||
|
|
||||||
strip-json-comments@^2.0.0:
|
strip-json-comments@^2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||||
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
|
integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
|
||||||
|
|
||||||
|
strtok3@^7.0.0-alpha.7:
|
||||||
|
version "7.0.0-alpha.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-7.0.0-alpha.8.tgz#23a7870974e0494b58b14af6dd1c2c67cf13314d"
|
||||||
|
integrity sha512-u+k19v+rTxBjGYxncRQjGvZYwYvEd0uP3D+uHKe/s4WB1eXS5ZwpZsTlBu5xSS4zEd89mTXECXg6WW3FSeV8cA==
|
||||||
|
dependencies:
|
||||||
|
"@tokenizer/token" "^0.3.0"
|
||||||
|
peek-readable "^5.0.0-alpha.5"
|
||||||
|
|
||||||
superagent@^5.2.1:
|
superagent@^5.2.1:
|
||||||
version "5.3.1"
|
version "5.3.1"
|
||||||
@@ -1457,10 +1494,18 @@ to-regex-range@^5.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-number "^7.0.0"
|
is-number "^7.0.0"
|
||||||
|
|
||||||
|
token-types@^5.0.0-alpha.2:
|
||||||
|
version "5.0.0-alpha.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/token-types/-/token-types-5.0.0-alpha.2.tgz#e43d63b2a8223a593d1c782a5149bec18f1abf97"
|
||||||
|
integrity sha512-EsG9UxAW4M6VATrEEjhPFTKEUi1OiJqTUMIZOGBN49fGxYjZB36k0p7to3HZSmWRoHm1QfZgrg3e02fpqAt5fQ==
|
||||||
|
dependencies:
|
||||||
|
"@tokenizer/token" "^0.3.0"
|
||||||
|
ieee754 "^1.2.1"
|
||||||
|
|
||||||
tr46@~0.0.3:
|
tr46@~0.0.3:
|
||||||
version "0.0.3"
|
version "0.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||||
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
|
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
|
||||||
|
|
||||||
tree-kill@^1.2.2:
|
tree-kill@^1.2.2:
|
||||||
version "1.2.2"
|
version "1.2.2"
|
||||||
@@ -1543,9 +1588,14 @@ underscore@^1.12.0:
|
|||||||
integrity sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==
|
integrity sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==
|
||||||
|
|
||||||
undici@^5.4.0:
|
undici@^5.4.0:
|
||||||
version "5.4.0"
|
version "5.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/undici/-/undici-5.4.0.tgz#c474fae02743d4788b96118d46008a24195024d2"
|
resolved "https://registry.yarnpkg.com/undici/-/undici-5.5.1.tgz#baaf25844a99eaa0b22e1ef8d205bffe587c8f43"
|
||||||
integrity sha512-A1SRXysDg7J+mVP46jF+9cKANw0kptqSFZ8tGyL+HBiv0K1spjxPX8Z4EGu+Eu6pjClJUBdnUPlxrOafR668/g==
|
integrity sha512-MEvryPLf18HvlCbLSzCW0U00IMftKGI5udnjrQbC5D4P0Hodwffhv+iGfWuJwg16Y/TK11ZFK8i+BPVW2z/eAw==
|
||||||
|
|
||||||
|
undici@^5.7.0:
|
||||||
|
version "5.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/undici/-/undici-5.7.0.tgz#979f89229c01505573cb274d0e11ea8d82b4004f"
|
||||||
|
integrity sha512-ORgxwDkiPS+gK2VxE7iyVeR7JliVn5DqhZ4LgQqYLBXsuK+lwOEmnJ66dhvlpLM0tC3fC7eYF1Bti2frbw2eAA==
|
||||||
|
|
||||||
untildify@^4.0.0:
|
untildify@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
@@ -1562,7 +1612,7 @@ utf-8-validate@^5.0.9:
|
|||||||
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
|
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
|
||||||
|
|
||||||
v8-compile-cache-lib@^3.0.1:
|
v8-compile-cache-lib@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
@@ -1577,12 +1627,12 @@ validator@^13.7.0:
|
|||||||
webidl-conversions@^3.0.0:
|
webidl-conversions@^3.0.0:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
||||||
integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
|
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
|
||||||
|
|
||||||
whatwg-url@^5.0.0:
|
whatwg-url@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
||||||
integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
|
integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
|
||||||
dependencies:
|
dependencies:
|
||||||
tr46 "~0.0.3"
|
tr46 "~0.0.3"
|
||||||
webidl-conversions "^3.0.0"
|
webidl-conversions "^3.0.0"
|
||||||
@@ -1630,12 +1680,17 @@ wrap-ansi@^7.0.0:
|
|||||||
wrappy@1:
|
wrappy@1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
|
||||||
|
|
||||||
ws@^8.7.0:
|
ws@^8.7.0:
|
||||||
version "8.7.0"
|
version "8.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.7.0.tgz#eaf9d874b433aa00c0e0d8752532444875db3957"
|
resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.0.tgz#8e71c75e2f6348dbf8d78005107297056cb77769"
|
||||||
integrity sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==
|
integrity sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==
|
||||||
|
|
||||||
|
ws@^8.8.1:
|
||||||
|
version "8.8.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0"
|
||||||
|
integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==
|
||||||
|
|
||||||
xtend@^4.0.0, xtend@~4.0.1:
|
xtend@^4.0.0, xtend@~4.0.1:
|
||||||
version "4.0.2"
|
version "4.0.2"
|
||||||
|
|||||||
Reference in New Issue
Block a user