Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MultiTemplateContent fails with EmailVariant.TEXT, EmailVariant.HTML and Freemarker #52

Closed
MaggieLeber opened this issue Jul 17, 2017 · 8 comments

Comments

@MaggieLeber
Copy link

MaggieLeber commented Jul 17, 2017

We're trying to use MultiTemplateContent(...EmailVariant.TEXT, EmailVariant.HTML) with two Freemarker templates: testAlertEmail.html.ftl and testAlertEmail.txt.ftl.

Using the HTML variant alone works fine, but when we enable TEXT, we see the call to impl.getDetector().canParse(templateName, ctx) in AutoDetectTemplateParser.java:46 with a templateName of testAlertEmail.txt instead of the expected testAlertEmail.txt.ftl.

This results in a return of false for canParse so we end up with Failed to automatically detect parser due to detection error.

@aurelien-baudet
Copy link
Member

Hello,

I ran the sample HtmlAndTextTemplateSample (v1.1.1) and it works as expected.

Which version are you using ?
Could you please provide a minimal example of non working code so I can reproduce it ?

@MaggieLeber
Copy link
Author

I had been running 1.1.1 and stepped back to 1.1.0 to see it that helped.

Will work on a cut-down.
Also having trouble with Sms:
image

@MaggieLeber
Copy link
Author

It's really peculiar. In a cut-down test it works, embedded in our app it doesn't.

        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.sparkpostmail.com");
        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.starttls.enable", "true");
        props.setProperty("mail.smtp.socketFactory.port",  "587");
        props.setProperty("mail.smtp.socketFactory.class",   "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.auth", "true");
        props.put("ogham.email.authenticator.username", "xxxx");
        props.put("ogham.email.authenticator.password", "xxxx");
        props.put("ogham.email.from", "mleber@rajant.com");
        MessagingService service = new MessagingBuilder().useEmailDefaults(props).build();
        SimpleContext ctx = new SimpleContext("dateTime",new Date().toString())
                                .addValue("alertName", "OghamTest.java")
                                .addValue("metricName", "widget rate")
                                .addValue("metricValue", "42");
        try {
            service.send(new Email().from("mleber@rajant.com")
                    .to("maggie@matrisync.com")
                    .subject("Ogham test from Java:" + new Date().toString())
                    .content(new MultiTemplateContent("classpath:/templates/" + "testEmailAlert",ctx)
            ));

        } catch(Throwable t) {
            System.out.println(t.getMessage());
            System.out.println(t.getCause().getMessage());
        }
    }

That works.

This doesn't:

    public MessageResult sendMessage(Map<String, Object> message) {
        SimpleContext ctx = new SimpleContext(message);

        if (!message.containsKey("_template")) return new MessageResult(false, "All messages require _template");

        try {
            if (message.containsKey("_url") && message.containsKey("_method")) {
                // RESTful message
                String method = message.get("_method").toString();
                StringWriter writer = new StringWriter();
                cfg.getTemplate(message.get("_template").toString()).process((ctx.getVariables()), writer);
                switch (method) {
                    case "get":
                        throw new Error("We don't support GET yet."); // GET support would fill query parms from the context, I suppose
                    case "put":
                        HttpResponse result = Unirest.put(message.get("_url").toString()).body(writer.getBuffer().toString()).asString();
                        return new MessageResult(true, result.getStatus()+" "+result.getStatusText());
                    case "post":
                        HttpResponse postResult = Unirest.post(message.get("_url").toString()).body(writer.getBuffer().toString()).asString();
                        return new MessageResult(true, postResult.getStatus()+" "+ postResult.getStatusText());
                    default:
                        throw new Error("Unknown REST _method: " + method);
                }

            } else if (message.containsKey("_emailto")) {
                // email message
                Email email = new Email().to(message.get("_emailto").toString());

                if (message.containsKey("_subject"))
                    email = email.subject(message.get("_subject").toString());
                else
                    email = email.subject("Message from Rajant BC|Commander");

                if (message.containsKey("_from"))
                    email = email.from(message.get("_subject").toString());

                ogham.send(email.content(new MultiTemplateContent("classpath:/templates/messaging/" + message.get("_template"), ctx, EmailVariant.HTML)));
                // EmailVariant.TEXT currently failing; see https://github.com/groupe-sii/ogham/issues/52

            } else if (message.containsKey("_sms")) {
                // SMS message
                ogham.send(new Sms().content(new TemplateContent("classpath:/templates/messaging/" + message.get("_template"), ctx)).to(message.get("_sms").toString()));
            } else
                return new MessageResult(false, "Message requires {_url and _method} or {_emailto and _subject} or {_sms}");

        } catch (Throwable e) {
            return new MessageResult(false, e.getMessage() + ": "+ e.getCause().getMessage());
        }
        return new MessageResult(true, "OK");
    }
}

@MaggieLeber
Copy link
Author

MaggieLeber commented Jul 17, 2017

I'm trying to imagine what would cause classpath:/templates/messaging/myThing to cause a getDetector().canParse("myThing.txt.ftl", ctx) in one environment and getDetector().canParse("myThing.txt", ctx) in the other.

I hope it's not a red herring from the Thymeleaf support. Firing up the debugger again...

@MaggieLeber
Copy link
Author

The MultiTemplateContent now appears to be working after having Maven run a clean. Working on the SMS part now...it's still failing, but not even finding a template.

@MaggieLeber
Copy link
Author

MaggieLeber commented Jul 17, 2017

If I use the debugger to hack the templateName in AutoDetectTemplateParser from testAlertSms to testAlertSms.txt.ftl, it works.

Well, by "works" I mean it doesn't fail; we see the SMPP session being logged in INFO. Not actually receiving any SMS yet...

@aurelien-baudet
Copy link
Member

I tried your code with simple Freemarker templates and everything works fine.

For SMS, only a single template can be used so variants are useless and you have to provide the full extension (.txt.ftl).

Unfortunately, I can't reproduce your bugs...

For the record, you don't need to use SimpleContext class. You can directly write this (look at the last parameter):

 ogham.send(email.content(new MultiTemplateContent("classpath:/templates/messaging/" + message.get("_template"), message)));

Or even better, instead of using a map, you could use directly a domain object.

@MaggieLeber
Copy link
Author

Ah! I missed that the SMS version uses the full template name, with extension. I think that's the remaining issue for us.

The MultiTemplateContent is now working for the email case...I think the mvn:clean fixed it. Unfortunately a domain object for the context isn't an option, because we'll be using user-supplied templates and contexts. But I'll experiment with dropping SimpleContext.

Thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants