Unable to send file to Telegram Channel - python

Error below:
Failed to convert James Blake - Never Dreamed.mp4 to media. Not an existing file, an HTTP URL or a valid bot-API-like file ID
Function that I am running is here.
async def gramain():
# Getting information about yourself
me = await bott.get_me()
print(me.stringify())
filesww = os.listdir('media').pop()
now = os.getcwd()
mediadir = now + "/media/"
vid = open(mediadir+filesww, 'r')
# await bot.send_message(chat, 'Hello, friend!')
await bott.send_file(chat, filesww, video_note=True)
I trying to use this function from the library Telethon.
https://docs.telethon.dev/en/latest/modules/client.html#telethon.client.uploads.UploadMethods.send_file
I am unable to find out what the issue is. Please help!

Related

Telegram Bot receive video from user

i want my bot to receive videos thats been sent by users. Previously, i did this coding to receive images from users but i still cant use my bot to receive videos from them. Can any of you help me solve this problem?
coding:
file = update.message.photo[-1].file_id
At first place telegram can recieve two types of videos: simple videofile, that was sent by user as attachment and "video_note" - video that was created directly in the telegram.
Recieving both these types are pretty similar:
At first we need to obtain file_id:
def GetVideoNoteId(update):
if update['message'].get('video_note') != None:
return update['message']['video_note']['file_id']
else:
return 'not videonote'
second step - getting filepath of that file on telegram servers - from where we should download that file:
def GetVideoNoteFileSource(FileId):
url = 'https://api.telegram.org/bot' + TOKEN + '/' + 'getFile'
jsn = {'file_id': FileId}
r = requests.get(url,json=jsn).json()
fileSource = r['result']['file_path']
return fileSource
And third - finally - getting this file:
def GetFile(fileSource):
url = 'https://api.telegram.org/file/bot' + TOKEN + '/' + fileSource
r = requests.get(url)
filename = 'Video.mp4'
try:
with open(filename, 'wb') as file:
file.write(r.content)
return 'file dowloaded'
except:
return 'there are something wrong'
With videofile as attachments similar, but
return update['message']['video_note']['file_id'] - would be looks different (i do not remmember)

a python-telegram-bot Unsupported url protocol

So, I was Trying To Create a Telegram Bot That By Using The PyTube Moudle, Will Download The Video To My Computer And Then Send It To The User By The send_document Function.
My Problem Is When I Need To Send The Video, I Get This Error:
telegram.error.BadRequest: Invalid file http url specified: unsupported url protocol
I've Tried It On a Regular Text File And Got The Same Results.
I Assume It's Because The Url of The File Is Breaking Some Rules of How It Should Look Like, But I Don't Know How To Fix It...
Also Here Is My Code:
import telegram.ext
import telegram
from telegram.ext.messagehandler import MessageHandler
from telegram.ext.commandhandler import CommandHandler
from telegram.ext.filters import Filters
import time
import pytube
import os
with open('C:/Users/EvilTwin/Desktop/stuff/Python/API/Telegram/Download Youtube Videos Bot/token.txt')as file:
API_KEY = file.read()
updater = telegram.ext.Updater(token=API_KEY, use_context=True)
def start(update, context):
update.message.reply_text(f'Hello {update.effective_user.first_name}, I\'m Roee\'s Video Downloader!')
time.sleep(1)
update.message.reply_text(
f'''
To Download Videos Please Enter:
/download + Video URL + Format
''')
def download(update, context):
URL = context.args[0]
FORMAT = context.args[1]
VIDEO = pytube.YouTube(URL)
FILE = VIDEO.streams.filter(progressive=True, file_extension=FORMAT).order_by('resolution').desc().first()
VD = 'C:/Users/EvilTwin/Desktop/stuff/Python/API/Telegram/Download Youtube Videos Bot/Videos'
FILE.download(VD)
banned = ['/', '/-\\', ':', '?', '!', '*', '>', '<', '"', '|']
for ban in banned:
VIDEO.title = VIDEO.title.replace(ban, '')
time.sleep(1)
DOC = f'{VD}/{VIDEO.title}.{FORMAT}'
chat_id=update.effective_chat.id
context.bot.send_document(chat_id = chat_id ,document=DOC, filename = f'video.{FORMAT}')
os.remove(DOC)
updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(CommandHandler('download', download))
updater.start_polling()
updater.idle()
If Anyone Knows How To Fix It Please Help Me....
For local file you have to use file object (file handler) instead of file name
so you have to open it document=open(DOC, 'rb')
context.bot.send_document(chat_id=chat_id, document=open(DOC, 'rb'), filename=f'video.{FORMAT}')
Documentation shows also that you can use pathlib.Path or bytes (so it needs to read it document=open(DOC, 'rb').read()) but I didn't test it.
See doc: send_document()

lyricsgenius lyrics sometimes end with "EmbedShare URLCopyEmbedCopy"

