mirror of
https://github.com/thewesker/Video-Archive-Discord-Bot.git
synced 2025-12-20 04:11:05 -05:00
Video Archive Discord Bot
First commit. All changes to convert the bot into a video archive discord bot.
This commit is contained in:
22
README.md
22
README.md
@@ -1,23 +1,25 @@
|
|||||||
# TikBot
|
# Video Archive Discord Bot
|
||||||
A super simple Discord bot designed for helping you share TikToks without actually having to have your friends open TikTok.
|
A super simple Discord bot designed for helping you archive videos posted to your channels.
|
||||||
|
|
||||||
TikBot will download any TikTok (or other supported link in youtube-dl) linked in a Discord channel it is in, and post the video file directly.
|
Video Archive Discord Bot will download any video from YouTube, Instagram, Tik Tok, and Reddit linked in a Discord channel it is in, and post the video file directly in a designated channel.
|
||||||
In cases where the file is too large for Discord's free tier, the video will be compressed to fit first.
|
In cases where the file is too large for Discord's free tier, the video will be compressed to fit first.
|
||||||
|
|
||||||
# Installation & Usage
|
# Installation & Usage
|
||||||
Requirements: Python 2/3
|
Requirements: Python 3
|
||||||
|
|
||||||
1. Set Discord access token into ```.env``` as ```TOKEN=$yourTokenGoesHere```
|
1. Set Discord access token in ```.env``` as ```TOKEN=$yourTokenGoesHere```
|
||||||
|
|
||||||
2. Add the bot to the Discord server you wish to run it in.
|
2. Make a video archive channel in your discord server.
|
||||||
|
|
||||||
3. Setup any channel in the Discord server with a name starting with ```tik-tok```
|
3. Set Archive channel ID in ```.env``` as ```ARCHIVE=$yourChannelIDGoesHere```. You can get this ID by right clicking on the channel and clicking "Copy ID".
|
||||||
|
|
||||||
4. Ensure the bot has permission to post attachments and messages in the channel.
|
4. Add the bot to the Discord server you wish to run it in.
|
||||||
|
|
||||||
|
5. Ensure the bot has permission to post attachments and messages in the channel.
|
||||||
|
|
||||||
5. Install required packages with ```pip install -r requirements.txt ```
|
6. Install required packages with ```pip install -r requirements.txt ```
|
||||||
|
|
||||||
6. Run the bot ```python main.py```
|
7. Run the bot ```python main.py```
|
||||||
|
|
||||||
# Notes
|
# Notes
|
||||||
Not recommended to be available as a public bot due to the bandwidth and processing requirements of downloading and encoding videos.
|
Not recommended to be available as a public bot due to the bandwidth and processing requirements of downloading and encoding videos.
|
||||||
|
|||||||
43
main.py
43
main.py
@@ -36,7 +36,7 @@ async def on_message(message):
|
|||||||
print("Downloaded: " + fileName + " For User: " + str(message.author))
|
print("Downloaded: " + fileName + " For User: " + str(message.author))
|
||||||
|
|
||||||
if(messages.startswith("Error")):
|
if(messages.startswith("Error")):
|
||||||
await message.author.send('TikBot has failed you. Consider berating my human if this was not expected.\nMessage: ' + messages)
|
## await message.author.send('TikBot has failed you. Consider berating my human if this was not expected.\nMessage: ' + messages)
|
||||||
return
|
return
|
||||||
|
|
||||||
audioFilename = "audio_" + fileName + ".mp3"
|
audioFilename = "audio_" + fileName + ".mp3"
|
||||||
@@ -52,34 +52,36 @@ async def on_message(message):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Only do anything in TikTok channels
|
# Only do anything in TikTok channels
|
||||||
if(not message.channel.name.startswith("tik-tok")):
|
# if(not message.channel.name.startswith("tik-tok")):
|
||||||
return
|
# return
|
||||||
|
|
||||||
# Be polite!
|
# Be polite!
|
||||||
if message.content.startswith('$hello'):
|
# if message.content.startswith('$hello'):
|
||||||
await message.channel.send('Hello!')
|
# await message.channel.send('Hello!')
|
||||||
|
|
||||||
# Extract and validate the request
|
# Extract and validate the request
|
||||||
extractResponse = extractUrl(message.content)
|
extractResponse = extractUrl(message.content)
|
||||||
url = extractResponse["url"]
|
url = extractResponse["url"]
|
||||||
messages = extractResponse['messages']
|
messages = extractResponse['messages']
|
||||||
if(messages.startswith("Error")):
|
if(messages.startswith("Error")):
|
||||||
await message.channel.send('TikBot encountered an error determing a URL. Consider berating my human if this was not expected.\nMessage: ' + messages)
|
## await message.channel.send('TikBot encountered an error determing a URL. Consider berating my human if this was not expected.\nMessage: ' + messages)
|
||||||
return
|
return
|
||||||
|
|
||||||
print("Got URL: " + url + " For User: " + str(message.author))
|
# print("Got URL: " + url + " For User: " + str(message.author))
|
||||||
if('🤖' not in message.content):
|
if('🤖' not in message.content):
|
||||||
# Validate unless we've been reqeuested not to
|
# Validate unless we've been reqeuested not to
|
||||||
validateResponse = isSupportedUrl(url)
|
validateResponse = isSupportedUrl(url)
|
||||||
messages = validateResponse['messages']
|
messages = validateResponse['messages']
|
||||||
if(messages.startswith("Error")):
|
if(messages.startswith("Error")):
|
||||||
await message.channel.send('TikBot encountered an error validating the URL. Consider berating my human if this was not expected.\nMessage: ' + messages)
|
## await message.channel.send('TikBot encountered an error validating the URL. Consider berating my human if this was not expected.\nMessage: ' + messages)
|
||||||
return
|
return
|
||||||
if(validateResponse['supported'] == 'false'):
|
if(validateResponse['supported'] == 'false'):
|
||||||
# Unsupported URL, return silently without doing anything
|
# Unsupported URL, return silently without doing anything
|
||||||
return
|
return
|
||||||
|
ARCHIVE_CHANNEL = int(os.getenv('ARCHIVE'))
|
||||||
await message.channel.send('TikBot downloading video now!')
|
channel = client.get_channel(ARCHIVE_CHANNEL)
|
||||||
|
sent_message = await message.channel.send("Downloading and processing video now. It will be available to view in " + str(channel.mention) + " soon. If it's a long video, the length may be shortened.")
|
||||||
|
await sent_message.delete(delay=3)
|
||||||
downloadResponse = download(url)
|
downloadResponse = download(url)
|
||||||
fileName = downloadResponse['fileName']
|
fileName = downloadResponse['fileName']
|
||||||
duration = downloadResponse['duration']
|
duration = downloadResponse['duration']
|
||||||
@@ -88,21 +90,26 @@ async def on_message(message):
|
|||||||
print("Downloaded: " + fileName + " For User: " + str(message.author))
|
print("Downloaded: " + fileName + " For User: " + str(message.author))
|
||||||
|
|
||||||
if(messages.startswith("Error")):
|
if(messages.startswith("Error")):
|
||||||
await message.channel.send('TikBot has failed you. Consider berating my human if this was not expected.\nMessage: ' + messages)
|
## await message.channel.send('TikBot has failed you. Consider berating my human if this was not expected.\nMessage: ' + messages)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check file size, if it's small enough just send it!
|
# Check file size, if it's small enough just send it!
|
||||||
fileSize = os.stat(fileName).st_size
|
fileSize = os.stat(fileName).st_size
|
||||||
|
message_author = str(message.author)
|
||||||
|
vid_details = "Video posted by <@!" + str(message.author.id) + "> at " + str(message.created_at) + " in " + str(message.channel.mention) + " " + str(message.jump_url)
|
||||||
if(fileSize < 8000000):
|
if(fileSize < 8000000):
|
||||||
with open(fileName, 'rb') as fp:
|
with open(fileName, 'rb') as fp:
|
||||||
await message.channel.send(file=discord.File(fp, str(fileName)))
|
print(vid_details)
|
||||||
|
channel = client.get_channel(ARCHIVE_CHANNEL)
|
||||||
|
video_archive_msg = await channel.send(vid_details, file=discord.File(fp, str(fileName)))
|
||||||
|
vid_msg_id = await message.channel.send("Video archived: " + str(video_archive_msg.jump_url))
|
||||||
|
await vid_msg_id.delete(delay=300)
|
||||||
os.remove(fileName)
|
os.remove(fileName)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# We need to compress the file below 8MB or discord will make a sad
|
# We need to compress the file below 8MB or discord will make a sad
|
||||||
compressionMessage = getCompressionMessage()
|
# compressionMessage = getCompressionMessage()
|
||||||
await message.channel.send(compressionMessage)
|
# await channel.send(compressionMessage)
|
||||||
print("Duration = " + str(duration))
|
print("Duration = " + str(duration))
|
||||||
# Give us 7MB files with VBR encoding to allow for some overhead
|
# Give us 7MB files with VBR encoding to allow for some overhead
|
||||||
bitrateKilobits = 0
|
bitrateKilobits = 0
|
||||||
@@ -114,7 +121,11 @@ async def on_message(message):
|
|||||||
print("Calced bitrate = " + str(bitrateKilobits))
|
print("Calced bitrate = " + str(bitrateKilobits))
|
||||||
ffmpeg.input(fileName).output("small_" + fileName, **{'b:v': str(bitrateKilobits) + 'k', 'b:a': '64k', 'fs': '8M', 'threads': '4'}).run()
|
ffmpeg.input(fileName).output("small_" + fileName, **{'b:v': str(bitrateKilobits) + 'k', 'b:a': '64k', 'fs': '8M', 'threads': '4'}).run()
|
||||||
with open("small_" + fileName, 'rb') as fp:
|
with open("small_" + fileName, 'rb') as fp:
|
||||||
await message.channel.send(file=discord.File(fp, str("small_" + fileName)))
|
channel = client.get_channel(ARCHIVE_CHANNEL)
|
||||||
|
print(vid_details)
|
||||||
|
video_archive_msg = await channel.send(vid_details, file=discord.File(fp, str("small_" + fileName)))
|
||||||
|
vid_msg_id = await message.channel.send("Video archived: " + str(video_archive_msg.jump_url))
|
||||||
|
await vid_msg_id.delete(delay=60)
|
||||||
# Delete the compressed and original file
|
# Delete the compressed and original file
|
||||||
os.remove(fileName)
|
os.remove(fileName)
|
||||||
os.remove("small_" + fileName)
|
os.remove("small_" + fileName)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ def extractUrl(inputString):
|
|||||||
def isSupportedUrl(url):
|
def isSupportedUrl(url):
|
||||||
response = {'url': '', 'supported': 'false', 'messages': ''}
|
response = {'url': '', 'supported': 'false', 'messages': ''}
|
||||||
|
|
||||||
supportedDomains = ['youtube', 'tiktok', 'instagram', 'reddit', 'redd.it']
|
supportedDomains = ['youtube', 'youtu.be', 'tiktok', 'instagram', 'reddit', 'redd.it']
|
||||||
|
|
||||||
for domain in supportedDomains:
|
for domain in supportedDomains:
|
||||||
if(domain in url):
|
if(domain in url):
|
||||||
@@ -27,6 +27,6 @@ def isSupportedUrl(url):
|
|||||||
|
|
||||||
# We only reach here if the URL isn't supported
|
# We only reach here if the URL isn't supported
|
||||||
response['messages'] = "Information: Supplied URL is not a supported domain. To force TikBot to attempt it anyway, include a '🤖' in your message."
|
response['messages'] = "Information: Supplied URL is not a supported domain. To force TikBot to attempt it anyway, include a '🤖' in your message."
|
||||||
print(response['messages'])
|
# print(response['messages'])
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user