Wiki source code of Mail Module
Last modified by Vincent Massol on 2024/02/26 17:52
Show last authors
author | version | line-number | content |
---|---|---|---|
1 | {{error}} | ||
2 | Implementation done at [[http://extensions.xwiki.org/xwiki/bin/view/Extension/Mail+Sender+API]]. | ||
3 | {{/error}} | ||
4 | |||
5 | The goal is introduce a Mail API in the XWiki Platform to provide mail-related APIs. | ||
6 | |||
7 | {{toc/}} | ||
8 | |||
9 | = History & Status = | ||
10 | |||
11 | * Ludovic sent an email to propose a modification of the mailsender plugin: http://markmail.org/message/pfoyi4qeqvlc75yo | ||
12 | * Discussions ensued and Thomas Delafosse started working on a new ##xwiki-platform-mail## module (component-based) to replace the old mailsender plugin | ||
13 | * Thomas Delafosse put a first version of his ideas in his GitHub repo at: https://github.com/tdelafosse/mailSender | ||
14 | * Then Thomas Delafosse moved his code to https://github.com/xwiki-contrib/xwiki-platform-mail/ | ||
15 | * Work was stopped by Thomas Delafosse | ||
16 | * Now waiting for someone to take over... :) | ||
17 | |||
18 | = Use Cases = | ||
19 | |||
20 | * UC1: Be able to send multipart emails with any type of mime type content (html, text, vcalendar, etc) | ||
21 | * UC2: Be able to get the mail content to send by rendering the content of an XWiki document (a.k.a a template) | ||
22 | * UC3: Ensure the API is easy to use from Velocity (script service) | ||
23 | * UC4: SMTP config should be able to be either specified explicitly or taken from XWiki configuration | ||
24 | * UC5: Ability to easily embed images in the email (i.e. generate cid) | ||
25 | * UC6: Ability to easily send an XWiki page by email (i.e. automatically embed images from that page in the email) | ||
26 | * UC7: Allow both reading (POP3, IMAP) and sending (SMTP) emails, supporting SSL | ||
27 | * UC8: Ability to send batch of emails | ||
28 | |||
29 | == API Proposal == | ||
30 | |||
31 | === Scripting API === | ||
32 | |||
33 | {{code language="none"}} | ||
34 | // Message creation, internally creates a JavaMail MimeMessage | ||
35 | $message = $services.mailSender.createMessage() | ||
36 | $message = $services.mailSender.createMessage(from, to, subject) | ||
37 | $message = $services.mailSender.createMessage(from, to, cc, bcc, subject) | ||
38 | |||
39 | // Set from, to, cc, bcc, subject | ||
40 | // Note that "from" is optional and if not specified, taken from Mail configuration | ||
41 | $message.setFrom("[email protected](mailto:[email protected])") | ||
42 | |||
43 | $message.addToRecipient("[email protected](mailto:[email protected])”) | ||
44 | $message.addToRecipients(["[email protected](mailto:[email protected])”, ...]) | ||
45 | |||
46 | $message.addCcRecipient("[email protected](mailto:[email protected])”) | ||
47 | $message.addCcRecipients(["[email protected](mailto:[email protected])”, ...]) | ||
48 | |||
49 | $message.addBccRecipient("[email protected](mailto:[email protected])”) | ||
50 | $message.addBccRecipients(["[email protected](mailto:[email protected])”, ...]) | ||
51 | |||
52 | // Optional: | ||
53 | // Need a Converter implementation to convert from String to javax.mail.Message.RecipientType | ||
54 | $message.addRecipient("[email protected](mailto:[email protected])”, "to|bcc|cc") | ||
55 | $message.addRecipients("[email protected](mailto:[email protected])”, "to|bcc|cc") | ||
56 | |||
57 | $message.setSubject('Lorem Ipsum') | ||
58 | |||
59 | // Add the Content | ||
60 | // Note: the first parameter is a component hint. If no implementation corresponds to it, a default implementation is used which converts it to a Mime Type | ||
61 | // Note: We create by default a MultiPart("mixed") and the addPart() calls generate MultiPartBody added to this multipart. | ||
62 | |||
63 | // Add simple text to message | ||
64 | $message.addPart("text", "text message") | ||
65 | |||
66 | // Add simple text to message with a header | ||
67 | $message.addPart("text", "text message", {"headers" : { "Content-Transfer-Encoding" : "quoted-printable"}}) | ||
68 | |||
69 | // Add simple HTML to message | ||
70 | $message.addPart("html", "html message") | ||
71 | |||
72 | // Add HTML + alternate text to message | ||
73 | $message.addPart("html", "html message", {"alternate" : "text message"}) | ||
74 | |||
75 | // Add HTML + alternate text + embedded images + attachments to message | ||
76 | // Note: $attachments is of type List<Attachment> | ||
77 | $message.addPart("html", "html message", {"alternate" : "text message", "attachments" : $attachments}) | ||
78 | |||
79 | // Add an XWiki attachment to message | ||
80 | $message.addPart("attachment", Attachment) | ||
81 | |||
82 | // And XWiki attachment to message from an Attachment reference | ||
83 | $message.addPart("attachment", AttachmentReference) | ||
84 | |||
85 | // Add all attachments found in the passed document reference to the message | ||
86 | $message.addPart("attachment", DocumentReference) | ||
87 | |||
88 | // Add all attachments to message | ||
89 | $message.addPart("attachments", List<Attachment>) | ||
90 | |||
91 | // Add a wiki page to message with embedded images and attachments | ||
92 | $message.addPart("document", DocumentReference) | ||
93 | |||
94 | // Generate the message from a template containing a XWiki.Mail object | ||
95 | $message.addPart("template", DocumentReference, {"velocityVariables" : { "var1" : "value1" }}) | ||
96 | |||
97 | // Send Message now, asynchronously | ||
98 | $message.send() | ||
99 | |||
100 | // Send Message at some date | ||
101 | $message.send(Date) | ||
102 | |||
103 | // Wait for the message to be sent | ||
104 | $message.waitTillSent() | ||
105 | |||
106 | // Internally messages are added to a queue when send() is called and sent asynchronously by batches of N messages at a time. The number of messages to send in a batch is controlled by the Mail configuration in the Admin. We can imagine an API to get the mail configuration and override it temporarily: | ||
107 | |||
108 | $mailConfiguration = $services.mailSender.getConfiguration() | ||
109 | $mailConfiguration.setFrom(...) | ||
110 | $mailConfiguration.setSmtpAddress(...) | ||
111 | $mailConfiguration.setBatchSize(...) | ||
112 | |||
113 | // And then: | ||
114 | $message.send(MailConfiguration) | ||
115 | $message.send(Date, MailConfiguration) | ||
116 | {{/code}} | ||
117 | |||
118 | === Java API === | ||
119 | |||
120 | * ##MailConfiguration## component role with implementation taking the configuration values from the Administration | ||
121 | * ##MimeBodyPart MimeBodyPartFactory.create(T source)## | ||
122 | * ##MimeMessageFactory## to make it simple to create ##MimeMessage## | ||
123 | * ##MailSender## component role to make the glue between all + ability to send mails asynchronously and by batch | ||
124 | |||
125 | Spirit: It should be possible to send mail using directly the JavaMail API and using the helper components defined above or use the ##MailSender## component which acts as a helper but is not as generic. | ||
126 | |||
127 | {{code language="java"}} | ||
128 | @Inject MailSenderConfiguration configuration; | ||
129 | @Inject @Named("html") MimeBodyPartFactory htmlPartFactory; | ||
130 | @Inject MimeMessageFactory messageFactory; | ||
131 | @Inject MailSender mailSender; | ||
132 | |||
133 | // Step 1: Create a JavaMail Session | ||
134 | //... with authentication: | ||
135 | Session session = Session.getInstance(configuration.getAllProperties(), new XWikiAuthenticator(configuration)); | ||
136 | //... without authentication: | ||
137 | Session session = Session.getInstance(configuration.getAllProperties()); | ||
138 | |||
139 | // Step 2: Create the Message to send | ||
140 | MimeMessage message = new MimeMessage(session); | ||
141 | message.setSubject("subject"); | ||
142 | message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress("[email protected]")); | ||
143 | |||
144 | // Step 3: Add the Message Body | ||
145 | Multipart multipart = new MimeMultipart("mixed"); | ||
146 | // Add HTML in the body, with a text alternative and attachments | ||
147 | Map<String, Object> parameters = new HashMap<>(); | ||
148 | parameters.put("alternative", "text"); | ||
149 | parameters.put("attachments", attachments); | ||
150 | multipart.addBodyPart(htmlPartFactory.create("some html here", parameters)); | ||
151 | message.setContent(multipart); | ||
152 | |||
153 | // Step 4: Send the mail | ||
154 | sender.send(message, session); | ||
155 | {{/code}} | ||
156 | |||
157 | === Configuration Parameters === | ||
158 | |||
159 | * Introduce new parameters in ##xwiki.properties##:((( | ||
160 | {{code language="none"}} | ||
161 | mail.sender.host = ... | ||
162 | mail.sender.port = ... | ||
163 | mail.sender.username = ... | ||
164 | mail.sender.password = ... | ||
165 | mail.sender.from = ... | ||
166 | mail.sender.properties = ... = ... | ||
167 | mail.sender.properties = ... = ... | ||
168 | {{/code}} | ||
169 | ))) | ||
170 | * Algorithm: first try to find existing parameter names (##smtp_server##, ##smtp_port##, ##smtp_from##, ##smtp_server_username##, ##smtp_server_password##, ##javamail_extra_props##) in a ##user##, ##space## and ##wiki## level ##ConfigurationSource## and if not found then look for the ##mail.sender.*## property names from a ##xwikiproperties## ##ConfigurationSource##. | ||
171 | |||
172 | == Implementation Ideas == | ||
173 | |||
174 | * Current Mailsender plugin: https://github.com/xwiki/xwiki-platform/tree/master/xwiki-platform-core/xwiki-platform-mailsender | ||
175 | * Current Mail plugin: https://github.com/xwiki/xwiki-platform/tree/master/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/plugin/mail | ||
176 | * Existing MailArchive Application (read mails): http://extensions.xwiki.org/xwiki/bin/view/Extension/MailArchive+Application | ||
177 | * Existing APIs to consider: | ||
178 | ** [[Apache Commons Mail>>http://commons.apache.org/proper/commons-email/]] | ||
179 | ** Latest [[JavaMail API>>https://javamail.java.net/]] | ||
180 | * Could have several modules: | ||
181 | ** ##xwiki-commons-mail-common##: Store classes common to the other modules | ||
182 | ** ##xwiki-commons-mail-send##: Ability to send emails | ||
183 | ** ##xwiki-commons-mail-read##: Ability to read emails | ||
184 | ** ##xwiki-platform-mail##: Wiki specific features, like getting the template from a wiki page and rendering it |