Python To Send Emails Via Outlook Express

I

ian

Hi,
I'm a newbie (oh no I can here you say.... another one...)

How can I get Python to send emails using the default windows email
client (eg outlook express)?

I thought I could just do the following

import win32com.client

s = win32com.client.Dispatch('CDO.Message')
s.From = "(e-mail address removed)"
s.To = "(e-mail address removed)"
s.Subject = "The subject"
s.Send

.... but nothing happens.

What am I doing wrong? Does anyone have some sample code to share with
me please?

Thank you!

Ian Cook

(freeware author of Kirby Alarm And Task Scheduler www.kirbyfooty.com)
 
I

ian

Hi Ganesan
I tried changing s.Send to s.Send(). It now comes up with an exception
error..

The details are below.

Ian

Traceback (most recent call last):
File
"C:\Python23\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py",
line 307, in RunScript
debugger.run(codeObject, __main__.__dict__, start_stepping=0)
File
"C:\Python23\Lib\site-packages\pythonwin\pywin\debugger\__init__.py",
line 60, in run
_GetCurrentDebugger().run(cmd, globals,locals, start_stepping)
File
"C:\Python23\Lib\site-packages\pythonwin\pywin\debugger\debugger.py",
line 595, in run
exec cmd in globals, locals
File "D:\MyPython\emailtest.py", line 7, in ?
s.Send()
File
"C:\Python23\lib\site-packages\win32com\gen_py\CD000000-8B95-11D1-82DB-00C04FB1625Dx0x1x0.py",
line 686, in Send
return self._oleobj_.InvokeTypes(158, LCID, 1, (24, 0), (),)
com_error: (-2147352567, 'Exception occurred.', (0, None, 'The server
rejected one or more recipient addresses. The server response was: 554
<[email protected]>: Relay access denied\r\n', None, 0, -2147220977),
None)
 
F

Fredrik Lundh

I tried changing s.Send to s.Send(). It now comes up with an exception
error..
com_error: (-2147352567, 'Exception occurred.', (0, None, 'The server
rejected one or more recipient addresses. The server response was: 554
<[email protected]>: Relay access denied\r\n', None, 0, -2147220977),
None)

sure looks like you managed to talk to the mail program, but your mail
server thinks you're trying to send faked mails. your local mail admins
can probably help you sort this one out.

(googling for "Relay access denied" could also help)

</F>
 
I

ian

Thanks Fredrik,
That was my first impression too.

But all I want to do is use Python to instruct Outlook Express to send
an email.
That way the user would not have to do any setting up etc of the mail
server properties etc and Outlook Express will magage all the
connection side of things.

I have seen other python scripts that will talk to Excel etc but so far
(despite a lot of searching) I cannot see how Python can talk to
Outlook Express.

I know I can do this in Clarion by accessing MapiSendEmail but because
I'm new to Python I don't know how to do it in Python. I'm really
impressed with the power of Python. It seems just about anything you
can think of is there already so I know th eanswer is out there
somewhere!

Can this be done using Python? Does anyone have a sample script please?
Pretty please?? <grin>

Ian
 
K

Keith Dart

Hi Ganesan
I tried changing s.Send to s.Send(). It now comes up with an exception
error..

The details are below.

Looks like the COM part works, but sending mail has an error from the
SMTP host. But, slightly off topic, FYI, Python can send email directly
with the email and snmplib modules.
 
F

Fredrik Lundh

But all I want to do is use Python to instruct Outlook Express to send
an email.

and you succeeded -- the error message you saw came from the mail server, not
outlook itself. your problem is that the server didn't like the mail you sent; checking
the server configuration (or just the server logs) can help you figure out why.

have you tried different From/To settings, btw?

</F>
 
M

Max M

Thanks Fredrik,
That was my first impression too.

But all I want to do is use Python to instruct Outlook Express to send
an email.


Which you did! From the look of the traceback.

But your mailserver is configured in such a way that you cannot send
mail from your machine using those email adresse, or you don't log on
with the correct credentials.


--

hilsen/regards Max M, Denmark

http://www.mxm.dk/
IT's Mad Science
 
I

ian

Hi Keith
Thanks for your reply.

I am aware of the smtplib module and it works very well! (refer script
below)

The problem is that I have a developed a freeware application called
Kirby Alarm And Task Scheduler (see www.kirbyfooty.com).
The program can pop up a note, run a program, play a sound, or send an
email at whatever intervals the user wants..
When it comes to sending emails the user has the option of sending them
via smtp, or via there email client (eg outlook express). I prefer the
send method as this makes setting up the email parameters a lot easier
for the user.
As the program is used by over 16,000 people around the world I don't
want to complicate things by asking them to enter the mail server
properties.

Because Python is so powerful I want to develop a suite of applications
in Python that Kirby Alarm can run.
Things like FTP, Backup, Speech etc would be excellent


There has to be a way for Python to send emails via Outlook Express....

Kind regards
Ian

PS Here is the working script for sending emails via SMTP..

-----------------------------------------------------------------------------------------------------------------

# Import smtplib for the actual sending function
import os
import sys
import smtplib
import mimetypes
from email.Encoders import encode_base64
from email.MIMEAudio import MIMEAudio
from email.MIMEBase import MIMEBase
from email.MIMEImage import MIMEImage
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText


FROM = '(e-mail address removed)'
TO = '(e-mail address removed);[email protected]'
SUBJECT = 'This is the subject'
MSGBODY = 'This the body of the message '
ATTACHSTR =
'c:/ian.txt;c:/c55/footytip/2003finalresults.txt;c:/snap.jpg'
MAILSERVER = 'insert mail server'
port = 25
username = 'insert username'
password = 'insert password'

# trim the strings of any leading or trailing spaces
FROM = FROM.strip()
TO = TO.strip()
SUBJECT = SUBJECT.strip()
MSGBODY = MSGBODY.strip()
ATTACHSTR = ATTACHSTR.strip()
MAILSERVER = MAILSERVER.strip()
username = username.strip()
password = password.strip()

# function to attach files
def getAttachment(path, filename):
ctype, encoding = mimetypes.guess_type(path)
if ctype is None or encoding is not None:
ctype = 'application/octet-stream'
maintype, subtype = ctype.split('/', 1)
fp = open(path, 'rb')
if maintype == 'text':
attach = MIMEText(fp.read(),_subtype=subtype)
elif maintype == 'message':
attach = email.message_from_file(fp)
elif maintype == 'image':
attach = MIMEImage(fp.read(),_subtype=subtype)
elif maintype == 'audio':
attach = MIMEAudio(fp.read(),_subtype=subtype)
else:
print maintype, subtype
attach = MIMEBase(maintype, subtype)
attach.set_payload(fp.read())
encode_base64(attach)
fp.close
attach.add_header('Content-Disposition', 'attachment',
filename=filename)
return attach

#Connect to server
print 'Connecting to mail server ', MAILSERVER
try:
s = smtplib.SMTP(MAILSERVER,port)
#s.set_debuglevel(1)
except:
print 'ERROR: Unable to connect to mail server', MAILSERVER
sys.exit(1)

#login to server
if password <> '':
print 'Logging into mail erver'
try:
s.login(username,password)
except:
print 'ERROR: Unable to login to mail server', MAILSERVER
print 'Please recheck your password'
sys.exit(1)

# get list of email addresses to send to
ToList = TO.split(';')
print 'Sending email to ', ToList

# set up email parameters
msg = MIMEMultipart()
msg['From'] = FROM
msg['To'] = TO
msg['Subject'] = SUBJECT
msg.attach(MIMEText(MSGBODY))


# get list of file attachments
AttachList = ATTACHSTR.split(';')
for file in AttachList:
try:
attach = getAttachment(file,os.path.basename(file))
msg.attach(attach)
except:
print 'Error attaching ',file
pass


# send email
s.sendmail(FROM, ToList, msg.as_string())
s.quit()
s.close()

print 'done'
-----------------------------------------------------------------------------------------
 
I

ian

Hi Fredrik,
Thank you for the suggestion.

I tried different from/to settings and guess what? The mail came thru.

The script is now..
import win32com.client

s = win32com.client.Dispatch('CDO.Message')
s.From = "(e-mail address removed)" (was
"(e-mail address removed)")
s.To = "(e-mail address removed)" (was
"(e-mail address removed)")
s.Subject = "The subject"
s.Send()


My problem is thought, the message is still not being sent via Outlook
Express.
What am I missing?
Thanks again for your help so far!!

Kind regards
Ian
 
G

Ganesan R

ian" == ian said:
But all I want to do is use Python to instruct Outlook Express to send an
email. That way the user would not have to do any setting up etc of the
mail server properties etc and Outlook Express will magage all the
connection side of things.

Are you sure CDO.Message uses OE configuration to send mail? The examples of
CDO.Message usage that I see on the net appear to explicitly load some
configuration. Try this for example,

cdoSourceOutlookExpress = 2
s.Configuration.Load(cdoSourceOutlookExpress)

before s.Send(). It looks like by default CDO.Message() will use the local
IIS "Virtual SMTP Server" which refuses to relay by default.

Ganesan
 
I

ian

Hi Ganesan

Wow, I'm REALLY impressed with the high level of support in this forum.
(Another great reason to continue learning Python <grin>

I tried what you suggested.
After trying a different from/to address the message is sent. But it is
NOT sent via Outlook Express.

I would appreciate any other suggestions.

Thanks in advance


The script is now..

import win32com.client

s = win32com.client.Dispatch('CDO.Message')
s.From = "(e-mail address removed)"
s.To = "(e-mail address removed)"
s.Subject = "The subject"
cdoSourceOutlookExpress = 2
s.Configuration.Load(cdoSourceOutlookExpress)
s.Send()
 
G

Ganesan R

ian" == ian said:
Hi Ganesan
Wow, I'm REALLY impressed with the high level of support in this forum.
(Another great reason to continue learning Python <grin>

Well, I am a Linux guy myself. I experimented with win32com a bit a couple
of weeks back, so I am trying my ideas on you ;-).
I tried what you suggested. After trying a different from/to address the
message is sent. But it is NOT sent via Outlook Express.

s.Configuration.Load(cdoSourceOutlookExpress) only loads the OutlookExpress
configuration. It does not use Outlook Express to send. I am surprised why
your original from and to address settings didn't work after calling the
Load() method.

I did some more reading. Unlike Outlook which you can automate by getting
the application object using CreateObject("Outlook.Application") and
automate it, Outlook Express is not a COM server.

Ganesan
 
S

Steve Holden

Hi Fredrik,
Thank you for the suggestion.

I tried different from/to settings and guess what? The mail came thru.

The script is now..
import win32com.client

s = win32com.client.Dispatch('CDO.Message')
s.From = "(e-mail address removed)" (was
"(e-mail address removed)")
s.To = "(e-mail address removed)" (was
"(e-mail address removed)")
s.Subject = "The subject"
s.Send()


My problem is thought, the message is still not being sent via Outlook
Express.
What am I missing?
Thanks again for your help so far!!

Kind regards
Ian
Unfortunately Outlook Express isn't programmable in the same way as
Outlook. I used to use it because this property gave it a certain degree
of immunity from macro viruses (back in the days when Outlook came
configured to open any Office document it came across).

About the next you can do is to add your email address as a Cc and then
file the messages when you receive them, I suspect.

Why the insistence on using Outlook Express, is you don;t mind me asking?

regards
Steve
(who almost always uses smtplib)
 
I

ian

Hi Steve,
Why the insistence on using Outlook Express, is you don;t mind me
asking?
Good question.
The problem is that I have a developed a freeware application called
Kirby Alarm And Task Scheduler (see www.kirbyfooty.com).
The program can pop up a note, run a program, play a sound, or send an
email at whatever intervals the user wants..

When it comes to sending emails the user has the option of sending them
via smtp, or via there email client (eg outlook express).
I prefer the send method as this makes setting up the email parameters
a lot easier for the user.
As the program is used by over 16,000 people around the world I don't
want to complicate things by asking them to enter the mail server
properties.
I have written Kirby Alarm in Clarion. It can currently send the email
via outlook express by calling MapiSendMail.

I wanted to do the same thing in Python so I can build up a suite of
useful utilities and therefore try an keep the program size relatively
small.

Ian
 
M

Max M

Hi Steve,
When it comes to sending emails the user has the option of sending them
via smtp, or via there email client (eg outlook express).
I prefer the send method as this makes setting up the email parameters
a lot easier for the user.


If Outlook Express cannot be automated through COM, you are in abind.
Maybe you should shange your tactics.

What about just fetching the settings from the client?

That way the send function will be the same, and you can control it. But
the server settings could be fetched from the different clients.

It is probably much simpler to find those than it is to use them as the
sender.

Most email clients can fetch the settings from other mail clients, so
it's been done before.

--

hilsen/regards Max M, Denmark

http://www.mxm.dk/
IT's Mad Science
 
I

ian

Hi Max,
Thanks for the suggestion. I'm always open to new ideas.

Can you please tell me how to retrieve the default account settings
from Outlook Express?

Ian
 
G

Ganesan R

ian" == ian said:
Hi Max,
Thanks for the suggestion. I'm always open to new ideas.
Can you please tell me how to retrieve the default account settings
from Outlook Express?

s.Configuration.Load(2) is supposed to do exactly that. I have no clue
why that didn't work for you :-(.

Ganesan
 
I

ian

Hi Ganesan,
I'm on the verge of giving up <sigh>
I don't suppose you could write a small script to send the email for me
via the default windows email client. I will then try running your
script and my end to see if it works ok.
I may have missed something and would really appreciate your help.
Thanks in advance
Ian
 
G

Ganesan R

ian" == ian said:
Hi Ganesan,
I'm on the verge of giving up <sigh>
I don't suppose you could write a small script to send the email for me
via the default windows email client.

I can see no easy way to do this. Though you can access the default mail
client using a registry key (I don't have enough win32 programming
experience to do this), there is no guarantee that the email client is a COM
server. Even Outlook Express is not a COM server. What if the user has
configured Eudora or something like that?

The best we can do is use Outlook Express settings and send the mail.
I will then try running your script and my end to see if it works ok. I
may have missed something and would really appreciate your help.

The final script that you pasted:

=====
import win32com.client

s = win32com.client.Dispatch('CDO.Message')
s.From = "(e-mail address removed)"
s.To = "(e-mail address removed)"
s.Subject = "The subject"
cdoSourceOutlookExpress = 2
s.Configuration.Load(cdoSourceOutlookExpress)
s.Send()
=====

works fine for me. According to CDO.Message documentation, if IIS is
installed that configuration will be used by default, followed by OE
configuration. I don't have IIS installed, so the script picked up the OE
configuration automatically for me. Here's a variation of the above
script.

======
import win32com.client

s = win32com.client.Dispatch('CDO.Message')
c = win32com.client.Dispatch('CDO.Configuration')
cdoSourceOutlookExpress = 2
c.Load(cdoSourceOutlookExpress)
s.Configuration = c
s.From = "(e-mail address removed)"
s.To = "(e-mail address removed)"
s.Subject = "The subject"

s.Send()
======

If that doesn't help, I give up :-(.

Ganesan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top