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()
Related
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)
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)
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!
I have made a Slack bot using slackclient 1.3.2 and Python 3.5 in a virtualenv. I'm running this on Windows 7. One of the functions sends a files from a directory when requested. This function seems to work fine when sending files whose names and paths contain only ascii, but it doesn't do anything when I ask it to send a file with an accent in the name.
Here is the relevant part of the code:
import asyncio, requests
from slackclient import SlackClient
token = "MYTOKEN"
sc = SlackClient(token)
#asyncio.coroutine
def sendFile(sc, filename, channels):
print(filename)
f = {'file': (filename, open(filename, 'rb'), 'text/plain', {'Expires':'0'})}
response = requests.post(url='https://slack.com/api/files.upload',
data= {'token': token, 'channels': channels, 'media': f},
headers={'Accept': 'application/json'}, files=f)
#asyncio.coroutine
def sendExample(sc, chan, user, instructions):
path1 = 'D:/Test Files/test.txt' #note: just ascii characters
path2 = 'D:/Test Files/tést.txt' #note: same as path1 but with accent over e in filename
print('instructions: ', instructions)
if instructions[0] == 'path1':
sc.rtm_send_message(chan, 'Sending path1!')
asyncio.async(sendFile(sc, path1, chan))
if instructions[0] == 'path2':
sc.rtm_send_message(chan, 'Sending path2!')
asyncio.async(sendFile(sc, path2, chan))
#asyncio.coroutine
def listen():
x = sc.rtm_connect()
while True:
yield from asyncio.sleep(0)
info = sc.rtm_read()
if len(info) == 1:
if 'text' in info[0]:
print(info[0]['text'])
if r'send' in info[0]['text'].lower().split(' '):
chan = info[0]['channel']
user = info[0]['user']
instructions = info[0]['text'].lower().split(' ')[1:]
asyncio.async(sendExample(sc, chan, user, instructions))
def main():
print('Starting bot.')
loop = asyncio.get_event_loop()
asyncio.async(listen())
loop.run_forever()
if __name__ == '__main__':
main()
D:/Test Files/test.txt and D:/Test Files/tést.txt are identical text files, just one has an accent above the e in the file name.
Here is what it looks like from the Slack interface:
As you can see, when I request path1 (test.txt) it works, but when I request path2 (tést.txt) it says it is sending something but doesn't seem to do anything.
The command line output looks the same for both of the files:
>python testSlackSend.py
Starting bot.
send path1
instructions: ['path1']
D:/Test Files/test.txt
Sending path1!
send path2
instructions: ['path2']
D:/Test Files/tést.txt
Sending path2!
I guess I can just rename all the files to get rid of the accents, but that's not really ideal. Is there a more elegant way to solve this problem?
If it will help with the problem I could migrate the whole thing to slackclient 2.x, but that seems like a lot of work that I'd rather not do if it's an option.
i'm just implementing a simple bot who should send some photos and videos to my chat_id.
Well, i'm using python, this is the script
import sys
import time
import random
import datetime
import telepot
def handle(msg):
chat_id = msg['chat']['id']
command = msg['text']
print 'Got command: %s' % command
if command == 'command1':
bot.sendMessage(chat_id, *******)
elif command == 'command2':
bot.sendMessage(chat_id, ******)
elif command == 'photo':
bot.sendPhoto(...)
bot = telepot.Bot('*** INSERT TOKEN ***')
bot.message_loop(handle)
print 'I am listening ...'
while 1:
time.sleep(10)
In the line bot.sendphoto I would insert the path and the chat_id of my image but nothing happens.
Where am I wrong?
thanks
If you have local image path:
bot.send_photo(chat_id, photo=open('path', 'rb'))
If you have url of image from internet:
bot.send_photo(chat_id, 'your URl')
Just using the Requests lib you can do it:
def send_photo(chat_id, file_opened):
method = "sendPhoto"
params = {'chat_id': chat_id}
files = {'photo': file_opened}
resp = requests.post(api_url + method, params, files=files)
return resp
send_photo(chat_id, open(file_path, 'rb'))
I have used the following command while using python-telegram-bot to send the image along with a caption:
context.bot.sendPhoto(chat_id=chat_id, photo=
"url_of_image", caption="This is the test photo caption")
I've tried also sending from python using requests. Maybe it's late answer, but leaving this here for others like me.. maybe it'll come to use..
I succeded with subprocess like so:
def send_image(botToken, imageFile, chat_id):
command = 'curl -s -X POST https://api.telegram.org/bot' + botToken + '/sendPhoto -F chat_id=' + chat_id + " -F photo=#" + imageFile
subprocess.call(command.split(' '))
return
This is complete code to send a photo in telegram:
import telepot
bot = telepot.Bot('______ YOUR TOKEN ________')
# here replace chat_id and test.jpg with real things
bot.sendPhoto(chat_id, photo=open('test.jpg', 'rb'))
You need to pass 2 params
bot.sendPhoto(chat_id, 'URL')
sendPhoto requires at least two parameters; first one is target chat_id, and for second one photo you have three options:
Pass file_id if the photo is already uploaded to telegram servers (recommended because you don't need to reupload it).
If the photo is uploaded somewhere else, pass the full http url and telegram will download it (max photo size is 5MB atm).
Post the file using multipart/form-data like you want to upload it via a browser (10MB max photo size this way).