Overview
TheDiscussionForumService provides the API for both the Discussion Forums tool and the Private Messages tool in Sakai LMS. It defines events and constants used by both messaging systems.
Package: org.sakaiproject.api.app.messageforums
Source: /msgcntr/messageforums-api/src/java/org/sakaiproject/api/app/messageforums/DiscussionForumService.java
Constants
Service Identifiers
public static final String SERVICE_NAME = "org.sakaiproject.api.app.messageforums.DiscussionForumService";
public static final String REFERENCE_ROOT = "/messageforum";
Tool IDs
public static final String MESSAGE_CENTER_ID = "sakai.messagecenter";
public static final String FORUMS_TOOL_ID = "sakai.forums";
public static final String MESSAGES_TOOL_ID = "sakai.messages";
Private Messages Events
Events fired by the Private Messages tool:Message Events
public static final String EVENT_MESSAGES_ADD = "messages.new";
public static final String EVENT_MESSAGES_READ = "messages.read";
public static final String EVENT_MESSAGES_UNREAD = "messages.unread";
public static final String EVENT_MESSAGES_REMOVE = "messages.delete";
public static final String EVENT_MESSAGES_RESPONSE = "messages.reply";
public static final String EVENT_MESSAGES_FORWARD = "messages.forward";
public static final String EVENT_MESSAGES_READ_RECEIPT = "messages.read.receipt";
public static final String EVENT_MESSAGES_MOVE_TO_DELETED_FOLDER = "messages.movedtodeletefolder";
// When a new private message is created
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_MESSAGES_ADD,
messageReference,
true
)
);
// When a message is read
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_MESSAGES_READ,
messageReference,
false
)
);
Folder Events
public static final String EVENT_MESSAGES_FOLDER_ADD = "messages.newfolder";
public static final String EVENT_MESSAGES_FOLDER_REVISE = "messages.revisefolder";
public static final String EVENT_MESSAGES_FOLDER_REMOVE = "messages.deletefolder";
// Create a new folder
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_MESSAGES_FOLDER_ADD,
folderReference,
true
)
);
Discussion Forums Events
Events fired by the Discussion Forums tool:Forum Events
public static final String EVENT_FORUMS_ADD = "forums.new";
public static final String EVENT_FORUMS_FORUM_ADD = "forums.newforum";
public static final String EVENT_FORUMS_FORUM_REMOVE = "forums.deleteforum";
public static final String EVENT_FORUMS_FORUM_REVISE = "forums.reviseforum";
// When a new forum is created
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_FORUMS_FORUM_ADD,
forumReference,
true
)
);
Topic Events
public static final String EVENT_FORUMS_TOPIC_ADD = "forums.newtopic";
public static final String EVENT_FORUMS_TOPIC_REMOVE = "forums.deletetopic";
public static final String EVENT_FORUMS_TOPIC_REVISE = "forums.revisetopic";
public static final String EVENT_FORUMS_TOPIC_READ = "forums.topic.read";
// When a new topic is created
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_FORUMS_TOPIC_ADD,
topicReference,
true
)
);
// When a topic is viewed
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_FORUMS_TOPIC_READ,
topicReference,
false
)
);
Post/Response Events
public static final String EVENT_FORUMS_READ = "forums.read";
public static final String EVENT_FORUMS_RESPONSE = "forums.response";
public static final String EVENT_FORUMS_REMOVE = "forums.delete";
public static final String EVENT_FORUMS_REVISE = "forums.revise";
// When a user posts a response
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_FORUMS_RESPONSE,
postReference,
true
)
);
// When a post is read
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_FORUMS_READ,
postReference,
false
)
);
Grading Events
public static final String EVENT_FORUMS_GRADE = "forums.grade";
// When a forum post is graded
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_FORUMS_GRADE,
gradeReference,
true
)
);
Thread Management Events
public static final String EVENT_FORUMS_MOVE_THREAD = "forums.movethread";
// When a thread is moved to another topic
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_FORUMS_MOVE_THREAD,
threadReference,
true
)
);
Event Tracking Example
Here’s a complete example of how to use these events in a custom tool or service:import org.sakaiproject.api.app.messageforums.DiscussionForumService;
import org.sakaiproject.event.api.EventTrackingService;
import org.sakaiproject.event.api.Event;
public class ForumEventExample {
private EventTrackingService eventTrackingService;
/**
* Post a new forum message and track the event
*/
public void postNewMessage(String siteId, String topicId, String content) {
// Create the message (implementation details omitted)
String messageId = createMessage(topicId, content);
// Build reference
String reference = DiscussionForumService.REFERENCE_ROOT +
"/site/" + siteId + "/topic/" + topicId +
"/message/" + messageId;
// Post event
Event event = eventTrackingService.newEvent(
DiscussionForumService.EVENT_FORUMS_RESPONSE,
reference,
true // modify = true for creating content
);
eventTrackingService.post(event);
}
/**
* Mark a message as read and track the event
*/
public void markMessageAsRead(String siteId, String messageId) {
// Mark as read (implementation details omitted)
updateMessageReadStatus(messageId, true);
// Build reference
String reference = DiscussionForumService.REFERENCE_ROOT +
"/site/" + siteId + "/message/" + messageId;
// Post event
Event event = eventTrackingService.newEvent(
DiscussionForumService.EVENT_FORUMS_READ,
reference,
false // modify = false for read-only operations
);
eventTrackingService.post(event);
}
/**
* Create a private message and track the event
*/
public void sendPrivateMessage(String recipientId, String subject, String body) {
// Create the message (implementation details omitted)
String messageId = createPrivateMessage(recipientId, subject, body);
// Build reference
String reference = DiscussionForumService.REFERENCE_ROOT +
"/message/" + messageId;
// Post event
Event event = eventTrackingService.newEvent(
DiscussionForumService.EVENT_MESSAGES_ADD,
reference,
true
);
eventTrackingService.post(event);
}
// Implementation methods (simplified)
private String createMessage(String topicId, String content) {
// Create message logic
return "msg123";
}
private void updateMessageReadStatus(String messageId, boolean read) {
// Update read status logic
}
private String createPrivateMessage(String recipientId, String subject, String body) {
// Create private message logic
return "pm456";
}
}
Event Listening Example
To listen for forum events:import org.sakaiproject.event.api.Event;
import org.sakaiproject.event.api.EventTrackingService;
import org.sakaiproject.event.api.NotificationService;
import org.sakaiproject.api.app.messageforums.DiscussionForumService;
public class ForumEventListener implements Observer {
private EventTrackingService eventTrackingService;
public void init() {
// Register to observe forum events
eventTrackingService.addLocalObserver(this);
}
public void destroy() {
eventTrackingService.deleteObserver(this);
}
@Override
public void update(Observable o, Object arg) {
if (arg instanceof Event) {
Event event = (Event) arg;
String eventType = event.getEvent();
// Handle forum response events
if (DiscussionForumService.EVENT_FORUMS_RESPONSE.equals(eventType)) {
handleNewForumPost(event);
}
// Handle private message events
else if (DiscussionForumService.EVENT_MESSAGES_ADD.equals(eventType)) {
handleNewPrivateMessage(event);
}
// Handle grade events
else if (DiscussionForumService.EVENT_FORUMS_GRADE.equals(eventType)) {
handleForumGraded(event);
}
}
}
private void handleNewForumPost(Event event) {
String reference = event.getResource();
String userId = event.getUserId();
// Send notifications, update counts, etc.
System.out.println("New forum post by " + userId + ": " + reference);
}
private void handleNewPrivateMessage(Event event) {
String reference = event.getResource();
String senderId = event.getUserId();
// Send email notification, update unread count, etc.
System.out.println("New private message from " + senderId);
}
private void handleForumGraded(Event event) {
String reference = event.getResource();
String graderId = event.getUserId();
// Update gradebook, send notification, etc.
System.out.println("Forum post graded by " + graderId);
}
}
Reference Format
The reference format for forum entities follows this pattern:/messageforum/site/{siteId}/forum/{forumId}/topic/{topicId}/message/{messageId}
// Forum reference
String forumRef = "/messageforum/site/abc123/forum/forum456";
// Topic reference
String topicRef = "/messageforum/site/abc123/forum/forum456/topic/topic789";
// Message reference
String messageRef = "/messageforum/site/abc123/forum/forum456/topic/topic789/message/msg101";
// Private message reference
String privateMessageRef = "/messageforum/message/pm202";
Common Use Cases
Tracking Discussion Engagement
public class DiscussionEngagementTracker {
private EventTrackingService eventTrackingService;
public void trackTopicView(String siteId, String topicId) {
String reference = String.format(
"%s/site/%s/topic/%s",
DiscussionForumService.REFERENCE_ROOT,
siteId,
topicId
);
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_FORUMS_TOPIC_READ,
reference,
false
)
);
}
public void trackForumResponse(String siteId, String forumId,
String topicId, String messageId) {
String reference = String.format(
"%s/site/%s/forum/%s/topic/%s/message/%s",
DiscussionForumService.REFERENCE_ROOT,
siteId, forumId, topicId, messageId
);
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_FORUMS_RESPONSE,
reference,
true
)
);
}
}
Tracking Private Message Activity
public class MessageActivityTracker {
private EventTrackingService eventTrackingService;
public void trackMessageSent(String messageId) {
String reference = DiscussionForumService.REFERENCE_ROOT +
"/message/" + messageId;
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_MESSAGES_ADD,
reference,
true
)
);
}
public void trackMessageRead(String messageId) {
String reference = DiscussionForumService.REFERENCE_ROOT +
"/message/" + messageId;
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_MESSAGES_READ,
reference,
false
)
);
}
public void trackReadReceipt(String messageId) {
String reference = DiscussionForumService.REFERENCE_ROOT +
"/message/" + messageId;
eventTrackingService.post(
eventTrackingService.newEvent(
DiscussionForumService.EVENT_MESSAGES_READ_RECEIPT,
reference,
true
)
);
}
}
Integration Points
TheDiscussionForumService events integrate with:
- Statistics/Analytics: Track user engagement and participation
- Notifications: Trigger email or in-app notifications
- Gradebook: Integration for graded forums
- Reports: Generate activity reports
- Search: Index forum content for search
- LRS/xAPI: Send learning activity statements
See Also
- Event Tracking API - Event tracking service
- Entity API - Entity and reference handling
- Notification API - User notifications