发送和接收电子邮件
发送和接收电子邮件的第一步是设置一个EmailServer,像这条记录加载的:
<moqui.basic.email.EmailServer emailServerId="SYSTEM"
smtpHost="mail.test.com" smtpPort="25" smtpStartTls="N" smtpSsl="N"
storeHost="mail.test.com" storePort="143" storeProtocol="imap"
storeDelete="N" mailUsername="TestUser" mailPassword="TestPassword"/>
注意这些都是示例值,应被改成实际值,特别是smtpHost、storeHost、mailUsername和mailPassword字段。store*字段是为了连接远程邮件服务器接收邮件的。这是端口字段的一些其他常见的值:
- smtpPort: 25(SMTP), 465(SSMTP), 587(SSMTP)
- storeProtocol=imap时的storePort: 143(IMAP), 585(IMAP4-SSL), 993(IMAPS)
- storeProtocol=pop3时的storePort:110(POP3), 995(SSL-POP)
如果你需要使用多台邮件服务器,只要为每台添加EmailServer记录的设置。当使用邮件模板发送邮件时,要使用的EmailServer在EmailTemplate记录上用emailServerId字段来指定。
发送电子邮件的第二步是创建一个EmailTemplate。这是一个来自HiveMind PM的发送任务更新通知的email:
<moqui.basic.email.EmailTemplate emailTemplateId="HM_TASK_UPDATE"
description="HiveMind Task Update Notification"
emailServerId="SYSTEM" webappName="webroot"
bodyScreenLocation="component://HiveMind/screen/TaskUpdateNotification.xml"
fromAddress="test@test.com" ccAddresses="" bccAddresses=""
subject="Task Updated: ${document._id} - ${document.WorkEffort.name}"/>
一般想法是定义一个页面,在邮件被发送时它将被渲染成邮件体(bodyScreenLocation)。邮件体页面和普通的UI页面有一小点区别,因为在渲染时WebFacade不可用,因为它不是一个web请求的一部分。URL前缀(域名、端口等)是基于Moqui配置XML文件中的webapp设置生成的,这就是为什么需要指定一个webappName与moqui-conf.webapp-list.webapp.name属性匹配。
subject也是一个简单的模板,它是一个Groovy字符串,当邮件被发送时使用与渲染邮件体一样的上下文来填充扩展。fromAddress字段是必需的,你可以可选地指定ccAddresses和bccAddress。
EmailTemplate的附件可用EmailTemplateAttachment实体来添加。email上使用的文件名必须用fileName字段来指定。附件自己来自用attachmentLocation字段指定的页面的渲染结果。它也被用来决定MIME/content type。screenRenderMode字段被传到ScreenRender来指定从页面获得的输出的类型。如果为空,attachmentLocation的内容将被直接发送,而没有页面渲染的过程,它的MIME类型将基于它的文件扩展名。通过设置screenRenderMode为xsl-fo,这可以被用来生成XSL:FO,它被转成一个PDF并贴上邮件。
一旦EmailServer和EmailTemplate被定义,你可以用org.moqui.impl.EmailServices.send#EmailTemplate服务来发送邮件。当调用此服务时,传入emailTemplateId参数以标识使用的EmailTemplate。如上面提到的,EmailServer将基于EmailTemplate.emailServerId字段决定。
发送信息的目的email地址被传入toAddress参数,它是一个纯String,并能有多个逗号分隔的地址。用来渲染email页面的参数是与服务的上下文分开的,在bodyParameter入参中传入。默认send#EmailTemplate服务把关于发出的信息的详情保存在一条EmailMessage实体的记录中。要关闭这个,在createEmailMessage参数中传入false。出参是messageId,它是放入Message-ID邮件头字段中的值,如果一条EmailMessage记录被创建,是这条记录的emailMesageId。
EmailMessage实体既用于发出的也用于收到的邮件消息。对于发出的信息,使用send#EmailTemplate服务,状态(statusId)开始是Sent(实际上是设置为Ready,发送邮件,然后设置为Sent),如果有基于图片请求(一般有emailMessageId作为参数或者路径元素)的消息跟踪,可能被改成Viewed。如果消息被返回不能投递,则状态可能会被改为Bounced。
一个EmailMessage也可能被手工发送而不是从一个模板,那种情况状态将是以Draft开始。一旦用户编辑完消息,他们会修改状态为Ready,然后当实际发送时,状态会改变成Sent。收到的信息开始是Received状态,在他们被初次打开时能被改成Viewed。
对于email会话,EmailMessage实体有rootEmailMessageId给原始的信息,会话中的所有信息在其下组成一组。有parentEmailMessageId给当前被回复的信息。
接收邮件的路径非常不一样。org.moqui.impl.EmailServices.poll#EmailServer服务基于EmailServer实体上的设置拉取IMAP或POP3邮箱。它有单个入参emailServerId。一般这将被作为计划服务运行。
对于在邮箱中发现的每条未被标记位已读的消息,此服务为其调用Email ECA(EMECA)规则。这些类似于实体和服务ECA规则,但是没有特定的触发器,只是收到一封邮件时。条件可以被用来只为特定的收件人地址或主题中的标签或任意其他期望的标准运行动作。
条件和动作的上下文将包括一个headersMap,其中有所有的email头(String或如果一个头字段有多条时的List<String>),一个fieldsMap有:toList,ccList,bccList,from,subject,sentDate,receivedDate,bodyPartList。*List字段是String的List,*Date字段是java.util.Date对象。对于带着这样设置的上下文的一个直接调用的服务,你可以实现org.moqui.EmailServices.process#EmailEca接口。
他们调用的动作和服务可以对收到的邮件做任何事情。要保存收到的信息,你可以使用org.moqui.impl.EmailServices.save#EcaEmailMessage服务。