Python Power Automate - Email
Outlook email sent through flows - templates, attachments and reacting to incoming messages.
Sending email through Office 365 Outlook is among the most used Power Automate actions. Driving it through flows gives you what plain SMTP does not - the mail goes out from a real mailbox with the organization's branding, signatures and compliance rules, and business users can adjust the templates without touching your code. The service sends the data, the flow with its "Send an email" action does the rest.
Sending an email
# -*- coding: utf-8 -*-
# Zato
from zato.server.service import Service
class SendWelcomeEmail(Service):
input = 'recipient', 'customer_name'
def handle(self):
# Get the connection by its Dashboard name
conn = self.microsoft.power_platform['My Power Automate']
# The flow sends the email from the team's shared mailbox
conn.trigger('flow-send-welcome-email', {
'recipient': self.request.input.recipient,
'customer_name': self.request.input.customer_name,
})
self.response.payload = {'status': 'sent'}
Templated notifications
Keep the email's layout in the flow and send only the fields that vary - the flow fills its template with them. Business users edit the template in Power Automate, your service stays the same.
# -*- coding: utf-8 -*-
# Zato
from zato.server.service import Service
class SendOrderConfirmation(Service):
input = 'recipient', 'order_id', 'total', 'delivery_date'
def handle(self):
conn = self.microsoft.power_platform['My Power Automate']
conn.trigger('flow-order-confirmation', {
'recipient': self.request.input.recipient,
'order_id': self.request.input.order_id,
'total': self.request.input.total,
'delivery_date': self.request.input.delivery_date,
})
Emails with attachments
Attachments travel base64-encoded in the payload, and the flow's "Send an email" action attaches them.
# -*- coding: utf-8 -*-
# stdlib
from base64 import b64encode
# Zato
from zato.server.service import Service
class SendInvoiceEmail(Service):
input = 'recipient', 'invoice_id'
def handle(self):
conn = self.microsoft.power_platform['My Power Automate']
# Generate the invoice PDF ..
invoice = self.invoke('billing.render-invoice-pdf', {
'invoice_id': self.request.input.invoice_id,
})
# .. encode it for transport ..
content = b64encode(invoice['pdf']).decode('ascii')
# .. and let the flow send it as an attachment.
conn.trigger('flow-send-invoice', {
'recipient': self.request.input.recipient,
'invoice_id': self.request.input.invoice_id,
'attachment_name': f'invoice-{self.request.input.invoice_id}.pdf',
'attachment_content': content,
})
Reacting to incoming email
The other direction uses a flow with the "When a new email arrives" trigger whose action calls a Zato REST channel - a mailbox becomes an API. The service below is what the channel invokes.
# -*- coding: utf-8 -*-
# Zato
from zato.server.service import Service
class OnOrderEmailReceived(Service):
""" Invoked by a flow whenever an email arrives in the orders mailbox.
"""
input = 'sender', 'subject', 'body'
def handle(self):
sender = self.request.input.sender
subject = self.request.input.subject
self.logger.info('Order email from %s: %s', sender, subject)
# Continue the process - parse the order, create it in the ERP, and so on
self.invoke('orders.create-from-email', {
'sender': sender,
'body': self.request.input.body,
})