Alan Hou的个人博客

Odoo 12开发者指南第二十三章 在Odoo中管理email

全书完整目录请见:Odoo 12开发者指南(Cookbook)第三版

Email集成是Odoo的一个最耀眼的功能。你可以通过Odoo用户界面直接发送和接收邮件。你甚至可以在业务文档中直接管理email线程,如线索、销售订单和项目。本章中,我们将探讨一些在Odoo处理邮件的重要方式。这里我们将讲解如下课题:

技术准备

本章的技术要求包含一个在线Odoo平台。

本章中使用的所有代码均可通过GitHub仓库进行下载:https://github.com/PacktPublishing/Odoo-12-Development-Cookbook-Third-Edition/tree/master/Chapter23。

观看如下视频来查看代码实时操作:

配置接收和发送邮件服务器

你在Odoo中发送和接收邮件之前,需要配置接收和发送邮件服务器。本节中,我们将学习如何在Odoo中配置邮件服务器。

准备工作

本节中无需进行任何开发,但需要有邮件服务器的信息,如服务器URL,端口、服务类型、用户名和密码。我们将使用这些信息来配置邮件服务器。

ℹ️如果你在使用在线Odoo或Odoo.sh,则无需配置邮件服务器。在这些平台上你无需进行任何复杂配置即可发送并接收邮件。本节针对的是自有主机Odoo实例。

如何实现…

配置接收和发送邮件服务器包含一些通用步骤和一些单独的步骤。因此首先我们将了解通用的配置步骤,然后我们单独配置接收和发送邮件服务器。下面是接收和发送邮件服务器所要求的通用步骤:

  1. 从菜单打开通用设置,Settings > General Settings。
  2. 进入Discuss版块并启用External Email Servers。这会显示如下选项:
  3. 在Alias Domain字段中,输入你的邮件服务器所运行的域名。然后保存配置。

配置接收邮件服务器

执行如下步骤来配置接收邮件服务器:

  1. 打开通用配置并点击 Incoming Email Servers链接。这会重定向到一个接收邮件服务器的列表视图。
  2. 点击Create按钮,会打开如下的表单视图。输入接收邮件服务器的详情(参见运行原理一节了解对每个字段的讲解):
  3. 点击Test & Confirm按钮来验证你的配置。如果你错误地配置接收邮件服务器的话它会显示错误信息。

配置发送邮件服务器

按照如下步骤来配置发送邮件服务器:

  1. 打开通用设置并点击Outgoing Email Servers链接。会重定向到发送邮件服务顺路的列表视图。
  2. 点击Create,它会打开如下表单视图。输入发送邮件服务器的详情(查看运行原理一节了解对每个字段的讲解):
  3.  点击页面底部的Test connection来验证配置。如果你错误地配置了发送邮件服务器的话它会显示错误信息。

ℹ️发送邮件服务器即使在正确地配置的情况下也可能会显示报错对话框。注意查看报错对话框中的 Connection Test Succeeded! Everything seems properly set up! 消息。它表示发送邮件服务器已正确地配置。

运行原理…

本节中给出的步骤已经很清楚了,无需进一步解释。但是发送邮件和接收邮件记录有一些字段,下面我们来看看它们的用途。

以下是用于配置接收邮件服务器的字段列表:

以下是在配置发送邮件服务器时所使用的字段列表:

扩展知识…

默认接收邮件每5分钟获取一次。如果想要修改这一间隔,可按照如下步骤进行操作:

  1. 激活开发者模式
  2. 通过Settings > Technical > Automation > Scheduled Actions打开计划动作列表
  3. 搜索并打开名为Mail: Fetchmail的计划动作
  4. 使用标记为Execute Every的字段来修改间隔

管理文档中的聊天器

本节中,我们将学习如何管理你的文档中的聊天器,并向记录添加通讯线程。

准备工作

本节我们将复用第九章 高级服务端开发技巧中的my_library模块。可以从本书GitHub仓库的Chapter09/r1_user_performing_actions目录中获取该模块的拷贝。本节中我们将对library.book.rent模型添加聊天器。

如何实现…

按照如下步骤来对library.book.rent模型的记录添加聊天器:

  1. 在__manifest__.py文件中添加mail模块依赖:
  2. 在library.book.rent模型的library.book.rent定义中继承mail.thread:
  3. 在library.book.rent模型的表单视图中添加聊天器组件:

安装my_library模块来实时查看修改:

如以上截图所示,在安装该模块之后你将能够在表单视图中查看聊天器。

运行原理…

要对任意模型启动聊天器,你需要首先安装mail模块。这是因为要求启动聊天器或邮件功能的所有代码都属于mail模块。因此在第1步中我们在my_library模块的声明文件中添加了mail模块依赖。这会在安装my_library模块时自动安装mail模块。

