diff --git a/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/action/XMPPActions.java b/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/action/XMPPActions.java index 4bcc6b509e5..5d37b61d409 100644 --- a/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/action/XMPPActions.java +++ b/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/action/XMPPActions.java @@ -65,6 +65,23 @@ public class XMPPActions implements ThingActions { connection.sendMessage(to, text); } + @RuleAction(label = "publish a group message", description = "Publish a group message using XMPP.") + public void publishGroupXMPP(@ActionInput(name = "to", label = "To", description = "Send to") @Nullable String to, + @ActionInput(name = "text", label = "Text", description = "Message text") @Nullable String text) { + XMPPClientHandler clientHandler = handler; + if (clientHandler == null) { + logger.warn("XMPP ThingHandler is null"); + return; + } + + XMPPClient connection = clientHandler.getXMPPClient(); + if (to == null || text == null) { + logger.warn("Skipping XMPP messaging to {} value {}", to, text); + return; + } + connection.sendGroupMessage(to, text); + } + @RuleAction(label = "publish an image by HTTP", description = "Publish an image by HTTP using XMPP.") public void publishXMPPImageByHTTP( @ActionInput(name = "to", label = "To", description = "Send to") @Nullable String to, @@ -87,6 +104,10 @@ public class XMPPActions implements ThingActions { ((XMPPActions) actions).publishXMPP(to, text); } + public static void publishGroupXMPP(ThingActions actions, @Nullable String to, @Nullable String text) { + ((XMPPActions) actions).publishGroupXMPP(to, text); + } + public static void publishXMPPImageByHTTP(ThingActions actions, @Nullable String to, @Nullable String filename) { ((XMPPActions) actions).publishXMPPImageByHTTP(to, filename); } diff --git a/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/client/XMPPClient.java b/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/client/XMPPClient.java index 4ca39840436..3a2a12c0db6 100644 --- a/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/client/XMPPClient.java +++ b/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/client/XMPPClient.java @@ -37,8 +37,11 @@ import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; import org.jivesoftware.smackx.httpfileupload.HttpFileUploadManager; +import org.jivesoftware.smackx.muc.MultiUserChat; +import org.jivesoftware.smackx.muc.MultiUserChatManager; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.impl.JidCreate; +import org.jxmpp.jid.parts.Resourcepart; import org.jxmpp.stringprep.XmppStringprepException; import org.openhab.binding.xmppclient.internal.handler.XMPPClientMessageSubscriber; import org.slf4j.Logger; @@ -55,9 +58,11 @@ public class XMPPClient implements IncomingChatMessageListener, ConnectionListen private final Logger logger = LoggerFactory.getLogger(XMPPClient.class); private @Nullable AbstractXMPPConnection connection; private @Nullable ChatManager chatManager; + private @Nullable MultiUserChatManager multiUserChatManager; private @Nullable HttpFileUploadManager httpFileUploadManager; private Set subscribers = new HashSet<>(); private final XMPPClientEventlistener eventListener; + private String nickname = ""; public XMPPClient(XMPPClientEventlistener eventListener) { this.eventListener = eventListener; @@ -73,7 +78,7 @@ public class XMPPClient implements IncomingChatMessageListener, ConnectionListen subscribers.remove(channel); } - public void connect(String host, Integer port, String login, String domain, String password, + public void connect(String host, Integer port, String login, String nick, String domain, String password, SecurityMode securityMode) throws XMPPClientConfigException, XMPPClientException { disconnect(); String serverHost = domain; @@ -81,6 +86,12 @@ public class XMPPClient implements IncomingChatMessageListener, ConnectionListen serverHost = host; } + if (!nick.isBlank()) { + nickname = nick; + } else { + nickname = login; + } + XMPPTCPConnectionConfiguration config; try { config = XMPPTCPConnectionConfiguration.builder() // @@ -115,6 +126,10 @@ public class XMPPClient implements IncomingChatMessageListener, ConnectionListen ChatManager chatManager = ChatManager.getInstanceFor(connection); chatManager.addIncomingListener(this); this.chatManager = chatManager; + + MultiUserChatManager multiUserChatManager = MultiUserChatManager.getInstanceFor(connection); + multiUserChatManager.setAutoJoinOnReconnect(true); + this.multiUserChatManager = multiUserChatManager; httpFileUploadManager = HttpFileUploadManager.getInstanceFor(connection); } @@ -145,6 +160,33 @@ public class XMPPClient implements IncomingChatMessageListener, ConnectionListen } } + public void sendGroupMessage(String to, String message) { + if (connection == null) { + eventListener.onErrorEvent("XMPP connection is null"); + return; + } + + MultiUserChatManager chatManager = this.multiUserChatManager; + if (chatManager == null) { + eventListener.onErrorEvent("XMPP chatManager is null"); + return; + } + try { + EntityBareJid jid = JidCreate.entityBareFrom(to); + MultiUserChat chat = multiUserChatManager.getMultiUserChat(jid); + + if (!chat.isJoined()) { + chat.join(Resourcepart.from(nickname)); + } + + chat.sendMessage(message); + } catch (XmppStringprepException | SmackException.NotConnectedException | InterruptedException e) { + logger.warn("XMPP message sending error", e); + } catch (SmackException | XMPPException e) { + logger.warn("XMPP message group join error", e); + } + } + public void sendImageByHTTP(String to, String filename) { if (connection == null) { logger.warn("XMPP connection is null"); diff --git a/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/handler/XMPPClientConfiguration.java b/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/handler/XMPPClientConfiguration.java index b2f0bfdef55..ac1f9c08af4 100644 --- a/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/handler/XMPPClientConfiguration.java +++ b/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/handler/XMPPClientConfiguration.java @@ -26,6 +26,7 @@ public class XMPPClientConfiguration { public @Nullable String host; public Integer port = 5222; public String username = ""; + public String nickname = ""; public String password = ""; public String domain = ""; public String securityMode = SecurityMode.required.toString(); diff --git a/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/handler/XMPPClientHandler.java b/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/handler/XMPPClientHandler.java index 3c7cfc2dbfd..3b1f381e8b7 100644 --- a/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/handler/XMPPClientHandler.java +++ b/bundles/org.openhab.binding.xmppclient/src/main/java/org/openhab/binding/xmppclient/internal/handler/XMPPClientHandler.java @@ -95,8 +95,8 @@ public class XMPPClientHandler extends BaseBridgeHandler implements XMPPClientEv } try { - xmppClient.connect(Objects.requireNonNullElse(config.host, ""), config.port, config.username, config.domain, - config.password, SecurityMode.valueOf(config.securityMode)); + xmppClient.connect(Objects.requireNonNullElse(config.host, ""), config.port, config.username, + config.nickname, config.domain, config.password, SecurityMode.valueOf(config.securityMode)); updateStatus(ThingStatus.ONLINE); } catch (XMPPClientConfigException e) { logger.debug("XMPP connection error", e); diff --git a/bundles/org.openhab.binding.xmppclient/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.xmppclient/src/main/resources/OH-INF/thing/thing-types.xml index ea506032b3c..db15e6ca45c 100644 --- a/bundles/org.openhab.binding.xmppclient/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.xmppclient/src/main/resources/OH-INF/thing/thing-types.xml @@ -12,6 +12,11 @@ The XMPP Username (the left side of JID, e.g. user for JID user@example.com) + + + The XMPP Nickname to use in multi user chats. (Defaults to Username) + true + The XMPP Domain (the right side of JID, e.g. example.com for JID user@example.com)