I am trying to make a bot for Telegram using pyTelegramBotAPI, it is a store to download Windows Applications, because of the 50MB limit of sending the telegram. I send the file as a user and get the File_ID, which causes the bot to send 2GB files. Each program has a file.txt with your File_ID written.
The bot reads vlc.txt, sets it as a variable and sends the file.
But the program has an error.
"2020-12-19 21:06:09,106 (init.py:489 MainThread) ERROR - TeleBot: "A request to the Telegram API was unsuccessful. Error code: 400. Description: Bad Request: wrong remote file identifier specified: Wrong character in the string""
When I manually put the File_ID in the code, it works perfectly, it can't get the file_id from the variable, and I sent the program to print to make sure the variable contains the File_ID written correctly. What could be causing this?
def selecionou(query):
#pretreatment definition
download = query.data.count('down')
info = query.data.count('info')
prints = query.data.count('prints')
#app name treatment
if download > 0:
name = query.data.replace("down.","")
print(name)
file_id = open(f'/home/flaipy/PycharmProjects/Lucas/apps/{name}.txt','r')
file_id = file_id.read()
print(file_id)
#order type treatment
if download > 0:
print(file_id)
bot.send_document(query.message.chat.id, file_id)
I was reading w3schools from the "read ()" method in python, and saw that there is an argument to limit the number of characters, I put 70 and it worked, even in the txt file having no space. It is a tip for those who go through the same problem.
file_id = file_id.read(70)
Related
I currently use this solution to download attachments from Gmail using Gmail API via python.
However, every time an attachment exceeds 25MB, the attachments automatically get uploaded to Google Drive and the files are linked in the mail. In such cases, there is no attachmentId in the message.
I can only see the file names in 'snippet' section of the message file.
Is there any way I can download the Google dive attachments from mail?
There is a similar question posted here, but there's no solution provided to it yet
How to download a Drive "attachment"
The "attachment" referred to is actually just a link to a Drive file, so confusingly it is not an attachment at all, but just text or HTML.
The issue here is that since it's not an attachment as such, you won't be able to fetch this with the Gmail API by itself. You'll need to use the Drive API.
To use the Drive API you'll need to get the file ID. Which will be within the HTML content part among others.
You can use the re module to perform a findall on the HTML content, I used the following regex pattern to recognize drive links:
(?<=https:\/\/drive\.google\.com\/file\/d\/).+(?=\/view\?usp=drive_web)
Here is a sample python function to get the file IDs. It will return a list.
def get_file_ids(service, user_id, msg_id):
message = service.users().messages().get(userId=user_id, id=msg_id).execute()
for part in message['payload']['parts']:
if part["mimeType"] == "text/html":
b64 = part["body"]["data"].encode('UTF-8')
unencoded_data = str(base64.urlsafe_b64decode(b64))
results = re.findall(
'(?<=https:\/\/drive\.google\.com\/file\/d\/).+(?=\/view\?usp=drive_web)',
unencoded_data
)
return results
Once you have the IDs then you will need to make a call to the Drive API.
You could follow the example in the docs:
file_ids = get_file_ids(service, "me", "[YOUR_MSG_ID]"
for id in file_ids:
request = service.files().get_media(fileId=id)
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
print "Download %d%%." % int(status.progress() * 100)
Remember, seeing as you will now be using the Drive API as well as the Gmail API, you'll need to change the scopes in your project. Also remember to activate the Drive API in the developers console, update your OAuth consent screen, credentials and delete the local token.pickle file.
References
Drive API Docs
Managing Downloads Guide
Gmail API Docs
Drive API has also limtitation of downloading 10MBs only
I am just starting out in Python and I am trying to accomplish a manual task I have heard is on the simpler side to accomplish with python. My company uses Office 365 for their emails and I want to retrieve an email attachment and store it locally so I can save time . So far have established how to send a simple email, call the names of the folders in my account but I cannot figure out how to read any specific email .
my idea goes a little like this ,
from O365 import Account, message,mailbox
credentials = ('username', 'given password')
account = Account(credentials)
mailbox = account.mailbox()
mail_folder = mailbox.inbox_folder()
mail_folder = mailbox.get_folder(folder_name='Inbox')
print(mail_folder)
#_init__(*,parent= Inbox, con=None,**kwargs)
Message_body = message.body()
message.get_subject('email subject here!')
print(Message.body)
right now I am lost and trying anything within the O365 documentation page but the message module does not have the attribute subject according to how I am using it . Any guidance would be much appreciated
From your example - it's not clear if you are authenticated or not...
If you are then you will be able to list the mailbox folders. In the case below - you can access the inbox and then list the sub-folders:
from O365 import Account, Connection, MSGraphProtocol, Message, MailBox, oauth_authentication_flow
scopes=['basic', 'message_all']
credentials=(<secret>, <another secret>)
account = Account(credentials = credentials)
if not account.is_authenticated: # will check if there is a token and has not expired
account.authenticate(scopes=scopes)
account.connection.refresh_token()mailbox = account.mailbox()
inbox = mailbox.get_folder(folder_name='Inbox')
child_folders = inbox.get_folders(25)
for folder in child_folders:
print(folder.name, folder.parent_id)
This part will allow you to list folders (and also messages).
If I look at your code - it looks as though you are trying to do both?
Try doing something like the following to get the hang of paging through your inbox:
for message in inbox.get_messages(5):
if message.subject == 'test':
print(message.body)
Note that I'm looping through the first 5 messages in the inbox looking for a message with subject 'test'. If it finds the message - then it prints the body.
Hopefully this will shed a little light.
I need to create an email draft and save in msg format without launching the outlook application.
(Or)
I have an existing draft msg file, I need to modify the sender, body, and attachment to that file and save as msg file.
I tried win32 it is working fine, but it is launching the outlook application in my system. In my server, there is no outlook application.
Can you please tell me is there any other ways to generate the msg file.
If you don't want to to use the Outlook Object Model, you are pretty much limited to either using a library like Aspose (it handles MSG files without having to install Outlook, but your mileage may vary) or Redemption (disclosure: I am its author) - it requires the MAPI system to be installed (which means Outlook must be installed), but it won't start Outlook if you are using RDOSession.CreateMsgFile (ollowed by setting various RDOMail properties and/or importing an existing MSG file using RDOMail.Import followed by RDOMail.Save.
Update per OP request.
I don't use Python, but in VB script it would be something like the following:
Set Session = CreateObject("Redemption.RDOSession")
set newMsg = Session.CreateMessageFromMsgFile("c:\temp\new.msg")
newMsg.Import("c:\temp\template.msg", 3)
newMsg.Body = "updated body"
newMsg.Save
You can create an email draft and save it as MSG with Aspose.Email for Python via .NET using the code sample given below:
eml = MailMessage()
# Set from, to, subject and body properties
eml.from_address = "sender#domain.com";
eml.to.append("receiver#domain.com");
eml.subject = "This is test message";
eml.body = "This is test body";
# Create an instance of the MapiMessage class and pass MailMessage as argument
outlookMsg = MapiMessage.from_mail_message(eml);
# Save the message (MSG) file
strMsgFile = "CreatingAndSavingOutlookMessages_out.msg"
outlookMsg.save(dataDir + strMsgFile);
Note: I am working as Support developer/ Evangelist at Aspose.
I use python and here is a problem. First I use method get_chat to get file_id of photo chat as example.
import telebot
bot = telebot.TeleBot("xxxxxxxxxxxxxxxxxxxxxxxx")
s = bot.get_chat('#codygarbrandt_best')
print(s.photo.big_file_id)
Then I want to send this photo to myself.
bot.send_photo(my_chat_id , s.photo.big_file_id )
But I get the following error.
Bad Request: type of file mismatch
I remember it worked before, how can I achieve this now?
The big_file_id which can be read from the get_chat method can only be used for downloading the photo. You will have to store the file locally yourself and then resend it.
Unique file identifier of big (640x640) chat photo. This file_id can be used only for photo download. [doc]
I am trying to take info from my python program and update this real time on the web page.
I am trying to use node-red and communicate via web sockets.
My python program is below:
#!/usr/bin/python
import time
import websocket
ws = websocket.WebSocket();
ws.connect("ws://localhost:1880/ws/example")
count = 0;
while(count < 50):
print "Sending 'Hello, World'..."
ws.send("Hello, World")
print "Sent"
time.sleep(5)
count = count + 1
ws.close()
Using Node-red I have set up my flow as follows:
Node-Red Flow
However when I run them both, my python program says it is sending the message, however the node red console is returning null for the msg value.
Please check your settings.js file -- do you have a url prefix defined for either httpRoot or httpNodeRoot?
For instance, in my project, when I add a new websocket config node, this info box is shown:
By default, payload will contain the data to be sent over, or received from a
websocket. The listener can be configured to send or receive the entire message
object as a JSON formatted string. This path will be relative to /red.
If so, I believe you will have to modify the url in your python code, like so:
ws.connect("ws://localhost:1880/red/ws/example")
substituting your prefix, of course...