Mail Sender API - groovy

I want to send an email message from a scheduled job. The job scheduler requires groovy scripts. I found some velocity code snippets in https://extensions.xwiki.org/xwiki/bin/view/Extension/Mail/MailSenderAPI
and also a ‘Using from Java’-section. When I copy/paste the java code in a groovy macro, I get some error messages like
unable to resolve class Inject for annotation
After adding

  import org.xwiki.mail.*;
  import javax.inject.*;
  import javax.mail.*
  import javax.mail.internet.*;

I get the error message:
Annotation @javax.inject.Inject is not allowed on element LOCAL_VARIABLE
in the lines

  @Inject MailSenderConfiguration configuration;
  @Inject @Named("text/html") MimeBodyPartFactory htmlPartFactory;
  @Inject MailSender mailSender;
  @Inject @Named("database") MailListener databaseMailListener;

Hints to solve this problem?

@Inject don’t work in Groovy snippets. You need to use for example: def configuration = services.component.getInstance(MailSenderConfiguration.class) (or def htmlPartFactory = services.component.getInstance(MimeBodyPartFactory.class, 'test/html')).

It would be a nice improvement to implement BTW. See Loading...

Thanks for the hint.
Now I get stuck in step3, where I have to define the attachment:

// Step 3: Add the Message Body
Multipart multipart = new MimeMultipart("mixed");
// Add HTML in the body, with a text alternative and attachments
Map<String, Object> parameters = new HashMap<>();
parameters.put("alternative", "text");
parameters.put("attachments", attachments);
multipart.addBodyPart(htmlPartFactory.create("some html here", parameters));
message.setContent(multipart);

The error message:

No such property: attachments for class

How should I define “attachments”?

It’s a list of List<com.xpn.xwiki.api.Attachment>.

You can get attachments using the XWiki api. See for example: https://www.xwiki.org/xwiki/bin/view/Documentation/DevGuide/Scripting/APIGuide/#HListallattachmentsofapage

You could use something like this: xwiki.getDocument('reference here').getAttachment('attachment name') to get an attachment from a document.

Note: I’ve now updated https://extensions.xwiki.org/xwiki/bin/view/Extension/Mail/MailSenderAPI

Next problem:

  def htmlPartFactory = services.component.getInstance(MimeBodyPartFactory.class, 'text/html');
  println htmlPartFactory.getClass()

shows:

class org.codehaus.groovy.runtime.NullObject

=>

multipart.addBodyPart(htmlPartFactory.create("some html here", parameters));

fails with error message

Cause: [Cannot invoke method create() on null object].

That’s because MimeBodyPartFactory is a generic class.

{{groovy}}
import org.xwiki.mail.*
import org.xwiki.component.util.*

def roleType = new DefaultParameterizedType(null, MimeBodyPartFactory.class, String.class);
def htmlPartFactory = services.component.getInstance(roleType, 'text/html')
println htmlPartFactory
{{/groovy}}

Since you’re using scripting you might be better off using the scripting api we offer, which is simpler to use. See https://extensions.xwiki.org/xwiki/bin/view/Extension/Mail/MailSenderAPI#HAPI

It would be nice to have a simple groovy example on the MailSenderAPI page, e.g. something like this:

{{groovy}}
  from="me@mydomain.com"
  to="recepient@somedomain.com"
  message = services.mail.sender.createMessage(from, to, "test")
  attachment=xwiki.getDocument('Main.WebHome').getAttachment('example.png')
  def List attachments = [attachment]
  Map<String, Object> parameters = new HashMap<>();
  parameters.put("alternative", "text");
  parameters.put("attachments", attachments);
  discard = message.addPart("text/html", "<h1>html title</h1>", parameters)
  result = services.mail.sender.send(message)
  result.statusResult.waitTillProcessed(10000L)
{{/groovy}}

Why not.

We usually don’t put too many groovy examples because it’s not a good practice:

  • velocity should be favored in general since it doesn’t require Programming Rights (except if you call api requiring that)
  • if you’re writing java code, then they’re usually best deployed as extensions
  • we usually put java example and converting from a java example to a groovy one is mechanistic and generic.

Thx

Which leads me to the question of why you don’t use velocity in your case :slight_smile: What’s missing?

If I understood well, velocity is not an option for the job scheduler: https://www.xwiki.org/xwiki/bin/view/Blog/Drafts/Use+java+in+scheduler+jobs/ :
Jobs created by the scheduler application executes a Groovy script periodicaly

you’re quite right! Currently the scheduler application only supports writing Groovy (see Loading...).

I’ve now added it to https://extensions.xwiki.org/xwiki/bin/view/Extension/Mail/MailSenderAPI#HUsingfromGroovy

Thanks!

:+1: Great, thanks