Correct way to e-mail custom HTML record in function?

Hi guys,

I've been trying to create a function to send out HTML e-mails but I always run stuck.
I first created a new model '' which will be the older for my e-mail templates like this:

# -*- coding: utf-8 -*- from openerp import models, fields, api, _ from openerp.exceptions import Warning class odoo_environment_emails(models.Model): _name = '' name = fields.Char('E-mail name', required=True) email = fields.Char('E-mailadress primary person', required=True) email_cc = fields.Char('Emailadress CC persons') email_title = fields.Char('E-mail title', required=True) message = fields.Html('Message', required=True)

I then created a custom template in XML which contains HTML content:

<openerp> <data noupdate="1"> <record id="odoo_email_installation" model=""> <field name="name">Title</field> <field name="email"></field> <field name="email_cc"></field> <field name="email_title">New record(${object.odoo_username}) created!</field> <field name="message"><![CDATA[ <p>My custom text: ${}</p> </field> </record> </data> </openerp>

On another model 'odoo.environment' I've created a Many2many where you can add all the e-mail templates you like, which are created on the model '':

odoo_emails_to_send = fields.Many2many('', string='E-mails to send after installation', default=_get_default_emails)

Now I have a Python function that is triggered when the user clicks on a function. This function will loop over all items added in the Many2many and every e-mail template added should throw out an own e-mail. What I have now:

def send_required_mails(self, cr, uid, ids, record, context=None): # Get e-mail server ir_mail_server = self.pool.get('ir.mail_server') # Get all selected e-mail templates email_template_ids = record.odoo_emails_to_send # Send out one template at a time for email_id in email_template_ids: email_template = self.pool.get('').browse(cr, uid, title = email_template.email_title message = email_template.message msg = ir_mail_server.build_email('', [], title, message, [email_template.email_cc or ''], [], '') ir_mail_server.send_email(cr, uid, msg

This works pretty nice but I have 1 problem: the HTML is not rendered and all ${object.variable} are not filled / converted. I've read some posts and it seems to be that I need to send the e-mail out with generate_email, so I tried:

def send_required_mails(self, cr, uid, ids, record, context=None): # Send out one template at a time for email_id in email_template_ids: template_id = self.pool.get('').get_object(cr, uid, 'auto_odoo_installer', 'odoo_email_installation').id template_ids = self.pool.get('').browse(cr, uid, template_id) email_template_obj = self.pool.get('email.template') if template_ids: values = email_template_obj.generate_email(cr, uid, template_ids[0], ids, context=context) values['subject'] = subject values['email_to'] = email_to values['body_html'] = body_html values['body'] = body_html values['res_id'] = False mail_mail_obj = self.pool.get('mail.mail') msg_id = mail_mail_obj.create(cr, uid, values, context=context) if msg_id: mail_mail_obj.send(cr, uid, [msg_id], context=context) return True

However this keeps throwing up errors. For example:

File "/odoo/odoo-server/openerp/", line 256, in wrapper return old_api(self, *args, **kwargs) File "/odoo/odoo-server/addons/email_template/", line 219, in get_email_template_batch results = dict.fromkeys(res_ids, False) TypeError: unhashable type: 'list

So, how should I correctly send out these e-mails and get the HTML and ${object.variable} converted to plain text in the e-mail?


1 Comment
Dr Obx

Got the same problem. Will follow this subject

1 Answer
Axel Mendoza
Best Answer


Take this code of one of our modules as example, The code in bold is like do it all for me with just the object and the context vars:

def send_notifications(self, cr, uid, ids, context=None):

template_pool = self.pool.get('email.template')

template = self.pool.get('').get_object(cr, uid, 'solt_maintenance_preventive', 'solt_maintenance_remind_email')

assert template._name == 'email.template'

if context == None:

context = {}

res_groups_pool = self.pool.get('res.groups')

emails_send = []

group_id = self.pool.get('').get_object_reference(cr, SUPERUSER_ID,

'solt_maintenance', 'group_maintenance_planner')

if group_id:

for users_obj in res_groups_pool.browse(cr,uid,group_id[1],context=context).users:



context['email_send'] = ",".join(emails_send)

for sched in ids:

msg_id = template_pool.send_mail(cr, uid,, sched, True, context=context)

The template used is here:

<record id="solt_maintenance_remind_email" model="email.template">

<field name="name">Maintenance Remind Email</field>

<field name="model_id" ref="model_solt_maintenance_schedule" />

<field name="email_from"><![CDATA[${} <${}>]]></field>

<field name="email_to">${ctx.email_send}</field>

<field name="subject">[Recordatorio] Intervención de mantenimiento para:


<field name="body_html"><![CDATA[

<p>Se ha determinado que al objetivo ${} se le debe proporcionar mantenimiento de acuerdo a su programacion.</p>