[
  {
    "path": ".dockerignore",
    "content": "README.md\n.git/\n__pycache__/\nsample.env\n"
  },
  {
    "path": ".gitignore",
    "content": ".env\ntests/"
  },
  {
    "path": "Dockerfile",
    "content": "FROM debian:latest\n\t\nRUN apt update && apt upgrade -y\nRUN apt install git ffmpeg python3-pip -y\nRUN pip3 install -U pip\nRUN mkdir /app/\nWORKDIR /app/\nCOPY . /app/\nRUN pip3 install -U -r requirements.txt\nCMD python3 bot.py\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 Henrique Claranhan de Oliveira\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "Procfile",
    "content": "worker: python3 bot.py\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n  <img src=\"https://github.com/henriqueclaranhan/telegram-music-downloader-bot/blob/master/icon.png\" width=\"190\">\n  <h1>Telegram Music Downloader Bot</h1>\n  A Telegram bot to download music from YouTube. Click <a href=\"https://t.me/TLMusicDownloader_bot\">@TLMusicDownloader_bot</a> to use.\n</div>\n\n## :arrow_down: Installation\nTo get a local copy installed and working, follow these steps:\n\n - Clone this repository\n\n    ```console\n    git clone https://github.com/henriqueclaranhan/telegram-music-downloader-bot.git\n    ```\n    \n - Enter the project folder\n\n    ```sh\n    cd telegram-music-downloader-bot\n    ```\n\n### 📦 Install dependencies\n\n- Install telepotpro framework\n\n        pip3 install telepotpro\n\n - Install youtube-dl\n\n        pip3 install youtube-dl\n\n - Install youtube-search-python\n \n        pip3 install youtube-search-python\n\n### 🚀 Setup the bot\n\n 1. Get the token from <a href=\"https://t.me/BotFather\">@BotFather</a>\n\n 2. Insert your token in the `sample.env` file\n\n    ```py\n    TOKEN = \"INSERT_YOUR_TOKEN_HERE\"\n    ```\n\n 3. Rename `sample.env` to `.env`\n\n 4. Start the bot\n\n    ```shell\n    python3 bot.py\n    ```\n\n\n\n## 🟪 Deploy on Heroku\n\n[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/henriqueclaranhan/telegram-music-downloader-bot)\n\n\n## 📷 Screenshot\n\n<img src=\"https://user-images.githubusercontent.com/58452863/134260965-005e32f3-27aa-435e-81c9-70b50cf1a8f1.png\" alt=\"Screenshot\" width=\"305\" height=\"700\">\n\n\n"
  },
  {
    "path": "app.json",
    "content": "{\n  \"name\": \"telegram-music-downloader-bot\",\n  \"description\": \"YouTube Music Downloader Bot for Telegram. \",\n\t\"stack\": \"container\",\n  \"repository\": \"https://github.com/henriqueclaranhan/telegram-music-downloader-bot\",\n  \"keywords\": [\n  \"python\", \n  \"chatbot\", \n  \"telegrambot\"\n  ],\n  \"website\": \"https://github.com/henriqueclaranhan/telegram-music-downloader-bot\",\n  \"success_url\": \"https://t.me/tlmusicdownloader_bot\",\n  \"env\": {\n    \"TOKEN\": {\n      \"description\": \"Make a bot at BotFather http://telegram.dog/BotFather and get the token of your bot\",\n      \"value\": \"\",\n      \"required\": true\n    }\n  }\n}\n"
  },
  {
    "path": "bot.py",
    "content": "import os\nimport youtube_dl\nimport telepotpro\nfrom random import randint\nfrom multiprocessing import Process\nfrom youtubesearchpython import VideosSearch\nfrom dotenv import load_dotenv\nfrom os.path import join, dirname\n\ndotenv_path = join(dirname(__file__), '.env')\nload_dotenv(dotenv_path)\n\nTOKEN = os.environ.get(\"TOKEN\")\nbot = telepotpro.Bot(TOKEN)\n\nclass Music:\n    def __init__(self, user_input, msg):\n        self.chat = Chat\n        self.user_input = user_input[6:]\n\n    def search_music(self, user_input):\n        return VideosSearch(user_input, limit = 1).result()\n\n    def get_link(self, result):\n        return result['result'][0]['link']\n\n    def get_title(self, result):\n        return result['result'][0]['title']\n\n    def get_duration(self, result):\n        result = result['result'][0]['duration'].split(':')\n        min_duration = int(result[0])\n        split_count = len(result)\n        \n        return min_duration, split_count\n\n    def download_music(self, file_name, link):\n        ydl_opts = {\n            'outtmpl': './'+file_name,\n            'format': 'bestaudio/best',\n            'postprocessors': [{\n                'key': 'FFmpegExtractAudio',\n                'preferredcodec': 'mp3',\n                'preferredquality': '256',\n            }],\n            'prefer_ffmpeg': True\n        }\n\n        with youtube_dl.YoutubeDL(ydl_opts) as ydl:\n            info_dict = ydl.extract_info(link, download=True)\n\n        pass\n\nclass Chat:\n    def __init__(self, msg):\n        self.chat_id = msg['chat']['id']\n        self.user_input = msg['text']\n        self.user_input = self.user_input.replace('@TLMusicDownloader_bot', '')\n        self.user_name = msg['from']['first_name']\n        self.message_id = msg['message_id']\n\n        self.messages = {\n            'start':'🤖 Hello, '+ self.user_name +'!\\n\\n'\n                    '📩 Send me:\\n\\n'\n                    '\"*/music* _song name_\"  or\\n'\n                    '\"*/music* _musician name - song name_\"\\n\\n'\n                    'to order some music. 🎶',\n            \n            'spotify_input_error':\"‼️ *Oops! The bot doesn't support Spotify links!*\\n\"\n                    'Try: \"*/music* _song name_\"\\n'\n                    'or: \"*/music* _musician name - song name_\"',\n\n            'invalid_command':'‼️ *Oops! Invalid command!*\\n'\n                    'Try: \"*/music* _song name_\"\\n'\n                    'or: \"*/music* _musician name - song name_\"',\n\n            'too_long':'‼️ *Oops! Video too long to convert!*\\n'\n                    'Order something 30 minutes or less.'\n\n\n        }\n\n        self.check_input(self.user_input, msg)\n\n        pass\n\n    def send_message(self, content):\n        return bot.sendMessage(self.chat_id, content, reply_to_message_id=self.message_id, parse_mode='Markdown')\n\n    def delete_message(self, message):\n        chat_id = message['chat']['id']\n        message_id = message['message_id']\n        bot.deleteMessage((chat_id, message_id))\n\n        pass\n\n    def send_audio(self, file_name):\n        bot.sendAudio(self.chat_id,audio=open(file_name,'rb'), reply_to_message_id=self.message_id)\n\n        pass\n\n    def process_request(self, user_input):\n        result = Music.search_music(self, user_input[6:])\n\n        min_duration, split_count = Music.get_duration(self, result)\n\n        if int(min_duration) < 30 and split_count < 3:\n            file_name = Music.get_title(self, result) +' - @TLMusicDownloader_bot '+str(randint(0,999999))+'.mp3'\n            file_name = file_name.replace('\"', '')\n\n            self.send_message(f\"🎵 {Music.get_title(self, result)}\\n🔗 {Music.get_link(self, result)}\")\n            downloading_message = self.send_message('⬇️ Downloading... \\n_(this may take a while.)_')\n\n            Music.download_music(self, file_name, Music.get_link(self, result))\n\n            try:\n                self.send_audio(file_name)\n                self.delete_message(downloading_message)\n                self.send_message('✅ Sucess!')\n                print (\"\\nSucess!\\n\")\n            except:\n                print(\"\\nError\")\n\n            os.remove(file_name)\n        pass\n\n    def check_input(self, user_input, msg):\n        if user_input.startswith('/start'):\n            self.send_message(self.messages['start'])\n\n        elif user_input.startswith('/music') and user_input[6:]!='':\n            if 'open.spotify.com' in user_input[6:]:\n                self.send_message(self.messages['spotify_input_error'])\n\n            else:\n                #Valid command\n                self.process_request(user_input)\n\n        else:\n            #Invalid command\n            self.send_message(self.messages['invalid_command'])\n\n        pass \n\ndef start_new_chat(msg):\n    Process(target=Chat, args=(msg,)).start()\n    \n\nbot.message_loop(start_new_chat, run_forever=True)\n"
  },
  {
    "path": "heroku.yml",
    "content": "build:\n  docker:\n    worker: Dockerfile\nrun:\n  worker:\n    command:\n      - python3 bot.py\n    image: worker\n"
  },
  {
    "path": "requirements.txt",
    "content": "youtube-dl\ntelepotpro\nyoutube-search-python\npython-dotenv\n"
  },
  {
    "path": "sample.env",
    "content": "TOKEN = \"INSERT_YOUR_TOKEN_HERE\"\n"
  }
]