I am making a Discord lyrics bot and to receive the lyrics. I am using genius API (lyricsgenius API wrapper). But when I receive the lyrics, it ends with this:
"away" is the last word in the song but it is accompanied with EmbedShare URLCopyEmbedCopy. Sometimes it is just the plain lyrics without the EmbedShare text.
With the same song:
Is there anyway to prevent that?
Source code for the lyrics command:
#commands.command(help="Gives the lyrics of the song XD! format //lyrics (author) (song name)")
async def lyrics(self, ctx, arg1, arg2):
song = genius.search_song(arg1, arg2)
print(song.lyrics)
name = ("Lyrics for " + arg2.capitalize() + " by " + arg1.capitalize())
gembed = discord.Embed(title=name.capitalize(), description=song.lyrics)
await ctx.send(embed=gembed)
This is a known bug with lyricsgenius and there's an open PR to address this issue: https://github.com/johnwmillr/LyricsGenius/pull/215.
This is because lyricsgenius web scrapes the lyrics from Genius' website, which means if their website updates, lyricsgenius would fail to fetch the lyrics. This library hasn't been updated in 6 months; itself being a web scraping library means that kind of inactivity would render the library severely unstable. Since the library is licensed under MIT, you can fork the library and maintain an up-to-date version for your project/bot. However, it would be much better to use a dedicated API to fetch songs lyrics to guarantee stability.
Also, lyricsgenius uses the synchronous requests library, which means it'll "block" your asynchronous bot while it fetches the lyrics. This is definitely undesirable for a Discord Bot since your bot would be completely unresponsive while it fetches the lyrics. Consider rewriting it using aiohttp or use run_in_executor when calling blocking functions.
Some Random API is something easy to deal with when you are creating a command that will send you the song lyrics.
This is how to do it with some random api,
# these imports are used for this particular lyrics command. the essential import here is aiohttp, which will be used to fetch the lyrics from the API
import textwrap
import urllib
import aiohttp
import datetime
#bot.command(aliases = ['l', 'lyrc', 'lyric']) # adding aliases to the command so they they can be triggered with other names
async def lyrics(ctx, *, search = None):
"""A command to find lyrics easily!"""
if not search: # if user hasnt given an argument, throw a error and come out of the command
embed = discord.Embed(
title = "No search argument!",
description = "You havent entered anything, so i couldnt find lyrics!"
)
return await ctx.reply(embed = embed)
# ctx.reply is available only on discord.py version 1.6.0, if you have a version lower than that use ctx.send
song = urllib.parse.quote(search) # url-encode the song provided so it can be passed on to the API
async with aiohttp.ClientSession() as lyricsSession:
async with lyricsSession.get(f'https://some-random-api.ml/lyrics?title={song}') as jsondata: # define jsondata and fetch from API
if not 300 > jsondata.status >= 200: # if an unexpected HTTP status code is recieved from the website, throw an error and come out of the command
return await ctx.send(f'Recieved poor status code of {jsondata.status}')
lyricsData = await jsondata.json() # load the json data into its json form
error = lyricsData.get('error')
if error: # checking if there is an error recieved by the API, and if there is then throwing an error message and returning out of the command
return await ctx.send(f'Recieved unexpected error: {error}')
songLyrics = lyricsData['lyrics'] # the lyrics
songArtist = lyricsData['author'] # the author's name
songTitle = lyricsData['title'] # the song's title
songThumbnail = lyricsData['thumbnail']['genius'] # the song's picture/thumbnail
# sometimes the song's lyrics can be above 4096 characters, and if it is then we will not be able to send it in one single message on Discord due to the character limit
# this is why we split the song into chunks of 4096 characters and send each part individually
for chunk in textwrap.wrap(songLyrics, 4096, replace_whitespace = False):
embed = discord.Embed(
title = songTitle,
description = chunk,
color = discord.Color.blurple(),
timestamp = datetime.datetime.utcnow()
)
embed.set_thumbnail(url = songThumbnail)
await ctx.send(embed = embed)

How to send file from server using telebot?

I made a bot that sends files from an external server with a URL.
I want the bot to send files directly from your server.
What am I doing wrong? Why didn't the open() command work?
import telebot
bot = telebot.TeleBot("Token")
#bot.message_handler(commands=['start','help'])
def send_start_message(message):
bot.reply_to(message, "Hi.")
#bot.message_handler(func=lambda m: True)
def echo_all(message):
print(message.text)
duck = open('duck.png','r')
bot.send_photo(message.chat.id, duck)
bot.send_message(message.chat.id, "hi")
bot.polling()
You'll need to tell python3 to use binary mode;
duck = open('duck.png', 'rb')
Read more about open()
Minimal working example to send local image:
import telebot
bot = telebot.TeleBot("<YOUR-TOKEN-HERE>")
cid = <YOUR-ID-HERE>
img = open('image.jpg', 'rb')
bot.send_photo(cid, img)

How do I only get a picture from PRAW

I am trying to use PRAW for a discord.py command. However I do not want videos to play when I execute the command, so is there a way I can only get pictures when I get the post?
Here is what I have:
#commands.command()
async def aww(self, ctx):
subreddit = reddit.subreddit("aww")
allsubs = []
top = subreddit.top(limit = 50)
for submission in top:
allsubs.append(submission)
randomsub = random.choice(allsubs)
name = randomsub.title
url = randomsub.url
em = discord.Embed(
title = name,
color = discord.Color.blurple()
)
em.set_image(url = url)
await ctx.send(embed = em)
Any help will be appreciated, thanks!
Because the PRAW api only provides you a url (str) without any information on the URL, I'd suggest adding some conditionals to ensure that the url is a photo and not a video.
e.g.
randomsub = random.choice(allsubs)
extension = randomsub.url[len(randomsub.url) - 3 :].lower()
while "jpg" not in extension or "png" not in extension:
randomsub = random.choice(allsubs)
extension = randomsub.url[len(randomsub.url) - 3 :].lower()
And proceed from there. Obviously there are more graceful ways of solving this but the underlying point is the same.

Categories

Resources