Project

General

Profile

how to implement a online-customer service robot by tigase?

peirong jiang
Added over 3 years ago

how to implement a online-customer service robot by tigase?

I don't know how to develop the plugin,I can't modify the packet's body content,could you help me ?

my demo code like this:

        @Override
    public boolean preProcess(Packet packet, XMPPResourceConnection session, NonAuthUserRepository repo, Queue<Packet> results, Map<String, Object> settings) {
        JID from =  packet.getStanzaTo();
        if ("message" == packet.getElemName() && "admin".equals(from.getLocalpart()) && null!=packet.getElemCData("message/body") ) {
            try {
                Packet resultData =  packet.swapFromTo();
                // 简单的对XML元素进行克隆,然后……
                Element result = resultData.getElement().clone();
                String content = result.getCData("message/body");
                Element elemBody = result.findChildStaticStr(Message.MESSAGE_BODY_PATH);
                if (null!=elemBody && null!=elemBody.getChildren() && elemBody.getChildren().size() > 0 )
                {
                    String body = elemBody.childrenToString();
                    if (null!=body && ""!=body) {
                        elemBody.getChildren().remove(0).addChild(new CData("--您好,回复:Message:" + body));
                    }else{
                        elemBody.getChildren().remove(0).addChild(new CData("----消息不能为空!"));
                    }

                    result.removeChild(result.findChildStaticStr(Message.MESSAGE_BODY_PATH));
                    result.addChild(elemBody);
                }
                //修改返回内容
//              String body = result.getAttribute("body");
//              result.setAttribute("body","你好,"+body);
                Packet response =  Packet.packetInstance(result) ;
                // 在大多数情况,这可能是一个能够保持于客户端连接的c2s或Bosh组件
                response.setPacketTo(packet.getPacketFrom());
                // 在大多数情况,这一步可以跳过,但是当packet的投递过程出现了什么问题,这么做可以为调用者返回一个错误
                response.setPacketFrom(packet.getPacketTo());
                // 把他放到传出packet队列里面就行了
                results.offer( response);
                return true;//表示拦截后不再做后续处理,直接响应客户端
            } catch (TigaseStringprepException e) {
                e.printStackTrace();
            }

        }

        return false;
    }

any help will be appreciated!


Replies (5)

Added by peirong jiang over 3 years ago

I have optimized my code like this:

@Override
    public boolean preProcess(Packet packet, XMPPResourceConnection session,
                              NonAuthUserRepository repo, Queue<Packet> results, Map<String, Object> settings) {
        /*JID from =  packet.getStanzaTo();
        if (Message.ELEM_NAME == packet.getElemName() && "robot".equals(from.getLocalpart())  && null!=packet.getElemCData("message/body") ) { // && "admin".equals(from.getLocalpart())
            try {
                *//*Packet ok_result = Packet.packetInstance("message", packet.getStanzaFrom().toString(), packet.getStanzaTo().toString(), StanzaType.chat);
                ok_result.setPacketFrom(packet.getPacketFrom());
                ok_result.setPacketTo(packet.getPacketTo());
                //Packet ok_result = packet.okResult((String) "你好", 0);
                ok_result.setPriority(Priority.NORMAL);*//*
                Packet ok_result = packetMsgResult(packet,StanzaType.chat,"您好,已收到您的消息",true);
                results.offer(ok_result);
                //return true;//表示拦截后不再做后续处理,直接响应客户端
            } catch (Exception e) {
                e.printStackTrace();
            }
        }*/

        return false;
    }
    /**
     * 处理消息
     * @param packet 在PROCESS处理过程中无法修改它
     * @param session XMPPResourceConnection用于保存所有用户的数据,它提供权限访问用户的仓库数据,在没有在线用户SESSION的情况下该参数可以为null
     * @param repo NonAuthUserRepository该参数往往在参数session为NULL的时候被使用,它用于为不在线的用户保存私有或公开的数据信息。
     * @param results Queue<Packet>这个为输入数据包的处理结果产生的数据包集合,它总被要求一定要存放一个输入数据包PACKET的备份到里面,其实包含了所有需要处理的PACKET,<strong>包括process生成的结果packet</strong>。
     * @param settings Map<String, Object>  为PLUGIN制定配置信息,一般情况下不需要使用,然而如果需要访问额外的数据库则可以通过配置文件将数据库连接字符串传给plugin
     *
     * @throws XMPPException
     */
    @Override
    public void process(Packet packet, XMPPResourceConnection session, NonAuthUserRepository repo, Queue<Packet> results, Map<String, Object> settings) throws XMPPException {
        // 出于性能的考虑,最好在打印日志之前现检查一下日志级别
        if(log.isLoggable(Level.FINEST)) {
            log.finest("Robot Plugin -> Processing packet: "+ packet.toString());
        }

        JID from =  packet.getStanzaTo();
        if (Message.ELEM_NAME == packet.getElemName() && "robot".equals(from.getLocalpart())  && null!=packet.getElemCData("message/body") ) { // && "admin".equals(from.getLocalpart())
            try {
                /*Packet ok_result = Packet.packetInstance("message", packet.getStanzaFrom().toString(), packet.getStanzaTo().toString(), StanzaType.chat);
                ok_result.setPacketFrom(packet.getPacketFrom());
                ok_result.setPacketTo(packet.getPacketTo());
                //Packet ok_result = packet.okResult((String) "你好", 0);
                ok_result.setPriority(Priority.NORMAL);*/
                Packet ok_result = packetMsgResult(packet,StanzaType.chat,"您好,已收到您的消息-" + Math.random(),true);
                ok_result.setPriority(Priority.NORMAL);
                if (!results.isEmpty()) {
                    results.remove();
                }
                results.offer(ok_result);
                //return true;//表示拦截后不再做后续处理,直接响应客户端
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

but my client received twice messages of the same from tigase-server(my robot plugin). how can i resovle it?

any help will be appreciated.

1.png (45.7 KB) 1.png

Added by Wojciech Kapcia TigaseTeam over 3 years ago

Please peruse How Packets are Processed by the SM and Plugins As described there - plugins are consumers, so they need to create result packets. With that in mind - if you have two plugins responsible for processing/handling stanzas of same type and both of them create a result packet this will entail user receiving message twice.

Added by peirong jiang over 3 years ago

OK, I have resolved it.

Now a new problem:

I have created a robot repository in JDBCRepository ,Now I want to use the robotRepository instance in my plugin class: RobotPlugin.java

How can i to get the robotRepository instance in the method (the following)?

public boolean preProcess(Packet packet, XMPPResourceConnection session, NonAuthUserRepository repo, Queue results, Map settings)

I just get the userRepository instance according to the session instance.but can't get my robot repository instance.

maybe I must devlop a component to resolved the problem.(I know it can get my repository instance by the component class' method: setProperties(Map props))

Added by Wojciech Kapcia TigaseTeam over 3 years ago

In plugins you cannot get direct access to User/AuthRepository via available API.

Added by peirong jiang over 3 years ago

understand it.

now I set my repository instance to the tigase's props map.and then modify plugin-init methods to implement to set robot-repository instance from pros map to plugin class' init(settings) method.

then I can get the instance from RobotPlugin.java's init() method.

    (1-5/5)