I'm trying to import an email with a particular search string from the server. I'm using the following code.
library(rPython)
python.exec("import imaplib
import email")
python.exec('
m=imaplib.IMAP4("imap.myserver.com","143")
m.login(r"myid","mypass")
m.select()')
python.exec('r,data=m.search(None,\'HEADER From "*cds*"\')')
a = python.get("data")
but it seems to not like the escaped apostrophes. I get the message
Error in python.exec("r,data=m.search(None,'HEADER From \"*cds*\"')") :
SEARCH command error: BAD ['unable to handle request: Invalid search parameters: "HEADER FROM \\"*CDS*\\""']
Can anyone help me figure out how to get this right? Thanks
Related
I am trying to send a text message that contains both text and a hypeprlink but am encountering the following message from the Twilio API:
"Error - 12300 Invalid Content-Type: Attempt to retrieve MediaUrl returned an unsupported Content-Type."
Here is the code I am attempting to leverage:
import os
from twilio.rest import Client
# Find your Account SID and Auth Token at twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = os.environ['TWILIO_ACCOUNT_SID']
auth_token = os.environ['TWILIO_AUTH_TOKEN']
client = Client(account_sid, auth_token)
message = client.messages \
.create(
body='Article: https://4r7s.short.gy/GPaoh7',
from_='123-345-5667',
to='123-345-5668',
)
When I send a message without a hyperlink it works fine (e.g. body = 'Here is the article for you to read') but when it contains a link I receive the aforementioned error. I've also tried using a shortened url of the above but that causes the same issue.
I was just able to send messages containing that exact link using my own Twilio account.
There might be an issue in that you are using phone numbers in local format, when they should be provided in e.164 format.
It's possible that your message is being blocked. Certain carriers don't like when you use link shorteners to obscure a link.
The error you are getting definitely seems weird, since you are not sending media. If you continue to have issues with this, I would contact Twilio support.
Test code:
fetch_criteria = AND(seen=False), AND(NOT(uid=['61','88']))
for message in mailbox.fetch(fetch_criteria, mark_seen=False, charset='utf8', limit=10):
print(message.uid)
Server response:
SEARCH command error: BAD [b'Could not parse command']
Please help me correctly create the conditions to exclude emails with UID 66 and 88
from imap_tools import AND, NOT
mailbox.fetch(AND(NOT(uid=['39', '40'])))
mailbox.fetch(NOT(AND(uid=['39', '40'])))
Both works for me at [yandex, google, outlook, zimbra].
May be your server can not do this.
Error example at mail.ru: imap_tools.errors.MailboxSearchError: Response status "OK" expected, but "NO" received. Data: [b'[CANNOT] Unsupported search criterion: (UID 5,6)']
Lib author.
I have 2 Gmail accounts, and I use one ("gmail1") to forward all e-mail to the other one ("gmail2"). This works fine, but I discovered recently (after years!) that in fact, Gmail does not forward all my e-mail, but only the e-mail it considers not to be spam. Therefore, checking my spam folder in gmail2 for missing e-mails, I have often blamed senders, when really the e-mail had gotten lost on gmail1. I want to solve this programatically, by regularly checking for spam e-mails in gmail1 and importing them into gmail2 (then I'm fine with gmail2 categorizing as spam or not, as long as the mail makes its way there).
I'm only a very amateur programmer, and so far thanks to some samples from the gmail API docs, I've managed to log in to my accounts, and retrieve some messages corresponding to a query, including for example recent spam e-mails. However, I'm struggling with the "import" concept and how to use it. There are no Python examples for this, and I couldn't solve the problems I'm facing.
Where I am right now:
- if I "get" a message from gmail1 and attempt an import_ call on gmail2, using the message I just retrieved, I get an error because threadId is not allowed
- if I do the same and then "del message['threadId']" then the error becomes error 400 : 'raw' RFC822 payload message string or uploading message via /upload/* URL required. I've seen that there are some situations where upload is required, but I am completely lost as to what I should do to make this work.
Here's what I have so far (sorry for the very hacky style):
# skipping imports
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/gmail.modify']
def getMessage(service, user_id, msg_id):
"""from gmail API examples"""
try:
message = service.users().messages().get(userId=user_id, id=msg_id).execute()
return message
except errors.HttpError as error:
print ('An error occurred:' , error)
def listMessagesMatchingQuery(service, user_id, query=''):
"""from gmail API examples"""
# skipping some code
return messages
def login(accountId):
"""from gmail API examples, adapted to handle 2 accounts"""
# skipping some code
return build('gmail', 'v1', credentials=creds)
def importMessage(service, user_id, msg):
"""my daring attempt at using import, without any Python sample to use as a basis"""
try:
message = service.users().messages().import_(userId=user_id, body=msg).execute()
return message
except errors.HttpError as error:
print ('An error occurred:' , error)
if __name__ == '__main__':
service_gmail = login('gmail2')
service_dnt = login('gmail1')
messages = listMessagesMatchingQuery(service_dnt,"me","in:spam is:unread after:" + str(int((datetime.now() - timedelta(hours=12)).timestamp())))
# this gets me some recent unread spam messages
m=getMessage(service_dnt,"me",messages[0]['id'])
# now I have a full message - I'm just investigating for now so the first message is enough
del m['threadId']
# if I don't do that, the error I get is that threadId is not allowed here, so I remove it
imported = importMessage(service_gmail,"me",m)
# this now gives me error 400 : 'raw' RFC822 payload message string or uploading message via /upload/* URL required
I'd like to find the way to make this work, so that the e-mail appears in gmail2 as if it had been received by gmail2 directly (though I would like to keep the To: address, as I use a catch-all on gmail1 and want to know which e-mail address the e-mail was directed to). But right now, I get only errors about having to use upload; I'm not sure if that's what I really should be doing, and if it is , I have no idea how.
Thanks a lot in advance for any help!
In the end I managed. I had missed the fact that there are 2 ways to "get" messages, a simple one and a "raw" one. With the "raw" way to access the message, I can use the import_ function easily:
message = service_dnt.users().messages().get(userId="me", id=messageId,format='raw').execute()
imported = importMessage(service_gmail,"me",{'raw': message['raw']})
whereby the importMessage function is unchanged vs. the original code I posted.
I tried to fetch a message content in the following way
result, data = m.uid('fetch', num, "( FLAGS BODY.PEEK[HEADER.FIELDS (SUBJECT FROM DATE)] BODYSTRUCTURE)")
It worked well when I was connecting to a private mail server "mail.example.com"
But it returns exception when I used "imap.gmail.com"
error: UID command error: BAD ['Could not parse command']
I think gmail doesnot support detailed search like HEADER.FIELDS....
So I tried the following option for gmail server and it worked really well
result, data = m.uid('fetch', num, "(FLAGS BODY.PEEK[HEADER] BODYSTRUCTURE)")
I am using this with Gmail's SMTP server, and I would like to search via IMAP for emails either sent to or received from an address.
This is what I have:
mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login('user', 'pass')
mail.list()
mail.select("[Gmail]/All Mail")
status, email_ids = mail.search(None, 'TO "tech163#fusionswift.com" OR FROM "tech163#fusionswift.com"')
The last line of the error is: imaplib.error: SEARCH command error: BAD ['Could not parse command']
Not sure how I'm supposed to do that kind of OR statement within python's imaplib. If someone can quickly explain what's wrong or point me in the right direction, it'd be greatly appreciated.
The error you are receiving is generated from the server because it can't parse the search query correctly. In order to generate a valid query follow the RFC 3501, in page 49 it is explained in detail the structure.
For example your search string to be correct should be:
'(OR (TO "tech163#fusionswift.com") (FROM "tech163#fusionswift.com"))'
Try to use IMAP query builder from https://github.com/ikvk/imap_tools
from imap_tools import A, AND, OR, NOT
# AND
A(text='hello', new=True) # '(TEXT "hello" NEW)'
# OR
OR(text='hello', date=datetime.date(2000, 3, 15)) # '(OR TEXT "hello" ON 15-Mar-2000)'
# NOT
NOT(text='hello', new=True) # 'NOT (TEXT "hello" NEW)'
# complex
A(OR(from_='from#ya.ru', text='"the text"'), NOT(OR(A(answered=False), A(new=True))), to='to#ya.ru')
Of course you can use all library tools