📄 workgroup.java
字号:
// If just the user has left the room, just persist the transcript
boolean isAgent = false;
try {
isAgent = agentManager.getAgentSession(presenceFullJID) != null;
}
catch (AgentNotFoundException e) {
// Ignore.
}
if (!((Presence)packet).isAvailable() && !isAgent) {
// Build the XML for the transcript
Map<Packet, java.util.Date> map = transcripts.get(roomID);
StringBuilder buf = new StringBuilder();
buf.append("<transcript>");
for (Packet p : map.keySet()) {
java.util.Date date = map.get(p);
// Add the delay information
if (p instanceof Message) {
Message storedMessage = (Message)p;
Element delay = storedMessage.addChildElement("x", "jabber:x:delay");
delay.addAttribute("stamp", UTC_FORMAT.format(date));
if (ModelUtil.hasLength(storedMessage.getBody())) {
buf.append(p.toXML());
}
}
else {
Presence storedPresence = (Presence)p;
Element delay = storedPresence.addChildElement("x", "jabber:x:delay");
delay.addAttribute("stamp", UTC_FORMAT.format(date));
buf.append(p.toXML());
}
// Append an XML representation of the packet to the string buffer
}
buf.append("</transcript>");
// Save the transcript (in XML) to the DB
DbWorkgroup.updateTranscript(sessionID, buf.toString(), new java.util.Date());
}
// If the agent and the user left the room then proceed to dump the transcript to
// the DB and destroy the room
if (!((Presence)packet).isAvailable() && set.isEmpty()) {
// Delete the counter of occupants for this room
occupantsCounter.remove(roomID);
initialRequest = requests.remove(sessionID);
if (initialRequest != null && initialRequest.hasJoinedRoom()) {
// Notify the request that the support session has finished
initialRequest.supportEnded();
}
// Build the XML for the transcript
Map<Packet, java.util.Date> map = transcripts.get(roomID);
StringBuilder buf = new StringBuilder();
buf.append("<transcript>");
for (Packet p : map.keySet()) {
java.util.Date date = map.get(p);
// Add the delay information
if (p instanceof Message) {
Message storedMessage = (Message)p;
Element delay = storedMessage.addChildElement("x", "jabber:x:delay");
delay.addAttribute("stamp", UTC_FORMAT.format(date));
if (ModelUtil.hasLength(storedMessage.getBody())) {
buf.append(p.toXML());
}
}
else {
Presence storedPresence = (Presence)p;
Element delay = storedPresence.addChildElement("x", "jabber:x:delay");
delay.addAttribute("stamp", UTC_FORMAT.format(date));
buf.append(p.toXML());
}
// Append an XML representation of the packet to the string buffer
}
buf.append("</transcript>");
// Save the transcript (in XML) to the DB
//DbWorkgroup.updateTranscript(sessionID, buf.toString(), new java.util.Date());
// Leave Chat Room (the room will be destroyed)
String roomJID = packet.getFrom().toString() + "/" + getJID().getNode();
LeaveRoom leaveRoom = new LeaveRoom(getFullJID().toString(), roomJID);
send(leaveRoom);
// Remove the transcript information of this room since the room no
// longer exists
transcripts.remove(roomID);
// Trigger the event that a chat support has finished
WorkgroupEventDispatcher.chatSupportFinished(this, sessionID);
}
// Invoke the room interceptor after the presence has been processed
interceptorManager.invokeInterceptors(getJID().toBareJID(), packet, false, true);
}
else if (packet instanceof Message) {
// Filter messages sent from the room itself since we don't want the
// transcript to include things like "room locked"
if (packet.getFrom().getResource() != null) {
// Invoke the room interceptor before processing the presence
interceptorManager.invokeInterceptors(getJID().toBareJID(), packet, false, false);
// Add the new message to the list of sent packets
Map<Packet, java.util.Date> messageList = transcripts.get(roomID);
if (messageList == null) {
messageList = new LinkedHashMap<Packet, java.util.Date>();
transcripts.put(roomID, messageList);
}
messageList.put(packet.createCopy(), new java.util.Date());
// Invoke the room interceptor after the presence has been processed
interceptorManager.invokeInterceptors(getJID().toBareJID(), packet, false, true);
}
}
}
}
/**
* An agent has accepted the offer and was choosen to answer the user's requests. The workgroup
* will create a new room where the agent can answer the user's needs. Once the room has been
* created, the Agent and the user that made the request will receive invitiations to join the
* newly created room.<p>
* <p/>
* The workgroup will listen for all the packets sent to the room and generate a conversation
* transcript.
*
* @param agent the AgentSession that accepted and was choosen to respond the user's requests.
* @param request the request made by a user.
*/
public void sendInvitation(AgentSession agent, UserRequest request) {
// TODO When running LA as a plugin (internal component) and if the plugin is removed then
// we need to destroy all MUC rooms created by workgroups
try {
RoomInterceptorManager interceptorManager = RoomInterceptorManager.getInstance();
WorkgroupManager workgroupManager = WorkgroupManager.getInstance();
String userJID = request.getUserJID().toString();
final Workgroup sessionWorkgroup = request.getWorkgroup();
final String sessionID = request.getSessionID();
String workgroupName = getJID().getNode();
final String serviceName = workgroupManager.getMUCServiceName();
final String roomName = sessionID + "@" + serviceName;
final String roomJID = roomName + "/" + workgroupName;
// Create the room by joining it. The workgroup will be the owner of the room and will
// invite the Agent and the user to join the room
JoinRoom joinRoom = new JoinRoom(getFullJID().toString(), roomJID);
interceptorManager.invokeInterceptors(getJID().toBareJID(), joinRoom, false, false);
send(joinRoom);
interceptorManager.invokeInterceptors(getJID().toBareJID(), joinRoom, false, true);
// Configure the newly created room
Map<String, Collection<String>> fields = new HashMap<String, Collection<String>>();
// Make a non-public room
List<String> values = new ArrayList<String>();
values.add("0");
fields.put("muc#roomconfig_publicroom", values);
// Set the room description
values = new ArrayList<String>();
values.add(roomName);
fields.put("muc#roomconfig_roomdesc", values);
// Set that anyone can change the room subject
values = new ArrayList<String>();
values.add("1");
fields.put("muc#roomconfig_changesubject", values);
// Make the room temporary
values = new ArrayList<String>();
values.add("0");
fields.put("muc#roomconfig_persistentroom", values);
// Set that only moderators can see the occupants' JID
values = new ArrayList<String>();
values.add("moderators");
fields.put("muc#roomconfig_whois", values);
// Set that we want packets to include the real JID
values = new ArrayList<String>();
values.add("0");
fields.put("anonymous", values);
// Only broadcast presences of participants and visitors
values = new ArrayList<String>();
values.add("participant");
values.add("visitor");
fields.put("muc#roomconfig_presencebroadcast", values);
RoomConfiguration conf = new RoomConfiguration(fields);
conf.setTo(roomName);
conf.setFrom(getFullJID());
interceptorManager.invokeInterceptors(getJID().toBareJID(), conf, false, false);
send(conf);
interceptorManager.invokeInterceptors(getJID().toBareJID(), conf, false, true);
// Create a new entry for the active session and the request made by the user
requests.put(sessionID, request);
// Invite the Agent to the new room
Invitation invitation = new Invitation(agent.getJID().toString(), sessionID);
invitation.setTo(roomName);
invitation.setFrom(getFullJID());
// Add workgroup extension that includes the JID of the user that made the request
Element element = invitation.addChildElement("offer", "http://jabber.org/protocol/workgroup");
element.addAttribute("jid", userJID);
// Add custom extension that includes the sessionID
element = invitation.addChildElement("session", "http://jivesoftware.com/protocol/workgroup");
element.addAttribute("workgroup", sessionWorkgroup.getJID().toString());
element.addAttribute("id", sessionID);
// Add custom extension that includes the userID if the session belongs to an
// anonymous user
if (request.isAnonymousUser()) {
element = invitation.addChildElement("user", "http://jivesoftware.com/protocol/workgroup");
element.addAttribute("id", request.getUserID());
}
interceptorManager.invokeInterceptors(getJID().toBareJID(), invitation, false, false);
send(invitation);
interceptorManager.invokeInterceptors(getJID().toBareJID(), invitation, false, true);
// Invite the user to the new room
sendUserInvitiation(request, roomName);
// Notify the request that invitations for support have been sent
request.invitationsSent(sessionID);
}
catch (Exception e) {
ComponentManagerFactory.getComponentManager().getLog().error(e);
}
}
/**
* Sends the room invitation to the user that made the request.
*
* @param request the Request that the user made to join a workgroup.
* @param roomID the id of the room where the user is being invited.
*/
public void sendUserInvitiation(UserRequest request, String roomID) {
String userJID = request.getUserJID().toString();
final String sessionID = request.getSessionID();
final String serviceName = WorkgroupManager.getInstance().getMUCServiceName();
final String roomName = sessionID + "@" + serviceName;
Invitation invitation = new Invitation(userJID, "Please join me for a chat.");
invitation.setTo(roomName);
invitation.setFrom(getFullJID());
// Add workgroup extension that includes the JID of the workgroup
Element element = invitation.addChildElement("workgroup",
"http://jabber.org/protocol/workgroup");
element.addAttribute("jid", getJID().toBareJID());
// Add custom extension that includes the sessionID
element =
invitation.addChildElement("session", "http://jivesoftware.com/protocol/workgroup");
element.addAttribute("id", sessionID);
RoomInterceptorManager interceptorManager = RoomInterceptorManager.getInstance();
interceptorManager.invokeInterceptors(getJID().toBareJID(), invitation, false, false);
send(invitation);
interceptorManager.invokeInterceptors(getJID().toBareJID(), invitation, false, true);
}
/**
* Users that have received an invitation to join a room and haven't done so may receive
* another invitation. The exact (recovery) action to do will depend on the type of client
* used by the user to join the workgroup. For instance, if the user was using a chatbot to
* join the workgroup then instead of receiving another invitation he may be asked if he wants
* to receive another invitation.
*/
public void checkRequests() {
for (String roomID : requests.keySet()) {
UserRequest request = requests.get(roomID);
// Check invitations if an invitation was sent and the user hasn't joined the room yet
if (request != null) {
request.checkRequest(roomID);
}
}
}
/**
* Returns the list of packets, including Presence and Messages, sent to the room or
* <tt>null</tt> if the room has currently no occupants (ie. does not exist).
*
* @param roomID the id of a room (node of the JID) that exists and was created by this
* workgroup for a chat with a user
* @return the list of packets sent to an existing room
*/
public Map<Packet, java.util.Date> getTranscript(String roomID) {
return transcripts.get(roomID);
}
// #############################################################################
// Package access methods - For classes that need extra workgroup access
// #############################################################################
/**
* <p>Obtain the agent manager associated with the workgroup.</p>
*
* @return The agent manager for this workgroup
* <p/>
* <!-- DbC -->
*/
public AgentManager getAgentManager() {
return agentManager;
}
/**
* Returns a collection with all the agent session that are present in the workgroup. If the
* same agent is present in more than one queue then the answer will only include one instance
* of the agent session.
*
* @return a collection with all the agent session that are present in the workgroup.
*/
public Collection<AgentSession> getAgentSessions() {
Collection<AgentSession> answer = new HashSet<AgentSession>();
for (RequestQueue queue : queues.values()) {
answer.addAll(queue.getAgentSessionList().getAgentSessions());
}
return Collections.unmodifiableCollection(answer);
}
/**
* Returns a collection with all the agent session that are available for chat in the workgroup.
* A chat session is available for chat based on the presence status. If the same agent is
* present in more than one queue then the answer will only include one instance of the agent
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -