skip to Main Content

Good morning everybody. I’d like to send a document using Python and the API from Telegram Bot. The Bot has been successfully created and I can also send messages, but unfortunately I’m not managing to send documents that are on my Laptop.

My Code is the following:

import requests


def telegram_bot_send_document():

    bot_token = '####'
    bot_chatID = '####'

    file = open('test.txt', 'rb')
    send_document = 'https://api.telegram.org/bot' + bot_token + '/sendDocument?chat_id=' + bot_chatID + '&multipart/form-data=' + str(file.read())

    r = requests.post(send_document)
    print(r.url)

    return r.json()

The Output is always:

{'ok': False, 'error_code': 400, 'description': 'Bad Request: there is no document in the request'}

3

Answers


  1. First of all, I have never used the telegramm API oder send documents with telegram.

    From their documentation:

    (source: https://core.telegram.org/bots/api#sending-files)

    Sending files There are three ways to send files (photos, stickers,
    audio, media, etc.):

    1. If the file is already stored somewhere on the Telegram servers, you
      don’t need to reupload it: each file object has a file_id field,
      simply pass this file_id as a parameter instead of uploading. There
      are no limits for files sent this way.
    2. Provide Telegram with an HTTP
      URL for the file to be sent. Telegram will download and send the file.
      5 MB max size for photos and 20 MB max for other types of content.
    3. Post the file using multipart/form-data in the usual way that files
      are uploaded via the browser. 10 MB max size for photos, 50 MB for
      other files.

    You need to upload first the file and reference the ID or you need a POST-Request, not attached to the URL.

    Login or Signup to reply.
  2. Though its late, I thought I must share for others who might face the same problem as I did.

    From Antonio’s code there are two major modifications:

    Passing stream=True in post()

    When uploading files, requests requires us to pass the stream=True parameter so that the file can be downloaded on the server side. You can read more about it Here. Also, since it is a post request with multipart/form-data, we are required to pass the data parameter which carries the data(chat_id, caption, parse_mode etc) as well as the files parameter which carries the document in binary.

    Opening the file within post()

    This is weird and I have not found out why, but when I opened my file into a varible like file = open('text.txt','rb) and reference it in files parameter like requests.post(url, data=data, files=file), Telegram would throw a Bad Request saying no document found, But when I opened the file within the files parameter like requests.post(url, data=data, files=open('text.txt','rb')), It worked fine.

    So the final code should look like this:

    import requests
    
    
    def telegram_bot_send_document():
    
        bot_token = '####'
        bot_chatId = '####'
    
        open('test.txt', 'rb')
        send_document = 'https://api.telegram.org/bot' + bot_token +'/sendDocument?'
        data = {
          'chat_id': bot_chatId,
          'parse_mode':'HTML',
          'caption':'This is my file'
           }
    
        r = requests.post(send_document, data=data, files=open('test.txt','rb'),stream=True)
        print(r.url)
    
        return r.json()
    
    Login or Signup to reply.
  3. I have tried all of the above and spent a day searching for the right answer to the question but found nothing anywhere. Weird!
    But finally after testing and modifying the answer of @Nengha here’s my solution that works perfectly fine.

    def telegram_bot_send_document():
    
    bot_token = ""
    bot_chatId = ""
    
    file_location = 'test.txt'
    send_document = 'https://api.telegram.org/bot' + bot_token +'/sendDocument?'
    data = {
      'chat_id': bot_chatId,
      'parse_mode':'HTML',
      'caption':'This is my file'
    }
    # Need to pass the document field in the files dict
    files = {
        'document': open(file_location, 'rb')
    }
    
    r = requests.post(send_document, data=data, files=files, stream=True)
    print(r.url)
    
    return r.json()
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search