0
votes

I am writing a script to auto send emails from outlook. Inbound mail from a third party contains a recipients Name, Email Address and an Activation Code. I iterate through the received messages, harvest the required information and then send a message to the customer based on an outlook template. The script works fine with a single message but it seems to be loosing the template on subsequent messages.

The specific error I receive is: (-2147352567, 'Exception occurred.', (4096, 'Microsoft Outlook', 'The item has been moved or deleted.', None, 0, -2147221238)

The relevant code snippets are as follows:

I have a class for instantiating a connection to outlook.

class MailboxHandler():
""" Used to instantiate outlook instance for handling mail. """

def __init__(self, mailbox, email_template):
    self.mailbox = mailbox
    self.email_template = email_template

def mailbox_interface(self):
    "Instatiate instance of mailbox COM Object"
    try:
        mailbox = self.mailbox
        email_template = self.email_template
        outlook_in = win32com.client.Dispatch(
            "Outlook.Application").GetNamespace("MAPI")
        outlook_out = win32com.client.Dispatch("Outlook.Application")
        inbox = outlook_in.Folders(mailbox).Folders("Inbox")
        destination = outlook_in.Folders(mailbox).Folders("Completed")
        template = outlook_out.CreateItemFromTemplate(email_template)
    except Exception as Errors:
        print("{}".format(Errors))
        pass
    return inbox, destination, template

There is a Mailer() class for sending a receiving:

class Mailer():
""" Handles email activity """

def __init__(self, mailbox, email_template):
    self.mailbox_instance = MailboxHandler(mailbox, email_template)
    self.inbox, self.destination, self.template = self.mailbox_instance.mailbox_interface()

def new_inbound_mail(self):
    try:
        messages = self.inbox.Items
    except Exception as Errors:
        LOGGER.error(Errors)
        pass
    return messages

def move_mail(self, message):
    try:
        message.Move(self.destination)
        print("{} has been moved to {}.".format(message.Subject, self.destination))
    except Exception as Errors:
        LOGGER.error(Errors)


def send_mail(self, email_address, email_subject, customer_name, activation_code):
    try:
        template = self.template
        email_temp = template.HTMLBody
        email_temp = email_temp.replace(
            "<CUSTOMER NAME>", customer_name)
        email_temp = email_temp.replace(
            "&lt;ACTIVATION CODE&gt;", "<strong>" + activation_code + "</strong>")
        template.HTMLBody = email_temp

        template.To = email_address
        template.Subject = email_subject
        template.Send()
    except Exception as Errors:
        LOGGER.error(Errors)

From main() I loop through the messages, and call send_mail() to email a customer. The first message sends but all subsequent messages fail. Any suggestions? I may be way off but I feel it must be something happening on the windows side of the fence or within the win32com.client module.

1
FWIW I resolved the issue by moving the 2 lines of code that handled the email template from the MailboxHandler() class to the send_email() method. Works perfectly now. - Dave

1 Answers

0
votes

FWIW I resolved the issue by moving the 2 lines of code that handled the email template (below) directly into the send_mail() method.

    def send_mail(self, email_template, email_address, email_subject, customer_name, activation_code):
    try:
        outlook = win32com.client.Dispatch("Outlook.Application")
        template = outlook.CreateItemFromTemplate(email_template)