Send email on event

Hello,
I created an Eventlistenerprovider for Keycloak an it works fine, I get an sysout on the server, on an event in Keycloak -> Loggin, register…
Now I want that an email will send, on an new register event.
How can I send emails from keycloak on an event?

Pfeiffy

Create a class that implements the UserModel interface.
Create a new instance and set the email for the recipient.
Then use it as follows

DefaultEmailSenderProvider senderProvider = new DefaultEmailSenderProvider(session);
senderProvider.send(
        session.getContext().getRealm().getSmtpConfig(),
        userModel,
        "test",
        "body test",
        "html test"
);

You can also take a look at the FreeMarkerEmailTemplateProviderFactory on how to get a provider for the existing implementation and use freemarker templates if you want to include them in your theme

2 Likes

Hello,
I wrote an EventListenerProvider and I want to send a mail on an register-event in the method

@Override
        public void onEvent(Event event) {

How can I get the session, like on your code

Pfeiffy

Take a look at how you can inject the KeycloakSession https://github.com/zonaut/keycloak-extensions/tree/master/spi-event-listener

1 Like

Hello,
I wrote this code from you to use your GIT-Example:
public class SampleEventListenerProvider implements EventListenerProvider {

private final KeycloakSession session;
private final RealmProvider model;

public SampleEventListenerProvider(KeycloakSession session) {
	this.session = session;
	this.model = session.realms();
}

@Override
public void onEvent(Event event) {

	RealmModel realm = this.model.getRealm(event.getRealmId());
	UserModel user = this.session.users().getUserById(event.getUserId(), realm);
	if (user != null && user.getEmail() != null) {
		System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>" + user.getEmail());

		org.keycloak.email.DefaultEmailSenderProvider senderProvider = new org.keycloak.email.DefaultEmailSenderProvider(session);
		try {
			senderProvider.send(session.getContext().getRealm().getSmtpConfig(), user, "test", "body test",
					"html test");
		} catch (EmailException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();	
		}
	}

	System.out.println(
			"***************************************************************************************************************");
	System.out.println("********************Event Occurred:" + toString(event));

}

But I get an Error:

17:32:12,121 ERROR [org.keycloak.events.EventBuilder] (default task-1) Failed to send type to com.pf.keycloak.eventhandler.SampleEventListenerProvider@16404ca: java.lang.NoClassDefFoundError: org/keycloak/email/DefaultEmailSenderProvider
        at com.pf.keycloak.eventhandler.SampleEventListenerProvider.onEvent(SampleEventListenerProvider.java:39)

Keycloak dont find the class? Do you know what is my Error? I use Keycloak 9.0.3 and Maven-Build

Pfeiffy

You will need to declare the keycloak-services module as global in your standalone-ha.xml file so your SPI can access these things.
An example on how you can configure this can be found under the Keycloak config section of the README file in https://github.com/zonaut/keycloak-extensions/tree/master/spi-registration-profile

I’m sorry, but I think I’m a little too stupid for that, I have entered the following text in my > standalone-ha.xml on the server:

       <subsystem xmlns="urn:jboss:domain:ee:4.0">    
			<global-modules>
				<module name="org.keycloak.email"/>  ???
		</global-modules>
            <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
            <concurrent>
                <context-services>

I think this is wrong, the error is still coming, I don’t have the experience with JBoss

Greetings Pfeiffy

Hi,

I mentioned the keycloak-services module in my last reply, so it’s exactly as in the readme file like

<module name="org.keycloak.keycloak-services"/>

You can know which module to declare based on the Keycloak source code itself.
In this case the DefaultEmailSenderProvider class is located under the keycloak-services artifact so the module becomes groupId (in this case org.keycloak) + artifactId (in this case keycloak-services), so the module’s full name is org.keycloak.keycloak-services.
External dependencies can also be declared by their own groupId and artifact name.

You can take a look at the https://github.com/zonaut/keycloak-extensions/blob/master/_resources/demo-config/standalone-ha.xml file I use in my examples, there are some others declared that I use in other examples.

I have declared the class global in the standalone\configuration\settings-ha.xml, see code, but I still get the same error.

   <subsystem xmlns="urn:jboss:domain:ee:4.0">    
        <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
		<global-modules>
            <module name="org.keycloak.keycloak-services"/>
        </global-modules>
        <concurrent>
            <context-services>
                <context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
            </context-services>

Greetings Pfeiffy

1 Like

settings-ha.xml ? You mean standalone-ha.xml ?
If you’re not using the Docker Keycloak image it could be that the file being used is the standalone.xml file but I’m not sure of that.
Either way I’ve tried it out on my keycloak-extensions repo and it works for me so maybe create a git repo so I can take a look at it

Hi,
yes, that was the problem, I have to define the class in standalone.xml, not in standalone-ha.xml !!
Thank you very much for the help, the state of Baden-Württemberg thanks you very much!
We are using Keycloak for the first time and are thrilled with what it can do.

Thanks again and greetings Pfeiffy