1 Introduction 2 Getting Started 2.1 Requirements 2.2 The Bot Definition File 2.3 Running a Bot 2.4 Testing a Bot 2.5 Debugging a Bot 3 Client Gateways 3.1 Connecting a Bot to IM Networks 3.2 Client Properties 3.3 Password Security 3.3.1 The EncryptPassword Utility 3.3.2 Using Pass Keys 4 Targets 4.1 Sending Content and Messages 4.2 Using Parameters 4.2.1 Getting User Input 4.2.2 Validating User Input (with Patterns) 4.3 Sending Files 4.4 Nested Targets 5 Actions 5.1 Java Actions 5.2 System Actions 6 Menus 6.1 Creating Sub-Menus 6.2 Navigating a Menu Hierarchy 7 Event Handlers 7.1 Menu-Local Event Handlers 7.2 Consuming Events 8 Filters 8.1 Include Filters 8.2 Exclude Filters 8.3 Using Patterns In Filters 9 Dynamic Content 9.1 Dynamic XML 9.2 The Java API 10 Available Content Variables 10.1 User 10.2 Client 10.3 Statistics 10.4 Client Statistics 1 Introduction This guide will bring you up to speed on how to create a bot using the JBuddy Bot Framework (tm). Clear examples and descriptions of various features are given. 2 Getting Started 2.1 The Bot Definition File The bot engine processes messages and events from users and sends back responses. The engine is driven by an XML file called the Bot Definition File. The Bot Definition File contains markup defining the bot's logic and content. It contains a top-level element which looks like this: All elements in the Bot Definition File are part of the "http://www.zionsoftware.com/jbuddy/bot" namespace. 2.2 Running a Bot To run a bot, use the Run utility. Assuming your Bot Definition File is named "bot.xml", type the following at the command line from the lib folder of the installation directory: java -cp Bots.jar Run If your bot definition file is not named "bot.xml", specify the file path. For example, for a file named "mybot.xml", type the following at the command line: java -cp Bots.jar Run mybot.xml 2.3 Testing a Bot There is also a Test utility. You can use it to test a bot by issuing commands to it from the command line. Unlike Run, no network connections are made. You can use Test to test most of the examples in this guide. Assuming your Bot Definition File is named "bot.xml", type the following at the command line from the lib folder of the installation directory: java -cp Bots.jar Test If your bot definition file is not named "bot.xml", specify the file path. For example, for a file named "mybot.xml", type the following at the command line: java -cp Bots.jar Test mybot.xml 2.4 Debugging a Bot To help understand what the bot engine is doing and to help fix potential problems, you can enable debug logging. Do this by setting the bot's log level. Here, we set the log level to "all", which prints all log messages to the console, regardless of severity: 3 Client Gateways Client gateways allow the bot to connect to one or more public or private instant messaging networks. Once the bot is connected, users on those networks may interact with the bot. 3.1 Connecting a Bot to IM Networks To connect the bot to an IM network, use the element. It must be defined under the top level element. The following example connects the bot to the AOL Instant Messenger network: (Replace "myaimbot" and "mypassword" with your AIM login information.) Once signed in to AIM, AIM users may send messages to, and interact with, the bot. Multiple client gateways can be defined, to connect the bot to multiple networks. Here are the available network protocols, as provided by the JBuddy SDK: JSC - Zion Software's JBuddy Message Server AIM - AOL Instant Messenger ICQ - "I Seek You" MSN - MSN Messenger (also known as Windows Live Messenger) YIM - Yahoo Messenger LCS - Microsoft Live Communications Server JABBER - Jabber/XMPP SAMETIME - IBM Lotus Sametime You may now use the Run utility to run your bot and connect it to various types of networks. 3.2 Client Properties Special properties can be set in the client definition. These can be used to override similar entries in the JBuddy SDK's protocol properties files, such as "AIM.properties". We can add a property to tell JBuddy to send a keep-alive message to the server every 60 seconds from our AIM client: 3.3 Password Security As a security measure, to avoid using plain-text passwords in the bot definition, passwords can be encrypted. 3.3.1 The EncryptPassword Utility The utility asks for a password and an optional "pass key". It returns an encrypted password string, which may be used in a client definition. Type the following at the command line, from the lib folder of the installation directory: java -cp Bots.jar EncryptPassword You are prompted to enter some values. Here's an example session: Enter a password: mypassword Enter a pass key (optional): The encrypted value is: 5xnFMAERlD0jdfnP5WeA/g== Now, place the encrypted value in the client definition: Setting passwordEncrypted to "true" tells the bot engine that the password is encrypted, and needs to be decrypted in order to connect. 3.3.2 Using Pass Keys Password security can be increased further by introducing a custom pass key that is used to encrypt the client passwords. Here is an example EncryptPassword session with a custom pass key: Enter a password: mypassword Enter a pass key (optional): mypasskey The encrypted value is: 24Qw020G/TzpZdKOrnnydg== Note that the encrypted value is now different from the earlier example, which did NOT use a pass key. Place the encrypted value in the client definition as usual: You must specify the custom pass key to the Run utility in order for the engine to properly decrypt passwords. To run the previous example with the new pass key, type the following at the command line: java -cp Bots.jar Run -passkey mypasskey 4 Targets Targets are tasks carried out by the bot in response to an event, such as a message from a user. They can be used to send messages or files to the user, carry out actions, and more. A target is defined under the element, like this: SOME_TITLE The command is a one-word command typed by a user which triggers this target. The title is used to describe this target within menus (see the section on menus for more information). 4.1 Sending Content and Messages In this example, we have an "about" target that provides some simple content to the user: About This Bot This is a test bot built by Zion Software to show the capabilities of the JBuddy Bot Framework. Now, when a user types "about", the content ("This is a test bot...") is sent to them in the form of an instant message. Content may contain HTML-like markup which is parsed by the bot engine and shown as rich text. Supported HTML tags include (bold), (italic), (underline), (strike-through), , (superscript), (subscript), and (hyperlink). A element can also be used to send a message. The previous example can be rewritten as follows: About This Bot This is a test bot built by Zion Software to show the capabilities of the JBuddy Bot Framework. Recipients can also be specified in a message, using a comma-delimited list of user names. The above example can be modified to send the "about" info to users other than the one who typed the command (in this case, to both "adam" and "joe"): About This Bot This is a test bot built by Zion Software to show the capabilities of the JBuddy Bot Framework. Note the differences between and . is used to send simple instant message replies. Multiple, successive elements are combined into a single instant message to the user, and recipients cannot be specified. 4.2 Using Parameters Parameters can be used to ask a user for input. The user's input can be used later by the engine in various ways. 4.2.1 Getting User Input The following example asks the user for his or her birth date: Enter Your Birth Date Please enter your birth date (MM/DD/YYYY): You entered: ${date} If a user types "birth", the parameter's description is displayed to the user. The value entered by the user is saved as the "date" parameter value. A message is then sent back, confirming the date the user entered. ${date} is an example of a content variable. (The engine replaces ${date} with the value of the "date" parameter.) Here is an example session: User: birth Bot: Please enter your birth date (MM/DD/YYYY): User: 04/15/1980 Bot: You entered: 04/15/1980 The user can also choose not to enter a value, canceling execution of the parameter (and its target) by simply typing "cancel". 4.2.2 Validating User Input (with Patterns) The previous example can be improved to validate the user's input, only accepting a value from the user if it matches a specified pattern: Enter Your Birth Date Please enter your birthday (MM/DD/YYYY): You entered: ${date} The pattern is a regular expression. It matches 2 digits (the month), followed by a forward slash, followed by 2 digits (the day), followed by a forward slash, followed by 4 digits (the year). Here is an example session: User: birth Bot: Please enter your birth date (MM/DD/YYYY): User: april 15 1980 Bot: Invalid input. Please enter your birth date (MM/DD/YYYY): User: 04/15/1980 Bot: You entered: 04/15/1980 4.3 Sending Files Files can also be sent to the user. The following example creates a "file" target that sends a file named "test.gif": Request a File Hey ${displayName}, Please accept this image. ${displayName} is another example of a content variable. The engine replaces this variable with the value of the user's display name. Also, like messages, recipients can be specified: Request a File Hey ${displayName}, Please accept this image. 4.4 Nested Targets Targets can call other targets. For example, consider the following target: Here is some content. Here is some more content. Now, if a user types "nested", the bot sends the following message: Here is some content. This is a test bot built by Zion Software to show the capabilities of the JBuddy Bot Framework. Here is some more content. Note the use of the "ref" attribute. It is used to reference the existing "about" target by its command name. 5 Actions Actions are external processes carried out by the bot engine. They can be a Java class file, or a system command. 5.1 Java Actions A Java action loads and executes an external Java class. The class must extend the abstract com.zion.jbuddy.bots.BotActionTask class. Here's an example of a Java action: A Java Action Enter your first name: Here is the code for MyActionTask.java: import java.util.*; import com.zion.jbuddy.bots.*; /** * An example action task. */ public class MyActionTask extends BotActionTask { public Object execute() { return "Hi there, " + parameters.get("firstname"); } } Parameter values are saved in the parameters Map attached to the BotActionTask. The content returned from the execute method is sent to the user as an instant message, similar to a element. Here is an example session: User: java Bot: Enter your first name: User: Bob Bot: Hi there, Bob! 5.2 System Actions A system action calls a system command or executable file. The results of the command are returned to the user. Here's an example of a system action: Ping an Address Please enter an address to ping. If a user types "ping", the bot asks the user to enter a value for "address". After the user enters the address, the system "ping" command is called. The address value is passed to the ping command (the content variable ${address} is replaced with the parameter's value). Finally, the results of the ping command are sent to the user in an instant message. The results could also be saved to a file, which is then sent to the user: Ping an Address Please enter an address to ping. The "resultType" attribute dictates what type of content is sent to the user (in this case, a file). 6 Menus Menus are used to organize targets (and other menus) into a menu hierarchy. When a user opens a menu, its available targets and sub-menus are presented to the user. Menus are defined under the top-level element. Here is an example of a simple menu: Options Menu Here are the available options. Ping an Address Please enter an address to ping. About This Bot This is a test bot built by Zion Software to show the capabilities of the JBuddy Bot Framework. Here is an example session: User: options Bot: Options Menu Here are the available options. ping - Ping an Address about - About This Bot The menu displays its available target commands and their descriptive titles. The targets from earlier examples are now available within this menu. After loading this menu, the user can use the "about" and "ping" commands. Here is an example session: User: options Bot: Options Menu Here are the available options. ping - Ping an Address about - About This Bot User: ping Bot: Please enter an address to ping. Remember that targets can also be referenced from other targets. The previous example can be rewritten using references: Options Menu Here are the available options. For the references to work, the "ping" and "about" targets must be defined under , like in the earlier examples. 6.1 Creating Sub-Menus Menus can be defined under other menus, creating sub-menus. The following example adds an "actions" sub-menu to "options": Options Menu Here are the available options. Actions Menu Here are the available actions. Like targets, menus can also be referenced. The above example can be rewritten using references. In this example, "actions" is a top-level menu, but can also be found as a sub-menu of "options". Actions Menu Here are the available actions. Options Menu Here are the available options. 6.2 Navigating a Menu Hierarchy Using the earlier examples, the user may navigate the menu hierarchy. Here is an example session: User: options Bot: Options Menu Here are the available options. ping - Ping an Address about - About This Bot actions - Actions Menu User: actions Bot: Actions Menu Here are the available actions. java - A Java Action system - A System Action back - Back to Options Menu Note that the "actions" sub-menu contains a selection that wasn't defined before: "back". The "back" command is automatically available when a user navigates to a new menu while viewing another. Here is an example session, illustrating the "back" command: User: options Bot: Options Menu Here are the available options. ping - Ping an Address about - About This Bot actions - Actions Menu User: actions Bot: Actions Menu Here are the available actions. java - A Java Action system - A System Action back - Back to Options Menu User: back Bot: Options Menu Here are the available options. ping - Ping an Address about - About This Bot actions - Actions Menu Another built-in command, "refresh", can be used to show the last menu the user navigated to: User: options Bot: Options Menu Here are the available options. ping - Ping an Address about - About This Bot actions - Actions Menu User: refresh Bot: Options Menu Here are the available options. ping - Ping an Address about - About This Bot actions - Actions Menu 7 Event Handlers Event handlers are similar to targets, but instead of being triggered by user commands, they are triggered in response to certain events, such as a user message or status change. The element is defined under the element, just like targets and menus. In the following example, an event handler is triggered when a user sends a message to the bot: Hey! You just sent me a message. Note that the message may be an IM, a typing notification, or more. Event handlers can also be called in response to presence updates (such as when a user changes their status): I just received your presence update! Now, when the bot receives a presence update from a user on its buddy list, it sends them an instant message. 7.1 Menu-Local Event Handlers Event handlers can be defined directly within menus. A menu-local event handler can only be triggered when the user is viewing the menu it is contained in. For example, we can define a menu-local event handler in the "options" menu we defined earlier: Options Menu Here are the available options. Hey! You just sent Options Menu a message. Now, if a user types "options", and then types any message, the bot will send a message back. Here is an example session: User: options Bot: Options Menu Here are the available options. ping - Ping an Address about - About This Bot actions - Actions Menu User: hi Bot: Hey! You just sent Options Menu a message. 7.2 Consuming Events Normally, when an event occurs, the bot engine will try to trigger each associated event handler, in order. If you'd like an event handler to prevent the engine from triggering more event handlers for the same event, you can "consume" the event. Take the following example: Hello there! Hello there! (You won't see this!) If a user types a message, the bot triggers the first event handler, but since the event is consumed there, the second event handler is NOT triggered. The engine processes event handlers first, and then if the event was an IM message, it processes user commands. Therefore if an event is consumed, it will not trigger any further event handlers, targets, or menus. 8 Filters Filters can be used to restrict a , , or to certain users or properties. Each of these elements may contain a element that represents a set of filters. 8.1 Include Filters An include filter allows only users or events that match the filter. If any include filters are defined, at least one of them must match for the target or event handler to be triggered. For example, an include filter could be used to create an event handler that responds to IM type messages, ignoring all other types of messages: Hey! You just sent me an IM. A more powerful example is an event handler that automatically accepts buddy authorization requests on the Yahoo Messenger network: Thanks for adding me to your buddy list! Filters may apply to presence event handlers. The following example sends a message to users on the bot's buddy list when they are BUSY: I can see that you are busy! Filters apply to targets and menus, too. The following example creates an "about" target that is only available to users using the JABBER protocol: About Jabber You are using the Jabber protocol! You can also define multiple similar targets with separate filters. The first target that is allowed will be triggered. The following example defines an "about" command that returns a different target depending if a user is on AOL Instant Messenger, MSN Messenger, or Yahoo Messenger: About AOL Instant Messenger You are using AOL Instant Messenger! About MSN Messenger You are using MSN Messenger! About Yahoo Messenger You are using Yahoo Messenger! 8.2 Exclude Filters An exclude filter tells the engine NOT to allow users or events that match the filter. The following example sends a response message to users, but only if they are NOT using the JABBER protocol: Hey! You just sent me an IM. We could also hide the actions menu from JABBER users: Actions Menu Here are the available actions. 8.3 Using Patterns In Filters Powerful regular expression patterns can be used anywhere in a filter. For example, we can make the bot send a response message to users on the "jabber.org" Jabber server only: Hey! You just sent me an IM. Note the value of the "user" attribute. It is a regular expression meaning "one or more characters followed by "@jabber.org". 9 Dynamic Content Dynamic features can be added to a bot. 9.1 Dynamic XML Raw bot definition elements can be returned from an action. The XML is parsed and processed by the engine on-the-fly, thus creating dynamic content. In this example, we create a Java action that returns a menu using dynamic XML. Here is the target that calls the Java action: Create a Dynamic Menu Setting the action resultType to "xml" tells the engine that the action returns dynamic XML that needs to be processed. Here is the source code for "DynamicMenuTask.java": import com.zion.jbuddy.bots.*; public class DynamicMenuTask extends BotActionTask { public Object execute() { return "" + " A Dynamic Menu" + " " + " " + ""; } } Note that all features available in the bot definition XML are available dynamically, including target and menu references. 9.2 The Java API A complete Java API is included with the framework that can also be used to create dynamic content. We can rewrite the previous example's source code to build the dynamic menu using pure Java code, instead of XML: import com.zion.jbuddy.bots.*; import com.zion.jbuddy.richcontent.RichContent; public class DynamicMenuTask extends BotActionTask { public Object execute() { BotMenu menu = new BotMenu(); RichContent titleContent = new RichContent(); titleContent.append("A Dynamic Menu"); menu.setTitle(titleContent); BotEngine engine = user.getClient().getEngine(); BotTarget optionsMenu = engine.getTargets().getByID("options"); menu.getTargets().add(optionsMenu); BotTarget aboutTarget = engine.getTargets().getByID("about"); menu.getTargets().add(aboutTarget); return menu; } } For more information on using the Java API, consult the javadocs included with the framework. 10 Available Content Variables These are the content variables that can be used within element content and certain attributes. 10.1 User These variables apply to the user. ${protocol} The user's protocol. ${name} The user's name. ${displayName} The user's display name. ${command} The command the user entered (if any). ${commandValue} The command value entered by the user (if any). The command value is everything entered after the command name. ${messageType} The type of message the user entered (if any). ${message} The message contents the user entered (if any). ${status} The user's status. ${statusMessage} The user's status message. 10.2 Client These variables apply to the user's associated client gateway. ${client.name} The client's name. ${client.displayName} The client's display name. 10.3 Statistics These variables apply to the bot engine. ${statistics.sessions} The current number of user sessions. ${statistics.peakSessions} The peak (highest) number of concurrent user sessions that occurred since the engine was started. ${statistics.totalSessions} The total number of user sessions handled since the engine was started. ${statistics.uniqueSessions} The number of unique user sessions handled in the last 24 hours since the engine was started. ${statistics.sentMessages} The number of messages sent since the engine was started. ${statistics.receivedMessages} The number of messages received since the engine was started. 10.4 Client Statistics These variables apply to the user's associated client gateway. ${client.statistics.sessions} The current number of user sessions. ${client.statistics.peakSessions} The peak (highest) number of concurrent user sessions that occurred since the engine was started. ${client.statistics.totalSessions} The total number of user sessions handled since the engine was started. ${client.statistics.uniqueSessions} The number of unique user sessions handled in the last 24 hours since the engine was started. ${client.statistics.sentMessages} The number of messages sent since the engine was started. ${client.statistics.receivedMessages} The number of messages received since the engine was started.