
For about two years now I have been developing bots for ICQ. After a number of recent
events , because of which ICQ bots were often unworkable, as well as after the article
Introducing jabber bots , I had a strong desire to study issues related to the development of bots for Jabber.
In this post I want to share with you my first experience in this field. I'll tell you how from scratch, having spent only one hour of time, write a simple Jabber-bot.
As a platform for developing a bot, I chose
Openfire . The choice was influenced by the fact that Openfire is written in Java (I really didn’t want to learn something like Python). Openfire plug-in structure allows you to quickly and conveniently attach bot functionality to it. In addition, Openfire is easy to set up, and by that time it was already installed as my jabber server.
Set the environment
First you need to set the development environment that allows you to build and run Openfire and its plugins. Here is the installation process for Windows. On other operating systems, the process should look similar.
- Download and install the Java SE Development Kit (JDK) . You can take it here . I installed the JDK in C: \ Program Files \ Java (default folder). After installation in C: \ Program Files \ Java , the subfolders jdk1.6.0_12 and jre6 appeared .
- Downloading the Eclipse IDE for Java Developers from here . Unpack in the same folder C: \ Program Files \ Java . As a result, there will be another subfolder - eclipse .
- Set the environment variables (this is done via My Computer> Properties> Advanced> Environment Variables ):
- JAVA_HOME = C: \ Program Files \ Java \ jdk1.6.0_12 . If you unpacked the JDK in another folder, specify the appropriate path.
- In the Path variable we add C: \ Program Files \ Java \ jre6 \ bin (also check the correctness of the path).
- Reboot.
- Run Eclipse, which asks you to choose Workspace, or in other words, the directory in which the projects will be located. Suppose that this is C: \ Edit . After selecting Workspace, the Welcome screen appears, you can close it immediately.
Build an openfire
Now proceed to the second stage - the construction and launch of Openfire. Try to follow the instructions exactly, otherwise it is likely that nothing will work right away:
- We download source Openfire from here . In addition to directly Openfire, the archive contains the source for all free plugins. When developing your plugin, you can look into their code.
- The source archive contains the openfire_src folder. Unpack it in C: \ Edit .
- We go to Eclipse, create a new project according to the source code. To do this, select the menu File> New> Project> Java Project . A new java project creation window will appear. We write the following in it:
- Project name = openfire_src .
- Check the Create project from existing source . In the Directory specify C: \ Edit \ openfire_src .
- Click Finish .
- After Eclipse creates the project, it will be time to build it. To do this, select in the menu Window> Show view> Ant . An Ant panel appears in the Eclipse work area. Click on it with the right mouse button, in the drop-down menu select Add Buildfiles .
- In the tree that appears, choose openfire_src> build> build.xml . Click OK.
- In the Ant panel, an Openfire XMPP server appears with many build options.
- We collect Openfire. To do this, we find in the tree a variant of the assembly with the name openfire [default] and double click on it. You can also simply click on the root element of the tree.
- After a short time after starting the build, Eclipse should show a console in which information about the build progress will appear. We are waiting for the appearance of the inscription BUILD SUCCESSFUL .
- Now we set up the launch parameters for Openfire, for this we go to the menu Run> Run configurations .
- In the window that appears, double-click on the Java application . A new configuration is created, now it needs to be configured to run our assembly correctly. We write the following:
- Name = Openfire (or whatever, not important).
- Project = openfire_src .
- Main class = org.jivesoftware.openfire.starter.ServerStarter .
- On the Arguments tab in VM arguments, we write -DopenfireHome = "target / openfire" . Note that there is no space after -D .
- On the Classpath tab, select User entries and click the Advanced button. Select Add folders and add the folder openfire_src \ src \ i18n . After that in the same way we add the openfire_src \ src \ resources \ jar folder.
- Click Apply , then Run .
If everything is done correctly, a line with the Openfire version will appear in the console and a message stating that the administrator console is listening on port 9090. Now you can go for coffee, since the main part of the work is already behind. You can also mentally sympathize with those who have the cherished inscription in the console did not appear. Turning to the latter - carefully check the sequence of their actions. As I warned earlier, the instruction must be executed exactly, nothing extra must be done.
Customizing Openfire
We continue. Now you need to configure the Openfire server itself. We enter in the browser
localhost : 9090 , after which the setup procedure will start. Here everything is quite trivial. Since we set the configuration for development, we will not be particularly wise:
- On the Server Settings page, set the server name = localhost , default ports.
- On the Database Settings page, select Embedded Database .
- On the Profile Settings page, leave everything by default.
- On the Administrator Account page - enter any non-existent mailbox. Also enter and remember the admin password.
After that, you can select
Login to the admin console and go to the login page. You need to log in with the
admin account with the password specified earlier. You can also try to connect to our server with any jabber-client under the same
admin . If everything is fine, then you can stop the server and proceed to the next step.
')
We write bot
So we got to the most important stage. Now we need to write a plugin that will implement the functions of the bot.
All sources of the Openfire plug-ins are located in the
openfire_src \ src \ plugins folder. For each plug-in there is a separate folder, in which at least there is a
plugin.xml file with the description of the plug-in and a Java file with the description of the main class of the plug-in. For more information, see the Openfire documentation (see for example
openfire_src \ documentation \ docs \ plugin-dev-guide.html ).
Create a folder for the new plugin:
openfire_src \ src \ plugins \ simplebot . In it we get the file
plugin.xml , in which we write the following:
<? xml version ="1.0" encoding ="UTF-8" ? > <br><br> < plugin > <br> < class > org.jivesoftware.openfire.plugin.simplebot </ class > <br> < name > Simple Bot </ name > <br> < description > Provides simple bot functionality. </ description > <br> < author > Habrahabr </ author > <br> < version > 1.0.0 </ version > <br> < date > 18/2/2009 </ date > <br> < minServerVersion > 3.5.0 </ minServerVersion > <br> </ plugin > <br><br> <br> * This source code was highlighted with Source Code Highlighter .
Now you need to create a folder in which the source of the plugin will be located. More precisely, it will be a whole series of nested folders:
openfire_src \ src \ plugins \ simplebot \ src \ java \ org \ jivesoftware \ openfire \ plugin . Since each Openfire plug-in path to the main class is always the same, I did not create all these folders manually, but simply copied them from the MOTD plug-in, then deleted the old contents from them.
The last thing you need to do is in the
openfire_src \ src \ plugins \ simplebot \ src \ java \ org \ jivesoftware \ openfire \ plugin folder put the bot source. To do this, create the file
simplebot.java (the register is important) and copy the source code into it:
package org.jivesoftware.openfire.plugin;<br><br>import java.io.File;<br>import org.jivesoftware.openfire.container.Plugin;<br>import org.jivesoftware.openfire.container.PluginManager;<br>import org.jivesoftware.openfire.XMPPServer;<br>import org.jivesoftware.openfire.auth.AuthToken;<br>import org.jivesoftware.openfire.multiplex.ClientSessionConnection;<br>import org.jivesoftware.openfire.SessionManager;<br>import org.jivesoftware.openfire.SessionPacketRouter;<br>import org.jivesoftware.openfire.session.Session;<br>import org.jivesoftware.openfire.session.LocalClientSession;<br>import org.jivesoftware.openfire.interceptor.*;<br>import org.xmpp.packet.*;<br><br> // <br> // Simple Bot Plugin <br> // <br> public class simplebot implements Plugin {<br><br> private JID myJID;<br> private LocalClientSession mySession;<br> private myPacketInterceptor myInterceptor = new myPacketInterceptor();<br><br> public void initializePlugin(PluginManager manager, File pluginDirectory) {<br> System. out .println( "Starting Simple Bot Plugin" );<br> <br> myJID = new JID( "test" , XMPPServer.getInstance().getServerInfo().getXMPPDomain(), "simplebot" );<br> <br> ClientSessionConnection connection = <br> new ClientSessionConnection(XMPPServer.getInstance().getConnectionManager().getClass().getName(),<br> "localhost" , "127.0.0.1" );<br> mySession = SessionManager.getInstance().createClientSession(connection);<br> mySession.setAuthToken( new AuthToken(myJID.getNode()), myJID.getResource());<br> <br> InterceptorManager.getInstance().addInterceptor(myInterceptor);<br> } // initializePlugin <br><br> public void destroyPlugin() {<br> // Resources are no longer needed <br> InterceptorManager.getInstance().removeInterceptor(myInterceptor);<br> mySession.close();<br><br> myJID = null ;<br> mySession = null ;<br> myInterceptor = null ;<br> } // destroyPlugin <br> <br> private class myPacketInterceptor implements PacketInterceptor {<br> <br> public void interceptPacket(Packet packet,<br> Session session,<br> boolean incoming,<br> boolean processed) throws PacketRejectedException<br> {<br> // If there is an incoming message for the bot <br> if (packet instanceof Message &&<br> packet.getTo().getNode().equals(myJID.getNode()) &&<br> incoming == true &&<br> processed == true )<br> {<br> // Create the response ... <br> Message message = new Message();<br> message.setTo(packet.getFrom());<br> message.setFrom(packet.getTo());<br> message.setSubject( "" );<br> message.setBody( "Hello from Simple OpenFire Bot" );<br> <br> // ... and send it <br> SessionPacketRouter router = new SessionPacketRouter(mySession);<br> router.route(message);<br> }<br> } // interceptPacket <br> <br> } // myPacketInterceptor <br><br>} // simplebot <br><br> <br> * This source code was highlighted with Source Code Highlighter .
Immediately, I note that this is the minimum amount of working code that I managed to achieve. Thrown out all the additional features and all checks. The bot does not know how to change its status, does not know how to authorize users. But he consistently responds to all incoming messages with the phrase “Hello from Simple OpenFire Bot”.
Let's take a look at how it works. The main class of the plugin is an implementation of the Plugin interface with two functions inside:
- initializePlugin - initializes the plugin when it starts. Here we initialize the myJID variable, which will contain the JID of the bot like test @ domain \ simplebot . When running on localhost, it will accordingly be test @ localhost \ simplebot . Next we create a new session for our JID. To do this, you need to establish a connection to the server ( connection ) and create a session ( mySession ) within this connection. In conclusion, it is necessary to authorize our user in this session.
- destroyPlugin - called when a plugin is destroyed. Here we release all previously captured resources.
In addition, the main plugin class contains the
myPacketInterceptor helper class that implements the
PacketInterceptor interface. This class is responsible for intercepting all messages that pass through the Openfire server (for this, inside
initializePlugin, we sign an instance of this class to intercept messages using the
InterceptorManager ). Now, when any message appears, the
interceptPacket function from this class will be called. All we have to do is to select the messages inside our function that are addressed to our JID and respond to them with the phrase “Hello from Simple OpenFire Bot”.
Now we need to build our plugin, and then start Openfire. In order to build a plugin (as well as all other plugins), you need to double-click on the target
plugins in the Ant panel (do not confuse with the
plugin ). Then wait for the
BUILD SUCCESSFUL caption to appear in the console. Now when you start Openfire in the console, among other things, the inscription
Starting Simple Bot Plugin should appear.
Well, that's it, now you can connect to the server with any jabber client (using the
admin account) and write some message to
test @ localhost to check the bot's work.
What's next?
As noted earlier, the bot described here is endowed with the most modest functionality. I am currently adding additional features to it, and plan to write a whole series of notes about this.
In any case, I hope that it brought the idea that the development of a jabber-bot is actually not such a complicated matter as it may seem at first glance.