Repository: henriqueclaranhan/telegram-music-downloader-bot Branch: master Commit: 9f1daa6750e5 Files: 11 Total size: 8.3 KB Directory structure: gitextract_dhrpt8st/ ├── .dockerignore ├── .gitignore ├── Dockerfile ├── LICENSE ├── Procfile ├── README.md ├── app.json ├── bot.py ├── heroku.yml ├── requirements.txt └── sample.env ================================================ FILE CONTENTS ================================================ ================================================ FILE: .dockerignore ================================================ README.md .git/ __pycache__/ sample.env ================================================ FILE: .gitignore ================================================ .env tests/ ================================================ FILE: Dockerfile ================================================ FROM debian:latest RUN apt update && apt upgrade -y RUN apt install git ffmpeg python3-pip -y RUN pip3 install -U pip RUN mkdir /app/ WORKDIR /app/ COPY . /app/ RUN pip3 install -U -r requirements.txt CMD python3 bot.py ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2021 Henrique Claranhan de Oliveira Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Procfile ================================================ worker: python3 bot.py ================================================ FILE: README.md ================================================
================================================
FILE: app.json
================================================
{
"name": "telegram-music-downloader-bot",
"description": "YouTube Music Downloader Bot for Telegram. ",
"stack": "container",
"repository": "https://github.com/henriqueclaranhan/telegram-music-downloader-bot",
"keywords": [
"python",
"chatbot",
"telegrambot"
],
"website": "https://github.com/henriqueclaranhan/telegram-music-downloader-bot",
"success_url": "https://t.me/tlmusicdownloader_bot",
"env": {
"TOKEN": {
"description": "Make a bot at BotFather http://telegram.dog/BotFather and get the token of your bot",
"value": "",
"required": true
}
}
}
================================================
FILE: bot.py
================================================
import os
import youtube_dl
import telepotpro
from random import randint
from multiprocessing import Process
from youtubesearchpython import VideosSearch
from dotenv import load_dotenv
from os.path import join, dirname
dotenv_path = join(dirname(__file__), '.env')
load_dotenv(dotenv_path)
TOKEN = os.environ.get("TOKEN")
bot = telepotpro.Bot(TOKEN)
class Music:
def __init__(self, user_input, msg):
self.chat = Chat
self.user_input = user_input[6:]
def search_music(self, user_input):
return VideosSearch(user_input, limit = 1).result()
def get_link(self, result):
return result['result'][0]['link']
def get_title(self, result):
return result['result'][0]['title']
def get_duration(self, result):
result = result['result'][0]['duration'].split(':')
min_duration = int(result[0])
split_count = len(result)
return min_duration, split_count
def download_music(self, file_name, link):
ydl_opts = {
'outtmpl': './'+file_name,
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '256',
}],
'prefer_ffmpeg': True
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
info_dict = ydl.extract_info(link, download=True)
pass
class Chat:
def __init__(self, msg):
self.chat_id = msg['chat']['id']
self.user_input = msg['text']
self.user_input = self.user_input.replace('@TLMusicDownloader_bot', '')
self.user_name = msg['from']['first_name']
self.message_id = msg['message_id']
self.messages = {
'start':'🤖 Hello, '+ self.user_name +'!\n\n'
'📩 Send me:\n\n'
'"*/music* _song name_" or\n'
'"*/music* _musician name - song name_"\n\n'
'to order some music. 🎶',
'spotify_input_error':"‼️ *Oops! The bot doesn't support Spotify links!*\n"
'Try: "*/music* _song name_"\n'
'or: "*/music* _musician name - song name_"',
'invalid_command':'‼️ *Oops! Invalid command!*\n'
'Try: "*/music* _song name_"\n'
'or: "*/music* _musician name - song name_"',
'too_long':'‼️ *Oops! Video too long to convert!*\n'
'Order something 30 minutes or less.'
}
self.check_input(self.user_input, msg)
pass
def send_message(self, content):
return bot.sendMessage(self.chat_id, content, reply_to_message_id=self.message_id, parse_mode='Markdown')
def delete_message(self, message):
chat_id = message['chat']['id']
message_id = message['message_id']
bot.deleteMessage((chat_id, message_id))
pass
def send_audio(self, file_name):
bot.sendAudio(self.chat_id,audio=open(file_name,'rb'), reply_to_message_id=self.message_id)
pass
def process_request(self, user_input):
result = Music.search_music(self, user_input[6:])
min_duration, split_count = Music.get_duration(self, result)
if int(min_duration) < 30 and split_count < 3:
file_name = Music.get_title(self, result) +' - @TLMusicDownloader_bot '+str(randint(0,999999))+'.mp3'
file_name = file_name.replace('"', '')
self.send_message(f"🎵 {Music.get_title(self, result)}\n🔗 {Music.get_link(self, result)}")
downloading_message = self.send_message('⬇️ Downloading... \n_(this may take a while.)_')
Music.download_music(self, file_name, Music.get_link(self, result))
try:
self.send_audio(file_name)
self.delete_message(downloading_message)
self.send_message('✅ Sucess!')
print ("\nSucess!\n")
except:
print("\nError")
os.remove(file_name)
pass
def check_input(self, user_input, msg):
if user_input.startswith('/start'):
self.send_message(self.messages['start'])
elif user_input.startswith('/music') and user_input[6:]!='':
if 'open.spotify.com' in user_input[6:]:
self.send_message(self.messages['spotify_input_error'])
else:
#Valid command
self.process_request(user_input)
else:
#Invalid command
self.send_message(self.messages['invalid_command'])
pass
def start_new_chat(msg):
Process(target=Chat, args=(msg,)).start()
bot.message_loop(start_new_chat, run_forever=True)
================================================
FILE: heroku.yml
================================================
build:
docker:
worker: Dockerfile
run:
worker:
command:
- python3 bot.py
image: worker
================================================
FILE: requirements.txt
================================================
youtube-dl
telepotpro
youtube-search-python
python-dotenv
================================================
FILE: sample.env
================================================
TOKEN = "INSERT_YOUR_TOKEN_HERE"