From 51bfc341be1975b7a11e0b3a59cfbb4710e78446 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Wed, 4 Oct 2017 15:31:44 +0300 Subject: juick-xmpp-wip: router component --- .../main/java/com/juick/components/XMPPBot.java | 161 +++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 juick-xmpp-wip/src/main/java/com/juick/components/XMPPBot.java (limited to 'juick-xmpp-wip/src/main/java/com/juick/components/XMPPBot.java') diff --git a/juick-xmpp-wip/src/main/java/com/juick/components/XMPPBot.java b/juick-xmpp-wip/src/main/java/com/juick/components/XMPPBot.java new file mode 100644 index 00000000..b551ff2b --- /dev/null +++ b/juick-xmpp-wip/src/main/java/com/juick/components/XMPPBot.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2008-2017, Juick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.juick.components; + +import com.juick.User; +import com.juick.server.helpers.UserInfo; +import com.juick.server.protocol.JuickProtocol; +import com.juick.server.protocol.ProtocolListener; +import com.juick.service.PMQueriesService; +import com.juick.service.UserService; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.env.Environment; +import rocks.xmpp.addr.Jid; +import rocks.xmpp.core.XmppException; +import rocks.xmpp.core.stanza.model.Message; +import rocks.xmpp.extensions.component.accept.ExternalComponent; +import rocks.xmpp.extensions.vcard.temp.VCardManager; +import rocks.xmpp.extensions.vcard.temp.model.VCard; +import rocks.xmpp.extensions.version.SoftwareVersionManager; +import rocks.xmpp.extensions.version.model.SoftwareVersion; + +import javax.inject.Inject; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.util.List; + +/** + * Created by vt on 12/11/2016. + */ +public class XMPPBot implements AutoCloseable, ProtocolListener { + private static final Logger logger = LoggerFactory.getLogger(XMPPBot.class); + @Inject + UserService userService; + @Inject + PMQueriesService pmQueriesService; + @Inject + JuickProtocol juickProtocol; + + Jid juickJid; + + private ExternalComponent component; + + public XMPPBot(Environment env) { + component = ExternalComponent.create(env.getProperty("component_name", "juick.com"), + env.getProperty("component_password", "secret"), env.getProperty("component_host", "localhost"), + NumberUtils.toInt(env.getProperty("component_port", "5347"), 5347)); + juickJid = Jid.of(env.getProperty("xmppbot_jid", "juick@juick.com/Juick")); + juickProtocol.setListener(this); + try { + SoftwareVersionManager softwareVersionManager = component.getManager(SoftwareVersionManager.class); + softwareVersionManager.setSoftwareVersion(new SoftwareVersion("Juick", "git", System.getProperty("os.name", "generic"))); + VCardManager vCardManager = component.getManager(VCardManager.class); + vCardManager.setEnabled(true); + VCard ownVCard = new VCard(); + ownVCard.setNickname("Juick"); + ownVCard.setUrl(new URL("http://juick.com/")); + ownVCard.setPhoto(new VCard.Image("image/png", IOUtils.toByteArray(getClass().getClassLoader().getResourceAsStream("vCard.png")))); + vCardManager.setVCard(ownVCard); + component.addInboundMessageListener(e -> { + Message message = e.getMessage(); + if (message.getType().equals(Message.Type.ERROR) || message.getType().equals(Message.Type.GROUPCHAT)) { + return; + } + String text = message.getBody().trim(); + String command = text.toUpperCase(); + User user = userService.getUserByJID(message.getFrom().asBareJid().toString()); + if (command.equals("VCARD")) { + try { + VCard vCard = vCardManager.getVCard(message.getFrom().asBareJid()).getResult(); + UserInfo info = new UserInfo(); + info.setFullName(vCard.getFormattedName()); + info.setCountry(vCard.getAddresses().get(0).getCountry()); + info.setUrl(vCard.getUrl().toString()); + userService.updateUserInfo(user, info); + component.sendMessage(new Message(message.getFrom(), Message.Type.CHAT, "vCard updated")); + } catch (XmppException vce) { + logger.warn("vcard exception", vce); + } + } else { + try { + String reply = juickProtocol.getReply(user, text); + Message replyMessage = new Message(message.getFrom(), Message.Type.CHAT); + replyMessage.setBody(reply); + replyMessage.setFrom(juickJid); + component.send(replyMessage); + } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException ex) { + logger.warn("unhandled error", ex); + } + } + }); + component.connect(); + } catch (XmppException | IOException e) { + logger.error("bot connection error", e); + } + } + + @Override + public void close() throws Exception { + if (component != null) + component.close(); + + logger.info("ExternalComponent on xmpp-bot destroyed"); + } + + @Override + public void privateMessage(User from, User to, String body) { + List toJids = userService.getJIDsbyUID(to.getUid()); + toJids.forEach(jid -> { + Message mm = new Message(); + mm.setTo(Jid.of(jid)); + mm.setType(Message.Type.CHAT); + boolean haveInRoster = pmQueriesService.havePMinRoster(from.getUid(), jid); + if (haveInRoster) { + mm.setFrom(Jid.of(from.getName(), juickJid.getDomain(), "Juick")); + mm.setBody(body); + } else { + mm.setFrom(Jid.of("juick", juickJid.getDomain(), "Juick")); + mm.setBody("Private message from @" + from.getName() + ":\n" + body); + } + component.send(mm); + }); + } + + @Override + public void userSubscribed(User from, User to) { + String notification = String.format("%s subscribed to your blog", from.getName()); + List toJids = userService.getJIDsbyUID(to.getUid()); + toJids.forEach(jid -> { + Message mm = new Message(); + mm.setTo(Jid.of(jid)); + mm.setType(Message.Type.CHAT); + mm.setFrom(juickJid); + mm.setBody(notification); + component.send(mm); + }); + } + + @Override + public void messagePosted(com.juick.Message msg) { + + } +} -- cgit v1.2.3