要求操作聊天器的字段和方法是mail.thread模型的一部分。mail.thread是一个抽象模型并且仅用于继承目的。在第2步中,我们在library.book.rent模型中继承了mail.thread模型。这会在library.book.rent模型中添加聊天器所需的必要字段和方法。如果你不知道模型继承如何运作,可参见第五章 应用模型中的为可复用模型功能使用抽象模型一节。

在前两步中,我们添加了聊天器所需要的所有字段和方法。聊天器所剩余的唯一事项是在表单视图中添加用户界面。在第3步中,我们添加了消息线程和关注者组件 。你可能在想message_follower_ids和message_ids字段。这些字段没有在library.book.rent模型定义中添加,但它通过对mail.thread模型的继承进行了添加。

扩展知识…

当你在聊天器中提交消息时,消息会发送给关注者。如果你注意观察本节中的示例,图书的借阅者并不是记录的关注者,因此他们不会接收到消息。如果你想要向借阅者发送消息通知,需要将其添加到借阅者列表中。可以手动通过用户有界面添加关注者,但如果想要自动添加他们,你可以使用message_subscribe()方法。查看如下代码 – 在我们将图书置为待借阅时,给定的代码会自动将借阅者添加到关注者列表中:

类似地,如果你希望从列表中删除关注者,可以使用message_unsubscribe()方法。

管理文档中的活动

在使用聊天器时,你还可以添加活动。它们用于对记录计划你的动作。这是一种对每条记录的待办事项列表。本节中,我们将学习如何对任意模型启用活动。

准备工作

本节我们将使用前一小节管理文档中的聊天器中的my_library模块。我们将对library.book.rent模型添加活动。

如何实现…

按照如下步骤来对library.book.rent模型添加活动:

  1. 在library.book.rent 模型的Python定义中继承mail.activity.mixin:
  2. 在library.book.rent模型的聊天器中添加mail_activity组件:

更新my_library模块来应用这些修改。这会显示聊天器活动:

这是用户能够管理不同的聊天器活动。注意由一个用户所设置的计划活动对另一个用户也可见。

运行原理…

活动是mail模块的一部分,并且你可以选择在聊天器中启用它们。要对记录启用活动,你需要继承mail.activity.mixin。类似mail.thread模型,mail.activity.mixin也是一个抽象模型。继承mail.activity.mixin将在模型中所有的必要字段和方法。这些方法和字段用于对记录管理活动。在第1步中,我们对library.book.rent模型添加了mail.activity.mixin。因此,对library.book.rent的继承将获取管理活动所要求的所有方法和字段。

在第2步中,我们在表单视图中添加了mail_activity组件。它将显示管理活动的UI界面。通过继承在library.book.rent模型中添加了activity_ids字段。

活动可以为不同的类型。默认,你可以创建类型为Email、电话、会议和待办事项的活动。如果你希望添加自己的活动类型,可以通过在开发者模式下访问Settings > Technical > Email > Activity Types来实现。

扩展知识…

如果你想要自动设置一个定时活动,可以使用mail.activity.mixin模型的 activity_schedule()方法。它会在指定日期创建该活动。可以通过activity_schedule()方法手动创建定时活动,如下:

本例将在有人借阅图书时为图书管理员设置定时电话活动。活动的截止日期设置为图书的归还日期,因此图书管理员可在当天对借阅者打电话。

使用Jinja模板发送邮件

Odoo支持通过Jinja模板创建动态邮件。本节中我们钭创建一个Jinja邮件模板,然后借助它发送邮件。

准备工作

本节中我们将使用前一小节管理文档中的活动中的my_library模块。我们将添加Jinja模板来发送邮件给借阅者告诉他/她图书已逾期。

如何实现…

按照如下步骤来向借阅者发送提醒邮件:

  1. 创建名为my_library/data/mail_template.xml的文件并添加邮件模板:
  2. 在声明文件中注册模板文件:
  3. 在library.book.rent模型的表单视图中添加Send reminder按钮来发送邮件:
  4. 在library.book.rent模型中添加book_return_reminder()方法:

更新my_library模块来应用修改。这会在library.book.rent模型的表单视图中添加一个Send reminder按钮。在他们点击该按钮时,订阅者会收到如下消息:

本节中所展示的流程在你想要通过邮件向客户发送更新时会很有用。借助Jinja模板,你可以发送基于单条记录的动态邮件。

运行原理…

在第1步中,我们使用Jinja创建了一个邮件模板。Jinja模板帮助我们根据记录数据生成一个动态邮件。邮件模板存储在mail.template模型中。让我们来看一下为创建Jinja邮件模板你需要传递的字段列表:

小贴士:可以在email_from, email_to, subject和lang字段中使用${}。这有且于我们动态设置值。参见本节的第1步,我们使用了${object.borrower_id.email}来动态设置了email_to字段。

如果你仔细查看body_html字段的内容,会发现我们使用了${object.borrower_id.name}。这里,该对象是一个library.book.rent模型的记录集。在渲染期间,${object.borrower_id.name}使用借阅者的名字进行替换。类似object,在渲染上下文中传递了一些其它帮助函数和变量。以下是传递给渲染器上下文的帮且函数列表:

在第2步中,我们在声明文件中注册了模板文件。

在第3步中,我们在表单视图中添加了一个按钮来调用book_return_reminder()方法,它会向关注者发送邮件。

在第4步中,我们添加了book_return_reminder()方法,它将通过点击按钮进行调用。message_post_with_template()方法用于发送邮件。message_post_with_template()方法在模型中通过mail.thread来继承。要发送邮件,你只需要传递模板ID来作为参数。

ℹ️如果想要看到模板列表,激活开发者模式并打开Settings > Technical > Email > Templates菜单。模板的表单视图还提供预览已渲染模板的按钮。

扩展知识…

message_post_with_template()方法用于通过Jinja模板发送邮件。如果你只是想要通过普通文件发送邮件,可以使用message_post()方法:

以上的代码会在聊天器中添加一条Please return your book on time 的消息。所有的关注者会得到这个消息的通知。如果你只是想要记录这条消息,通过subtype_id参数调用该方法。

使用QWeb模板发送邮件

在前一节中,我们学习了如何使用Jinja模板发送邮件。本节中,我们将了解发送动态邮件的另一种方式。我们将借助于QWeb模板来发送邮件。

准备工作

本节,我们将使用前一节使用Jinja模板发送邮件中的my_library模块。我们将使用QWeb模板来向借阅者发送邮件来告诉他/她图书已逾期。

如何实现…

按照如下步骤来向借阅者发送提醒邮件:

  1. 在my_library/data/mail_template.xml文件中添加QWeb模板:
  2. 在library.book.rent模型的表单社稷中添加Send reminder (QWeb) 按钮来发送邮件:
  3. 在library.book.rent 模型中添加book_return_reminder_qweb()方法:

更新my_library模块来应用修改。这会在library.book.rent模型的表单视图中添加一个Send reminder (QWeb)按钮。在点击该按钮时,关注者会获取一条如下的消息:

本节中所展示的流程和前一节使用Jinja模板发送邮件基本一致。唯一的不同是模板类型,因为本节中使用QWeb模板。

运行原理…

在第1步中,我们通过book_return_reminder_qweb ID创建了一个QWeb模板。如果你查看这个模板,我们不再使用 format_date()数据字段方法。这是因为QWeb渲染引擎自动根据用户的语言处理并展示日期。出于同样的原因,你不需要使用format_amount() 方法来展示货币符号。QWeb渲染引擎将会自动对其进行管理。如果想要了解更多有关QWeb模板的知识,可参见第十五章 CMS网站开发中的创建或更改模板 – QWeb一节。

在第2步中,我们在表单视图中添加了一个按钮来调用book_return_reminder_qweb()方法,它向关注者发送邮件。

在第3步中,我们添加了book_return_reminder_qweb()方法,它通过按钮的点击进行调用。message_post_with_view()方法用于发送邮件。message_post_with_view()方法在模型中通过mail.thread来继承。要发送邮件,你只需传递网页模板的XML ID来作为参数。

通过QWeb模板发送邮件与前一节的运行方式相同,但QWeb邮件模板和Jinja邮件模板之间有一些细微的差别。以下是对这两种模板的快速对比:

扩展知识…

所有的方法(message_post, message_post_with_template和message_post_with_view)都和用户首选项有关。如果用户通过用户首选项修改通知管理选项,该用户将不会收到邮件:取而代之的是他们将在Odoo的用户界面中接收到通知。对于客户同样如此,如果用户取消邮件订阅,他们将不会通过邮件收到任何更新。

此外,Odoo的消息线程遵循一种称为子类型的概念。子类型仅用于接收你所感兴趣的邮件。你可以传递额外的参数subtype_id,在message_post_*方法中根据子类型发送邮件。通常,用会会通过Follow按钮的下拉选项管理它们的子类型。我们假定用户设置他们的子类型如下:

根据用户的首选项,该用记仅会收到讨论消息的邮件。

管理邮件别名

