I am trying to send a logo with the email and have it appear in the HTML part of the email. I am building my email like this:
mail_subject = _("Subject of email %s" %
self.get_company_display())
from_email = "test#test.com"
message = EmailMultiAlternatives(mail_subject, mail_txt, from_email,
['destination#email.com'])
message.attach_alternative(mail_html, 'text/html')
message.attach('logo.png', static('myapp/images/logo.png'))
message.send()
And in my mail template I have:
<img src="cid:logo.png">
I receive the email but the image doesn't appear in the email. In fact, the email does not appear to have the image as an attachment.
Working on Python 3.4, Django 1.8.4 and sending the mails through Postfix installed on the same machine Django is running.
The EmailMessage.attach method expects to be passed the content of the file not its path, what you are actually doing is attaching the string returned by static('myapp/images/logo.png') to the message.
Use EmailMessage.attach_file instead (EmailMessage reference).
The whole purpose of yagmail (I'm the developer) is to make it really easy to send emails, especially with HTML or attachment needs.
Please try the following code:
import yagmail
yag = yagmail.SMTP(from_add, password) # add host="" and port=
contents = ['See my attachment below', '/home/static/images/logo.png']
yag.send(contents = contents)
Notice the magic here: contents is a list, where an item equal to a file path will automatically be loaded, mimetype guessed, and attached.
There's a lot more magic involved, such as easy to embed images, passwordless scripts, usernameless scripts, easy aliases, smart defaults (notice I omitted the to and subject arguments?) and much more. I advise/encourage you to read its github page :-). Feel free to raise issues or add feature requests!
You can get yagmail by using pip to install it:
pip install yagmail # Python 2
pip3 install yagmail # Python 3
Related
I've been trying to work this one out for a while now but keep finding imperfect solutions - I think what I want to do is possible but maybe I'm not phrasing my Google search correctly.
I have a Python script that sends a user an email notification - in order to send said email I need to provide a password in the script to send the email. The code works perfectly but it requires that I pass the password into the script:
def send_email():
import smtplib
import ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
sender_email = "my-generic-email#gmail.com"
receiver_email = "recipient#gmail.com"
password = "my_password_here"
message = MIMEMultipart("alternative")
message["Subject"] = "subject_here"
message["From"] = sender_email
message["To"] = receiver_email
# Create the plain-text and HTML version of your message
text = f"""\
Plain text body here
"""
# Create secure connection with server and send email
context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
server.login(sender_email, password)
server.sendmail(
sender_email, receiver_email, message.as_string()
)
I don't want to store the password as plain text for obvious reasons. I've thought of environment variables but this wouldn't work as this is going to be deployed on GitHub for other people to use (or install as an EXE) so this would break the email functionality.
I've tried looking at PyCryptodome but anything I've found so far suggests encrypting the password with a key but then storing the key in the script to decrypt the password when you use it. This seems like a bad idea to me as surely any novice (like me!) would be able to easily decrypt this because the key is stored in the script.
Is anyone able to help push me in the right direction? I'm completely out of ideas as frankly I know hardly anything about password storing/security so not even sure what I should be Googling!
If others have to use your password to be able to use your script, it's impossible. If the computer can read it, then the user will also find a way to read it.
I recommend using a E-Mail service where the user can enter their own API key or just let them enter their own GMail credentials.
Correct me if I'm wrong, but I think there's no way to use your password in this case unless you write an API and send the E-Mail from your server. But don't forget that in this case, the user might be able to use your API as a way to send spam.
TL;DR: Let the users use their own passwords.
I want to verify whether I am receiving an email from a "sender" with a "subject" and a particular "email" template. I have seen help links with win32 module that works for windows. I want to know the way to read the mails from my Microsoft Outlook from macOS.
I had something similar using appscript library. You would need to have it installed.
pip install appscript
The sample code is something like this, you may to need to extend it for your use case.
from appscript import app, k
def make_msg(text):
outlook = app('Microsoft Outlook')
msg = outlook.make(
new=k.outgoing_message,
with_properties={
k.subject: 'Test Email',
k.plain_text_content: text})
msg.make(
new=k.recipient,
with_properties={
k.email_address: {
k.name: '<My name>',
k.address: '<My email ID>'}})
msg.open()
msg.activate()
if __name__ == '__main__':
make_msg("Sample text")
Let me know if you need more clarification.
I have a instrument at work that emails me a file containing raw data, I can go into my email and download them easily enough but when I have multiple files (which it sends as multiple emails) it gets a bit tedious.
I'm looking at using python and imaplib to login to my email account, search for emails from a known email address within the past day or so and then download any attachments to a directory. So I thought a script might help here.
I've setup a gmail account and altered the settings so that I can connect using imap from a shell, however I'm lost as to where to go from here.
Could someone point me in the right direction as to what I need to do to make this happen.
Here is a repository that is forked off imaplib (made compatible with Python3.6, did not test other versions)
https://github.com/christianwengert/mail
The following snippet checks all unseen messages, then returns their attachments:
server = IMAPClient(imap, use_uid=True, ssl=993)
server.login(username, password)
server.select_folder('INBOX')
message_ids = server.search([b'NOT', b'SEEN']) # UNSEEN
messages = server.fetch(message_ids, data=['ENVELOPE', 'BODYSTRUCTURE', 'RFC822.SIZE'])
for mid, content in messages.items():
bodystructure = content[b'BODYSTRUCTURE']
text, attachments = walk_parts(bodystructure, msgid=mid, server=server)
HTH
I want to do a "simple" task in Outlook, with a Python script, but I'm usually in PHP and it's a little bit difficult for me.
Here is the task:
Open Outlook (it's ok for that)
Check a specific account, example: test#test.com
Open the last mail
I want to open the "real" message windows at screen, not just to access to the content.
Is it possible?
For your second requirement, could the account be a shared inbox?
Here is the code for the rest:
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
message = messages.GetLast()
message.display()
Here is another example with exchangelib in python:
https://medium.com/#theamazingexposure/accessing-shared-mailbox-using-exchangelib-python-f020e71a96ab
Here is the snippet to get the last email. I did it using a combination of order by and picking the first one or the last one depending on how you order by:
from exchangelib import Credentials, Account, FileAttachment
credentials = Credentials('FirstName.LastName#Some_Domain.com', 'Your_Password_Here')
account = Account('FirstName.LastName#Some_Domain.com', credentials=credentials, autodiscover=True)
filtered_items = account.inbox.filter(subject__contains='Your Search String Here')
print("Getting latest email for given search string...")
for item in account.inbox.filter(subject__contains='Your Search String Here').order_by('-datetime_received')[:1]: #here is the order by clause:: you may use order_by('datetime_received')[:-1]
print(item.subject, item.text_body.encode('UTF-8'), item.sender, item.datetime_received) #item.text_body.encode('UTF-8') gives you the content of email
while trying to open the real message might be a bit of a challenge but I will update this section once I have a solution. If I may ask:: are you looking at a python only solution ?
In PHP I can send an email simply by calling mail(). In Django, I need to specify SMTP backends and other things.
Is there a simpler way to send email from Django?
There are several good mail-sending functions in the django.core.mail module.
For a tutorial please see Sending e-mail:
Although Python makes sending e-mail
relatively easy via the smtplib
library, Django provides a couple of
light wrappers over it. These wrappers
are provided to make sending e-mail
extra quick, to make it easy to test
e-mail sending during development, and
to provide support for platforms that
can’t use SMTP.
The simplest function that would most likely suit your purposes is the send_mail function:
send_mail(
subject,
message,
from_email,
recipient_list,
fail_silently=False,
auth_user=None,
auth_password=None,
connection=None)
In PHP you can only send mail with a simple mail() command on non-Windows systems. These will expect a local MTA like Postfix to be installed and correctly configured, as should be the case for most web servers. If you want to depend on third-party or decentralized mail service depends on how critical email is for your application. Serious dependency on speedy and reliable email transmission usually results in sending mail via SMTP to a central mail server (the "big pipe").
Still, if you want to have the same function as in PHP, try this:
import subprocess
def send_mail(from_addr, to_addr, subject, body):
cmdline = ["/usr/sbin/sendmail", "-f"]
cmdline.append(from_addr)
cmdline.append(to_addr)
mailer = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
dialog = "From: %s\nTo: %s\nSubject: %s\n\n%s\n.\n" % (from_addr, to_addr, subject, body)
return mailer.communicate(dialog)
And use it like:
send_mail ("Me <myself#mydomain.com>", "Recip Ient <other#hisdomain.com>", "Teh' Subject", "Mail body")
Either way, you need some backend (read MTA). Of the top of my head I can think of two things:
As already pointed out, you can for example use sendmail http://djangosnippets.org/snippets/1864/
Even better, use a Python MTA. There's Lamson, a Python email server (MTA): http://lamsonproject.org/docs/hooking_into_django.html