询问Moqui是否内置主题通知邮件推送机制,需自定义NotificationMessageListener吗?
Great question! Let's walk through how you can handle sending email notifications to subscribed users in Moqui, covering both built-in capabilities and when you might need a custom listener.
Built-in Mechanism: Use Moqui's Native Notification Services
Moqui actually has out-of-the-box support for sending notifications to subscribed users based on specific topics. Here's how it works:
- Subscription Management: The
NotificationSubscriptionentity lets you track which users are subscribed to which topics. You can filter subscriptions by thetopicfield to target exactly the users who care about a specific event. - Notification Message Service: The
send#NotificationMessageservice is designed to handle bulk notifications. It can automatically pull subscribed users for a given topic, apply email templates, and send messages using Moqui's configured email sender. - Email Configuration: First, make sure your email settings are configured in
moqui-conf.xml(SMTP server, default from address, etc.) so Moqui can send emails.
Example: Using the Built-in Service
Here's a Groovy snippet to trigger a notification for a specific topic:
// Send email notifications to users subscribed to "ORDER_STATUS_UPDATED" topic ec.service.sync().name("send#NotificationMessage").parameters([ topic: "ORDER_STATUS_UPDATED", notificationTypeEnumId: "NTT_EMAIL", // Specify email as the notification type fromAddress: "alerts@yourstore.com", subject: "Your Order Status Changed", body: "Hi ${partyId},\n\nYour order ${orderId} has been updated to ${status}.\n\nThanks,\nThe Team" ])
This service will automatically fetch all users subscribed to the ORDER_STATUS_UPDATED topic and send them the email with the provided subject and body (you can also use Freemarker templates for more dynamic content).
When to Implement a Custom NotificationMessageListener
You'll need a custom listener if you require more control or specialized logic that the built-in service doesn't cover, such as:
- Complex subscription rules (e.g., filtering users based on additional attributes beyond just the topic)
- Custom email templating logic that goes beyond Moqui's default template support
- Sending notifications to multiple channels (email + SMS + in-app) in one workflow
- Adding custom logging or error handling for failed notifications
Example: Custom Listener Implementation
First, create a class that implements the NotificationMessageListener interface:
import org.moqui.notification.NotificationMessage; import org.moqui.notification.NotificationMessageListener; import org.moqui.context.ExecutionContext; import java.util.List; import java.util.Map; public class CustomEmailNotificationListener implements NotificationMessageListener { @Override public void onNotificationMessage(NotificationMessage notificationMessage, ExecutionContext ec) { // Fetch users subscribed to the target topic List<Map<String, Object>> subscriptions = ec.entity.find("moqui.notification.NotificationSubscription") .condition("topic", notificationMessage.getTopic()) // Add custom filter if needed (e.g., only active users) .condition("active", "Y") .list(); // Send email to each subscriber for (Map<String, Object> subscription : subscriptions) { String userEmail = (String) subscription.get("emailAddress"); String userName = (String) subscription.get("partyName"); // Use Moqui's send#Email service for actual delivery ec.service.sync().name("send#Email").parameters(Map.of( "toAddress", userEmail, "fromAddress", "custom-alerts@yourstore.com", "subject", notificationMessage.getSubject(), "body", String.format("Hi %s,\n\n%s", userName, notificationMessage.getBody()) )); } } }
Then register your listener in moqui-conf.xml:
<notification-listener class="com.yourcompany.notification.CustomEmailNotificationListener"/>
Final Takeaway
- Use built-in services if you need straightforward topic-based email notifications to subscribed users—it's quick, requires minimal code, and leverages Moqui's existing infrastructure.
- Build a custom listener when you need tailored logic that the native service can't handle.
内容的提问来源于stack exchange,提问作者Diego