邮件别名是Odoo中用于通过接收邮件创建记录的一种功能。邮件别名的最简单示例是销售团队。你只需要发送一封邮件到sale@yourdomain.com,Odoo会在销售团队中针对crm.lead 新建一条记录。本节中,我们将创建一个邮件别名来创建一本图书的借阅记录。

准备工作

本节我们将使用前一节使用QWeb模板发送邮件中的my_library模块。我们会使用rent@yourdomain.com邮箱地址创建自己的邮件别名。如果向这个邮箱发送一封标题中带有图书名称的邮件,在 library.book.rent模型中会创建一条记录。

如何实现…

按照如下步骤来为library.book.rent模型添加邮件别名:

  1. 在my_library/data/mail_template.xml文件中添加邮件别名数据:
  2. 在my_library/models/library_book_rent.py文件中添加如下导入:
  3. 在library.book.rent模型中重载message_new()方法:

更新my_library模块来应用修改。然后发送邮件到rent@yourdomain.com。确保你在邮件标题中包含了图书名称,如[Odoo 12 Development Cookbook] Request to borrow this book。这会创建一条新的library.book.rent记录并且它会显示如下:

在你向rent@yourdomain.com发送带有图书名邮件标题的邮件时,Odoo会生成一条新借阅记录。注意在仅对图书在图书馆中可借阅时才会生效。

运行原理…

在第1步中,我们创建了mail.alias记录。这个别名会处理rent@yourdomain.com邮箱地址。在你向这个地址发送邮件时,Odoo会在library.book.rent 模型中新建一条记录。如果你想要查看系统中活跃的别名列表,可打开Setting > Technical > Email > Aliases。些处为配置别名的可用字段列表:

在第2步中,我们添加了所需的导入。

在第3步中,我们重载了message_new()方法。该方法在别名邮箱上接收到新邮件时自动被调用。这个方法会接收两个参数:

本节中我们重载了message_new()方法并从邮件标题中通过一个正则表达式获取到图书的标题。然后我借助在第2步中导入的工具获取到发件人的邮箱。我们使用发件邮箱地址来查找借阅者记录。然后,我们通这两个值来更新custom_values:books_id和borrower_id。我们将更新后的custom_values数据传递给super()方法,它会通过给定的books_id和borrower_id新建一条library.book.rent记录。这就是在你发送邮件到别名时如何创建的记录。

注意本节在你没有发送适当的邮件标题时会产生报错,如[book name] remaining subject。你可以根据自己的业务逻辑来更新程序以避免报错。

扩展知识…

一些业务模型要求你需要对第条记录使用单独的别名。例如,销售团队对每个团队有独立的别名,如对印度团队使用sale-in@example.com,对比利时团队使用sale-be@example.com。如果你想要在自己的模型中管理这这种别名,可以使用mail.alias.mixin。为了能在自己的模型中使用它,你需要继承这个mixin:

在继承该mixin后,你将需要向表单视图添加alias_name字段,以便终端用衣可以自己添加别名。

在聊天器中记录用户修改

Odoo框架提供了一种内置工具在记录聊天器中的字段修改。本节中,我们将对其中的一些字段启用记录,因此如果对它们做出修改,Odoo会在聊天器中添加记录。

准备工作

本节我们将使用前一节管理邮件别名中的my_library模块。本节中我们将记录 library.book 模型中一些字段的修改。

如何实现…

修改这些字段的定义来在你修改它们时启用对这些字段的记录。如以下代码片断所示:

更新my_library模块来应用修改。在library.book.rent模型中新建一条记录,在这些字段中做一些修改,然后中归还图书。如果查看聊天器,你会看到如下日志:

在你对state, rent_date或return_date作出修改时,都会在聊天器中看到新的日志。这会有助于你查看该记录的完整历史信息。

运行原理…

通过对这个字段添加track_visibility属性,你可以对该字段启用日志。它有两个可选的值:onchange和always。在设置track_visibility=”onchage属性时,Odoo会在聊天器中添加一个更新字段值时的修改记录。在设置track_visibility=”always”属性时,即使值未进行修改Odoo也会在日志中一直显示记录值。这用于让日志信息量更充分。当然,带有track_visibility=”always”属性的字段会在字段值修改时添加日志。

本节中,我们对state字段添加了track_visibility=’always’,并对rent_date和return_date字段添加了track_visibility=’onchange’。这表示Odoo会在更新ent_date, return_date或state 字段的值时记录这些修改。但因为state设置为track_visibility=’always’,即使它的值未进行修改也会进行记录。查看如何实现小节中的截图,我们仅修改了rent_date字段,并设置了日志显示State: Ongoing。

注意track_visibility功能仅用于继承了 mail.thread模型的模型,因此代码相关的聊天器和日志是mail.thread 模型的一部分。

退出移动版