How can I get the subject of an email gmail python API - python-3.x

def getbodyinbox():
service = build('gmail', 'v1', credentials=creds)
label_name = "READ-BY-SCRIPT"
label_id = 'Label_8507504117657095973'
results = service.users().messages().list(
userId='me', q="-label:"+label_name, maxResults=1).execute()
messages = results.get('messages', [])
body = []
if not messages:
body = "no messages"
return body
else:
for message in messages:
msg = service.users().messages().get(
userId='me', id=message['id']).execute()
labels = msg['labelIds']
if "INBOX" in labels:
headers = msg['payload']['headers']
headers = str(headers)
print(headers)
if "class_ix" in headers:
body.append(msg['payload']['parts'])
if 'data' in body[0][0]['body']:
body = base64.urlsafe_b64decode(
body[0][0]['body']['data'])
elif 'data' in body[0][1]['body']:
body = base64.urlsafe_b64decode(
body[0][1]['body']['data'])
body = str(body)
return body
print(getbodyinbox())
This is my code so far with the part that gets the credentials and all of the imports removed. It gets the body of the most recent email without a label 'READ-BY-SCRIPT' that also has the label INBOX. How can I get the subject of the email instead of the body?

Have a look at the message resource, MessagePart and header
The structure is the following:
"payload": {
"partId": string,
"mimeType": string,
"filename": string,
"headers": [
{
"name": string,
"value": string
}
],
and:
So, in other words, the subject is contained in the headers.
You can retrieve in Python with
headers = msg['payload']['headers']
subject= [i['value'] for i in headers if i["name"]=="Subject"]

Related

PowerQuery (Excel) - POST rest api webservice call - fail get contents (500): internal server error

I try to call a webservice (sap business one) to login, so I can obtain a session id.
I try to use the following:
let
url = "https://WEB/b1s/v1/Login",
headers = [#"Content-type"="application/json", #"Connection"="keep-alive"],
postData = Json.FromValue([CompanyDB = "Company", Password = "12345", UserName = "test"]),
response = Web.Contents(
url,
[
Headers = headers,
Content = postData
]
),
jsonResponse = Json.Document(response)
in
jsonResponse
This gives me the response described in the title.
Now when I did obtain a session id and manually cal for a get request on the same I do get a result (eg.):
let
url = "https://WEB/b1s/v1/Items?$select=ItemCode,ItemName",
headers = [#"Prefer"="odata.maxpagesize=0", #"Cookie"="B1SESSION=1bba9408-dd9e-11ec-8000-000d3a83435c; ROUTEID=.node1"],
response = Web.Contents(
url,
[
Headers = headers
]
),
jsonResponse = Json.Document(response),
value = jsonResponse[value],
[...]
This gives the list of items as a result.
Doing all of the above in Postman returns a proper result. I would expect this out of the "LOGIN":
{
"odata.metadata": "https://WEB/b1s/v1/$metadata#B1Sessions/#Element",
"SessionId": "7c01d84a-dda2-11ec-8000-000d3a83435c",
"Version": "1000141",
"SessionTimeout": 30
}
Any idea what else I can try?
Cheers and thank you
Andreas

How to send POST request after form submit 302 in Django?

I have an implementation as follows:
There is a payment form wherein user fills all the details.(API1), here I'm getting an error 302:
On submit of that form one of the function in my views is called.
In the backend implementation ie. in views.py, I want to send a POST request to one of the gateways I have integrated.(API2)
But the problem is coming as the request is going as GET and hence it is dropping all the form data I'm sending along with the request.
Following is the code.
views.py -->
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
payload = {
'CustomerID': 'abc',
'TxnAmount': '1.00',
'BankID': '1',
'AdditionalInfo1': '999999999',
'AdditionalInfo2': 'test#test.test',
}
payload_encoded = urlencode(payload, quote_via=quote_plus)
response = requests.post('https://www.billdesk.com/pgidsk/PGIMerchantRequestHandler?hidRequestId=****&hidOperation=****', data=payload_encoded, headers=headers)
content = response.url
return_config = {
"type": "content",
"content": redirect(content)
}
return return_config
How do I send the 2nd request(API2) as POST request along with all parameters? What am I doing wrong here?
Thank you for your suggestions.
If the requests returns a 302 status, the new url is available in response.headers['Location']. You can keep following the new url, till you end up with a valid response.
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
payload = {
'CustomerID': 'abc',
'TxnAmount': '1.00',
'BankID': '1',
'AdditionalInfo1': '999999999',
'AdditionalInfo2': 'test#test.test',
}
payload_encoded = urlencode(payload, quote_via=quote_plus)
response = requests.post('https://www.billdesk.com/pgidsk/PGIMerchantRequestHandler?hidRequestId=****&hidOperation=****', data=payload_encoded, headers=headers)
while response.status_code == 302:
response = requests.post(response.headers['Location'], data=payload_encoded, headers=headers)
content = response.text
return_config = {
"type": "content",
"content": content
}
return return_config
# here you are assigning the post url to content ie. 'https://www.billdesk.com/pgidsk/PGIMerchantRequestHandler?hidRequestId=****&hidOperation=****'
content = response.url
return_config = {
"type": "content",
"content": redirect(content) # calling redirect with the response.url
}
change to:
# check status code for response
print(response)
content = response.json() # if response is of json in format
content = response.text # if response is of plain text
return_config = {
"type": "content",
"content": content
}
return return_config
request.post() returns requests.Response object. inorder to get the response data you need to access it using .text or .json() depending on the format in which the response is sent.

OTRS - REST-API - Send content of ticket including attachment via SMTPLIB

I am trying to get the content of a ticket via REST-API from OTRS v4 and send the content to an external mail-address.
Everything works fine, except the attachment part. It sends an attachment, but the file is not readable and even has a different size than the source.
Doc for OTRS REST-API (TicketGet): http://doc.otrs.com/doc/api/otrs/5.0/Perl/Kernel/GenericInterface/Operation/Ticket/TicketGet.pm.html
# get the data vie REST from OTRS
TicketID = "12345"
headers = {
"Content-Type": 'application/json'
}
payload = {
'UserLogin': 'user',
"Password": 'pass',
"Extended": '1',
'AllArticles': '1',
'Attachments': '1',
}
url = 'https://somedomain.com/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/TicketGet/' + TicketID
result = requests.get(url, headers=headers, data=json.dumps(payload))
data = result.json()
# send content of ticket as an email to "soemone#somedmain.com"
email_subject = data['Ticket'][0]['Article'][0]['Subject']
email_body = data['Ticket'][0]['Article'][0]['Body']
msg = MIMEMultipart()
msg['From'] = "noreply#somedomain.com"
msg['To'] = "soemone#somedmain.com"
msg['Subject'] = email_subject
# text
msg.attach(MIMEText(email_body, 'plain'))
# attachment
attachment_content_type = data['Ticket'][0]['Article'][0]['Attachment'][0]['ContentType'] #outputs for example:
attachment_content = data['Ticket'][0]['Article'][0]['Attachment'][0]['Content'] #base64 ?
attachment_filename = data['Ticket'][0]['Article'][0]['Attachment'][0]['Filename'] #outputs for example:
mimetype = attachment_content_type.split(';')[0]
basetype, subtype = mimetype.split('/', 1)
att = MIMEBase(basetype, subtype)
att.set_payload(attachment_file)
att.add_header('Content-Disposition', 'attachment', filename=attachment_filename)
msg.attach(att)
# send msg
s = smtplib.SMTP('localhost')
s.send_message(msg)
s.quit()
Looks like this works:
# attachment
attachment_content = data['Ticket'][0]['Article'][0]['Attachment'][0]['Content']
attachment_filename = data['Ticket'][0]['Article'][0]['Attachment'][0]['Filename']
filedata = base64.b64decode(attachment_content)
att = MIMEBase('application', 'octet-stream')
att.set_payload(filedata)
encoders.encode_base64(att)
att.add_header('Content-Disposition', 'attachment', filename=attachment_filename)
msg.attach(att)
# send msg
s = smtplib.SMTP('localhost')
s.send_message(msg)
s.quit()

return payload for a API Gateway AWS

I have created a lambda function in Python 3.6 to return few records to an API gateway. the return standard according to documentation must be:
{
"isBase64Encoded" : "boolean",
"statusCode": "number",
"headers": { ... },
"body": "JSON string"
}
However, I need to return the data cached from a list and parsed to a JSON format to returned in the required format but it's not going thru, apparently, I can't assign a variable to body:
def lambda_handler(event, context):
if event["httpMethod"] == "GET":
param1 = event["queryStringParameters"]["param1"]
param2 = event["queryStringParameters"]["param2"]
info = redshift_get_output(param1,param2)
payload = json.dumps(info)
print(payload)
outcome = {
"isBase64Encoded": 'false',
"statusCode": 200,
"headers": { "header": "headerValue" },
"body": payload
}
return outcome
When I run it like that I get in my API Gateway execution the success message but the body doesn't contain anything :(
Someone has a clue about how could I figure this out, please. thanks so much
I have finally figured this out. The thing is that even if I apply a casting method for my payload to JSON the string that was returning always has at the beginning and at the end the square brackets [].
I created a customer replace function to delete the brackets and pass to my return function the payload without [].
Script:
def replace_all(text, dic):
for i, j in dic.items():
text = text.replace(i, j)
return text
def lambda_handler(event, context):
if event["httpMethod"] == "GET":
param1 = event["queryStringParameters"]["param1"]
param2 = event["queryStringParameters"]["param2"]
rep = {"[": "", "]": ""}
info = redshift_get_output(param1,param2)
payload = json.dumps(info)
payload = replace_all(payload,rep)
print(payload)
outcome = {
"isBase64Encoded": 'false',
"statusCode": 200,
"headers": { "header": "headerValue" },
"body": json.loads(payload)
}
return outcome
thanks so much

How to send multiple recipient sendgrid V3 api Python

Anyone please help, I am using sendgrid v3 api. But I cannot find any way to send an email to multiple recipients. Thank in advance.
import sendgrid
from sendgrid.helpers.mail import *
sg = sendgrid.SendGridAPIClient(apikey="SG.xxxxxxxx")
from_email = Email("FROM EMAIL ADDRESS")
to_email = Email("TO EMAIL ADDRESS")
subject = "Sending with SendGrid is Fun"
content = Content("text/plain", "and easy to do anywhere, even with Python")
mail = Mail(from_email, subject, to_email, content)
response = sg.client.mail.send.post(request_body=mail.get())
print(response.status_code)
print(response.body)
print(response.headers)
I want to send email to multiple recipient. Like to_mail = " xxx#gmail.com, yyy#gmail.com".
Note that with the code of the other answers here, the recipients of the email will see each others emails address in the TO field. To avoid this one has to use a separate Personalization object for every email address:
def SendEmail():
sg = sendgrid.SendGridAPIClient(api_key="YOUR KEY")
from_email = Email ("FROM EMAIL ADDRESS")
person1 = Personalization()
person1.add_to(Email ("EMAIL ADDRESS 1"))
person2 = Personalization()
person2.add_to(Email ("EMAIL ADDRESS 2"))
subject = "EMAIL SUBJECT"
content = Content ("text/plain", "EMAIL BODY")
mail = Mail (from_email, subject, None, content)
mail.add_personalization(person1)
mail.add_personalization(person2)
response = sg.client.mail.send.post (request_body=mail.get())
return response.status_code == 202
You can send an email to multiple recipients by listing them in the to_emails parameter of the Mail constructor:
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import *
message = Mail(
from_email='sender#example.com',
to_emails=[To('test#example.com'), To('test2#example.com')],
subject='Subject line',
text_content='This is the message of your email',
)
sg = SendGridAPIClient(SENDGRID_API_KEY)
response = sg.send(message)
With this configuration, each recipient will be able to see each other listed on the email. To avoid this, use the is_multiple parameter to tell Sendgrid to create a new Personalization for each recipient:
message = Mail(
from_email='sender#example.com',
to_emails=[To('test#example.com'), To('test2#example.com')],
subject='Subject line',
text_content='This is the message of your email',
is_multiple=True # Avoid listing all recipients on the email
)
To send email to multiple recicpent in sendgrid v3.
import time
import sendgrid
import os
print "Send email to multiple user"
sg = sendgrid.SendGridAPIClient(apikey='your sendrid key here')
data = {
"personalizations": [
{
"to": [{
"email": "adiii#gmail.com"
}, {
"email": "youremail#gmail.com"
}],
"subject": "Multiple recipent Testing"
}
],
"from": {
"email": "Alert#gmail.com"
},
"content": [
{
"type": "text/html",
"value": "<h3 style=\"color: #ff0000;\">These checks are silenced please check dashboard. Click HERE</h3> <br><br> <h3>For any query please contact DevOps Team<h3>"
}
]
}
response = sg.client.mail.send.post(request_body=data)
print(response.status_code)
if response.status_code == 202:
print "email sent"
else:
print("Checking body",response.body)
https://libraries.io/github/sendwithus/sendgrid-python
You can update your code in the below way. You can find the same in mail_example.py present in Sendgrid's package.
personalization = get_mock_personalization_dict()
mail.add_personalization(build_personalization(personalization))
def get_mock_personalization_dict():
"""Get a dict of personalization mock."""
mock_pers = dict()
mock_pers['to_list'] = [Email("test1#example.com",
"Example User"),
Email("test2#example.com",
"Example User")]
return mock_pers
def build_personalization(personalization):
"""Build personalization mock instance from a mock dict"""
mock_personalization = Personalization()
for to_addr in personalization['to_list']:
mock_personalization.add_to(to_addr)
return mock_personalization
Based on Subhrajyoti Das answer, I wrote the following code, that is a simpler version of the mail_example.py example of sending email to multiple recipient.
def SendEmail():
sg = sendgrid.SendGridAPIClient(api_key="YOUR KEY")
from_email = Email ("FROM EMAIL ADDRESS")
to_list = Personalization()
to_list.add_to (Email ("EMAIL ADDRESS 1"))
to_list.add_to (Email ("EMAIL ADDRESS 2"))
to_list.add_to (Email ("EMAIL ADDRESS 3"))
subject = "EMAIL SUBJECT"
content = Content ("text/plain", "EMAIL BODY")
mail = Mail (from_email, None, subject, content)
mail.add_personalization (to_list)
response = sg.client.mail.send.post (request_body=mail.get())
return response.status_code == 202
You can pass a list of strings.
message = Mail(
from_email='sender#email.com',
to_emails=['xxx#email.com', 'yyy#email.com'],
subject='subject',
html_content='content')
sg = SendGridAPIClient('SENDGRID_API_KEY')
response = sg.send(message)

Resources