Jump to: navigation, search

Difference between revisions of "ECF/Bot Framework"

< ECF
(Notice)
(Conclusion)
 
(16 intermediate revisions by 6 users not shown)
Line 1: Line 1:
The '''Bot Framework''' was introduced as a new API in [[Eclipse Communication Framework|ECF]]'s [http://www.eclipse.org/ecf/NewAndNoteworthy_1.0.0M6.html 1.0.0M6 release]. It interoperated with the presence API which allowed it to be leveraged as both a typical chatroom-oriented bot in addition to one that was based around instant messaging. A bot can easily be created with just an implementation of an interface in addition to the declaration of extension points.
+
The '''Bot Framework''' was introduced as a new API in [[Eclipse Communication Framework|ECF]]'s [http://www.eclipse.org/ecf/NewAndNoteworthy_1.0.0M6.html 1.0.0M6 release]. It interoperated with the presence API which allowed it to be leveraged as both a typical [http://en.wikipedia.org/wiki/Internet_Relay_Chat_bot chatroom-oriented bot] in addition to one that was based around instant messaging. A bot can easily be created with just an implementation of an interface in addition to the declaration of extension points.
  
 
The tutorial below will show you just how easy it is to create a bot for IRC. This tutorial assumes the reader has some basic knowledge about plug-in development. This tutorial was tested on Linux using Sun's 1.4.2.13 JDK, the 3.3M6 build of the Eclipse SDK, and code from Eclipse.org's HEAD branch.
 
The tutorial below will show you just how easy it is to create a bot for IRC. This tutorial assumes the reader has some basic knowledge about plug-in development. This tutorial was tested on Linux using Sun's 1.4.2.13 JDK, the 3.3M6 build of the Eclipse SDK, and code from Eclipse.org's HEAD branch.
 
==Notice==
 
The code below will not work with the 1.0.0M6 build of ECF because of a bug that causes the 'IChatRoomContainer' instance passed into 'preChatRoomConnect(IChatRoomContainer, ID)' to be null. Please use the code from CVS HEAD when going through this tutorial. The ECF team would like to apologize for any inconvenience caused.
 
  
 
==Requirements==
 
==Requirements==
Line 39: Line 36:
  
 
===Extensions===
 
===Extensions===
#Open the 'Extensions' tab.
+
#Open the '''Extensions''' tab.
#Add the 'org.eclipse.ecf.presence.bot.chatroomrobot' and the 'org.eclipse.ecf.presence.bot.chatroommessagehandler' extension point.
+
#Add the '''org.eclipse.ecf.presence.bot.chatRoomRobot''' and the '''org.eclipse.ecf.presence.bot.chatRoomMessageHandler''' extension point.
#Select the 'org.eclipse.ecf.presence.bot.chatroomrobot' extension.
+
#Select the '''org.eclipse.ecf.presence.bot.chatRoomRobot''' extension.
 
#Fill in something unique for your 'id'. '''org.eclipse.ecf.example.bot.geir2'''
 
#Fill in something unique for your 'id'. '''org.eclipse.ecf.example.bot.geir2'''
 
#Fill in '''ecf.irc.irclib''' for your 'containerFactoryName'.
 
#Fill in '''ecf.irc.irclib''' for your 'containerFactoryName'.
#For the 'connectID', select an IRC server of your choice and a name for the bot. '''irc://geir2@irc.freenode.net'''
+
#For the 'connectId', select an IRC server of your choice and a name for the bot. '''irc://geir2@irc.freenode.net'''
#For the 'chatroom' field, pick the channel that you want your bot to join upon successful connection to the server above. '''#eclipse'''
+
#For the 'chatRoom' field, pick the channel that you want your bot to join upon successful connection to the server above. '''#eclipse'''
#Now select the 'org.eclipse.ecf.presence.bot.chatroommessagehandler' extension point.
+
#Now select the '''org.eclipse.ecf.presence.bot.chatRoomMessageHandler''' extension point.
 
#For your 'id', copy the same 'id' that you filled in above. '''org.eclipse.ecf.example.bot.geir2'''
 
#For your 'id', copy the same 'id' that you filled in above. '''org.eclipse.ecf.example.bot.geir2'''
#In 'filterexpression', enter a regular expression that should be matched for parsing purposes for your bot. '''(~bug[0-9]*)
+
#In 'filterExpression', enter a regular expression that should be matched for parsing purposes for your bot. '''(~bug[0-9]*)
 
#Click on the 'class*' hyperlink and then create a new class that implements the 'org.eclipse.ecf.presence.bot.IChatRoomMessageHandler' interface. For this example, I will assume that your class's name is '''Geir2Bot''' under the '''org.eclipse.ecf.example.bot''' package..
 
#Click on the 'class*' hyperlink and then create a new class that implements the 'org.eclipse.ecf.presence.bot.IChatRoomMessageHandler' interface. For this example, I will assume that your class's name is '''Geir2Bot''' under the '''org.eclipse.ecf.example.bot''' package..
  
 
'''plugin.xml'''
 
'''plugin.xml'''
<?xml version="1.0" encoding="UTF-8"?>
+
<source lang="xml">
<?eclipse version="3.2"?>
+
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
+
<?eclipse version="3.2"?>
    <extension
+
<plugin>
          point="org.eclipse.ecf.presence.bot.chatroommessagehandler">
+
  <extension
      <handler
+
        point="org.eclipse.ecf.presence.bot.chatRoomMessageHandler">
            chatroomrobotid="org.eclipse.ecf.example.bot.geir2"
+
      <handler
            class="org.eclipse.ecf.example.bot.Geir2Bot"
+
            chatRoomRobotId="org.eclipse.ecf.example.bot.geir2"
            filterexpression="(~bug[0-9]*)">
+
            class="org.eclipse.ecf.example.bot.Geir2Bot"
      </handler>
+
            filterExpression="(~bug[0-9]*)">
    </extension>
+
      </handler>
    <extension
+
  </extension>
          point="org.eclipse.ecf.presence.bot.chatroomrobot">
+
  <extension
      <chatroomrobot
+
        point="org.eclipse.ecf.presence.bot.chatRoomRobot">
            chatroom="#eclipse"
+
      <chatRoomRobot           
            connectID="irc://geir2@irc.freenode.net"
+
            connectId="irc://geir2@irc.freenode.net"
            containerFactoryName="ecf.irc.irclib"
+
            containerFactoryName="ecf.irc.irclib"
            id="org.eclipse.ecf.example.bot.geir2">
+
            id="org.eclipse.ecf.example.bot.geir2"
      </chatroomrobot>
+
            >
    </extension>
+
    <chatRooms
</plugin>
+
              name="#eclipse">
 +
        </chatRooms>  
 +
      </chatRoomRobot>
 +
  </extension>
 +
</plugin>
 +
</source>
  
 
==Writing the Code==
 
==Writing the Code==
Line 85: Line 87:
  
 
'''org.eclipse.ecf.example.bot.Geir2Bot'''
 
'''org.eclipse.ecf.example.bot.Geir2Bot'''
package org.eclipse.ecf.example.bot;
+
<source lang="java">
+
package org.eclipse.ecf.example.bot;
import org.eclipse.ecf.core.IContainer;
+
 
import org.eclipse.ecf.core.identity.ID;
+
import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.core.util.ECFException;
+
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.presence.bot.IChatRoomBotEntry;
+
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.presence.bot.IChatRoomMessageHandler;
+
import org.eclipse.ecf.presence.bot.IChatRoomBotEntry;
import org.eclipse.ecf.presence.chatroom.IChatRoomContainer;
+
import org.eclipse.ecf.presence.bot.IChatRoomMessageHandler;
import org.eclipse.ecf.presence.chatroom.IChatRoomMessage;
+
import org.eclipse.ecf.presence.chatroom.IChatRoomContainer;
import org.eclipse.ecf.presence.chatroom.IChatRoomMessageSender;
+
import org.eclipse.ecf.presence.chatroom.IChatRoomMessage;
+
import org.eclipse.ecf.presence.chatroom.IChatRoomMessageSender;
public class Geir2Bot implements IChatRoomMessageHandler {
+
 
+
public class Geir2Bot implements IChatRoomMessageHandler {
private IChatRoomMessageSender sender;
+
 
+
private IChatRoomMessageSender sender;
public void handleRoomMessage(IChatRoomMessage message) {
+
 
// use substring 1 to just truncate the opening tilda (~)
+
public void handleRoomMessage(IChatRoomMessage message) {
String msg = message.getMessage().substring(1);
+
// use substring 1 to just truncate the opening tilda (~)
try {
+
String msg = message.getMessage().substring(1);
if (msg.equals("bug")) { //$NON-NLS-1$
+
try {
// if no number was provided, just send them to bugzilla
+
if (msg.equals("bug")) { //$NON-NLS-1$
sender.sendMessage("https://bugs.eclipse.org/bugs/"); //$NON-NLS-1$
+
// if no number was provided, just send them to bugzilla
} else {
+
sender.sendMessage("https://bugs.eclipse.org/bugs/"); //$NON-NLS-1$
// otherwise, give the person a direct link to the bug
+
} else {
  sender.sendMessage("https://bugs.eclipse.org/bugs/" //$NON-NLS-1$
+
// otherwise, give the person a direct link to the bug
+ "show_bug.cgi?id=" + msg.substring(3)); //$NON-NLS-1$
+
sender.sendMessage("https://bugs.eclipse.org/bugs/" //$NON-NLS-1$
}
+
+ "show_bug.cgi?id=" + msg.substring(3)); //$NON-NLS-1$
} catch (ECFException e) {
+
}
e.printStackTrace();
+
} catch (ECFException e) {
}
+
e.printStackTrace();
}
+
}
+
}
public void init(IChatRoomBotEntry robot) {
+
 
// nothing to do
+
public void init(IChatRoomBotEntry robot) {
}
+
// nothing to do
+
}
public void preChatRoomConnect(IChatRoomContainer roomContainer, ID roomID) {
+
 
sender = roomContainer.getChatRoomMessageSender();
+
public void preChatRoomConnect(IChatRoomContainer roomContainer, ID roomID) {  
}
+
sender = roomContainer.getChatRoomMessageSender();
+
}
public void preContainerConnect(IContainer container, ID targetID) {
+
 
// nothing to do
+
public void preContainerConnect(IContainer container, ID targetID) {
}
+
// nothing to do
+
}
}
+
 
 +
}
 +
</source>
  
 
==Running the Example==
 
==Running the Example==
 
#Open the 'Run' dialog and then right-click on 'Eclipse Application' and select 'New'.
 
#Open the 'Run' dialog and then right-click on 'Eclipse Application' and select 'New'.
#From the combo drop down in the 'Program to Run' section, select 'Run an application:' and choose '''org.eclipse.ecf.presence.bot.chatroombot'''.
+
#In the 'Main' tab, from the combo drop down in the 'Program to Run' section, select 'Run an application:' and choose '''org.eclipse.ecf.presence.bot.chatRoomRobot'''.
 
#Click on the '''Plug-ins''' tab.
 
#Click on the '''Plug-ins''' tab.
 
#From the top, select '''plug-ins selected below only''' from the drop down box.
 
#From the top, select '''plug-ins selected below only''' from the drop down box.
Line 145: Line 149:
 
  <rcjsuen> ~bug76759
 
  <rcjsuen> ~bug76759
 
  <geir2> https://bugs.eclipse.org/bugs/show_bug.cgi?id=76759
 
  <geir2> https://bugs.eclipse.org/bugs/show_bug.cgi?id=76759
 +
 +
Tip: If you get an error about "ContainerTypeDescription cannot be null" you probably forgot to select the ''org.eclipse.ecf.provider.irc'' plugin in step 5 above!
 +
 +
==Working Demo==
 +
A working and well-featured [[IRC bot|implementation]] is currently being run on [[IRC|Eclipse-related channels on freenode]].
  
 
==Conclusion==
 
==Conclusion==
 
I hope you learned enough from this tutorial to be ready to go out and write your own bots using ECF's bot framework. If you have any questions, please do not hesitate to on the [http://www.eclipse.org/ecf/newsgroups.php newsgroup]. For questions, comments, inquiries, and anything else to the development of the framework or ECF in general, please join the ecf-dev [http://www.eclipse.org/ecf/maillist.php mailing lists].
 
I hope you learned enough from this tutorial to be ready to go out and write your own bots using ECF's bot framework. If you have any questions, please do not hesitate to on the [http://www.eclipse.org/ecf/newsgroups.php newsgroup]. For questions, comments, inquiries, and anything else to the development of the framework or ECF in general, please join the ecf-dev [http://www.eclipse.org/ecf/maillist.php mailing lists].
 +
 +
{{ECF}}
  
 
[[Category:Eclipse Communication Framework]]
 
[[Category:Eclipse Communication Framework]]
 +
[[Category:ECF]]

Latest revision as of 09:47, 22 December 2010

The Bot Framework was introduced as a new API in ECF's 1.0.0M6 release. It interoperated with the presence API which allowed it to be leveraged as both a typical chatroom-oriented bot in addition to one that was based around instant messaging. A bot can easily be created with just an implementation of an interface in addition to the declaration of extension points.

The tutorial below will show you just how easy it is to create a bot for IRC. This tutorial assumes the reader has some basic knowledge about plug-in development. This tutorial was tested on Linux using Sun's 1.4.2.13 JDK, the 3.3M6 build of the Eclipse SDK, and code from Eclipse.org's HEAD branch.

Requirements

As regular expression pattern matching is used, a Java runtime environment of 1.4.2 or higher is required.

The Bot Framework leverages code that is new to Equinox in Eclipse 3.3, so a recent milestone must be installed for this example to work.

ECF Plug-ins

  • org.eclipse.ecf (core ECF APIs)
  • org.eclipse.ecf.core.identity (identity and namespace APIs)
  • org.eclipse.ecf.presence (presence APIs for monitoring messages and presence status)
  • org.eclipse.ecf.presence.bot (bot API)
  • org.eclipse.ecf.provider.irc (IRC implementation and ECF bridging code)

Please see ECF's downloads page to find out how to retrieve these plug-ins.

Project Setup

Dependencies

  1. Create a Plug-in Project like how you normally would. Since this is a bot that will be run in headless mode, we do not need any UI components. You do not even need an activator class.
  2. Open the MANIFEST.MF file and go to the 'Dependencies' tab.
  3. Add org.eclipse.ecf, org.eclipse.ecf.presence, and org.eclipse.ecf.presence.bot as a 'Required Plug-in'.
  4. Now add org.eclipse.core.runtime as an 'Imported Package'.

MANIFEST.MF

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Geir Plug-in
Bundle-SymbolicName: org.eclipse.ecf.example.geir;singleton:=true
Bundle-Version: 1.0.0
Require-Bundle: org.eclipse.ecf,
 org.eclipse.ecf.presence,
 org.eclipse.ecf.presence.bot
Import-Package: org.eclipse.core.runtime

Extensions

  1. Open the Extensions tab.
  2. Add the org.eclipse.ecf.presence.bot.chatRoomRobot and the org.eclipse.ecf.presence.bot.chatRoomMessageHandler extension point.
  3. Select the org.eclipse.ecf.presence.bot.chatRoomRobot extension.
  4. Fill in something unique for your 'id'. org.eclipse.ecf.example.bot.geir2
  5. Fill in ecf.irc.irclib for your 'containerFactoryName'.
  6. For the 'connectId', select an IRC server of your choice and a name for the bot. irc://geir2@irc.freenode.net
  7. For the 'chatRoom' field, pick the channel that you want your bot to join upon successful connection to the server above. #eclipse
  8. Now select the org.eclipse.ecf.presence.bot.chatRoomMessageHandler extension point.
  9. For your 'id', copy the same 'id' that you filled in above. org.eclipse.ecf.example.bot.geir2
  10. In 'filterExpression', enter a regular expression that should be matched for parsing purposes for your bot. (~bug[0-9]*)
  11. Click on the 'class*' hyperlink and then create a new class that implements the 'org.eclipse.ecf.presence.bot.IChatRoomMessageHandler' interface. For this example, I will assume that your class's name is Geir2Bot under the org.eclipse.ecf.example.bot package..

plugin.xml

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<plugin>
   <extension
         point="org.eclipse.ecf.presence.bot.chatRoomMessageHandler">
      <handler
            chatRoomRobotId="org.eclipse.ecf.example.bot.geir2"
            class="org.eclipse.ecf.example.bot.Geir2Bot"
            filterExpression="(~bug[0-9]*)">
      </handler>
   </extension>
   <extension
         point="org.eclipse.ecf.presence.bot.chatRoomRobot">
      <chatRoomRobot            
            connectId="irc://geir2@irc.freenode.net"
            containerFactoryName="ecf.irc.irclib"
            id="org.eclipse.ecf.example.bot.geir2"
            >
     <chatRooms
               name="#eclipse">
         </chatRooms>    
      </chatRoomRobot>
   </extension>
</plugin>

Writing the Code

Interface Implementation

  1. Open the Geir2Bot class that you have created.
  2. Since we want our bot to be able to say something, we need to retrieve an interface that will provide us with such a functionality.
  3. Add a field to the class of type IChatMessageSender.
  4. We will retrieve our instance in the preChatRoomConnect(IChatRoomContainer, ID) method. This method will be called right before our bot joins the channel (#eclipse in our case). You can retrieve an instance of an IChatMessageSender by calling getChatRoomMessageSender() on the provided IChatRoomContainer instance.
  5. Now that our bot has a mechanism for replying, we should write some code to parse the messages that the bot receives so that it can give a correct response. To get the string that's been said, use the getMessage() method from the IChatRoomMessage interface that's passed into the handleRoomMessage(IChatRoomMessage) method.
  6. Our regular expression of (~bug[0-9]*) implies that any string beginning with ~bug followed by any number of digits will be a valid input for our bot to read. So let's add some string handling code to route people to Eclipse's bugzilla when they type something like ~bug150000 or ~bug180078.
  7. To send a reply to the IRC channel, simply use IChatRoomMessageSender's sendMessage(String) method. This method will throw an ECFException, but given this simple scenario, we won't bother to handle it.

org.eclipse.ecf.example.bot.Geir2Bot

package org.eclipse.ecf.example.bot;
 
import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.presence.bot.IChatRoomBotEntry;
import org.eclipse.ecf.presence.bot.IChatRoomMessageHandler;
import org.eclipse.ecf.presence.chatroom.IChatRoomContainer;
import org.eclipse.ecf.presence.chatroom.IChatRoomMessage;
import org.eclipse.ecf.presence.chatroom.IChatRoomMessageSender;
 
public class Geir2Bot implements IChatRoomMessageHandler {
 
	private IChatRoomMessageSender sender;
 
	public void handleRoomMessage(IChatRoomMessage message) {
		// use substring 1 to just truncate the opening tilda (~)
		String msg = message.getMessage().substring(1);
		try {
			if (msg.equals("bug")) { //$NON-NLS-1$
				// if no number was provided, just send them to bugzilla
				sender.sendMessage("https://bugs.eclipse.org/bugs/"); //$NON-NLS-1$
			} else {
				// otherwise, give the person a direct link to the bug
 				sender.sendMessage("https://bugs.eclipse.org/bugs/" //$NON-NLS-1$
						+ "show_bug.cgi?id=" + msg.substring(3)); //$NON-NLS-1$
			}
		} catch (ECFException e) {
			e.printStackTrace();
		}
	}
 
	public void init(IChatRoomBotEntry robot) {
		// nothing to do
	}
 
	public void preChatRoomConnect(IChatRoomContainer roomContainer, ID roomID) { 
		sender = roomContainer.getChatRoomMessageSender();
	}
 
	public void preContainerConnect(IContainer container, ID targetID) {
		// nothing to do
	}
 
}

Running the Example

  1. Open the 'Run' dialog and then right-click on 'Eclipse Application' and select 'New'.
  2. In the 'Main' tab, from the combo drop down in the 'Program to Run' section, select 'Run an application:' and choose org.eclipse.ecf.presence.bot.chatRoomRobot.
  3. Click on the Plug-ins tab.
  4. From the top, select plug-ins selected below only from the drop down box.
  5. Pick the plug-in you created (in the example, this was org.eclipse.ecf.example.geir) and org.eclipse.ecf.provider.irc.
  6. Click on the Add Required Plug-ins button on the right and then hit Run.
  7. Moments later, your bot should appear in the server and channel that you specified in the plugin.xml file.
* geir2 (n=geir2@bas3-kitchener06-1096650252.dsl.bell.ca) has joined #eclipse
<rcjsuen> ~bug
<geir2> https://bugs.eclipse.org/bugs/
<rcjsuen> ~bug76759
<geir2> https://bugs.eclipse.org/bugs/show_bug.cgi?id=76759

Tip: If you get an error about "ContainerTypeDescription cannot be null" you probably forgot to select the org.eclipse.ecf.provider.irc plugin in step 5 above!

Working Demo

A working and well-featured implementation is currently being run on Eclipse-related channels on freenode.

Conclusion

I hope you learned enough from this tutorial to be ready to go out and write your own bots using ECF's bot framework. If you have any questions, please do not hesitate to on the newsgroup. For questions, comments, inquiries, and anything else to the development of the framework or ECF in general, please join the ecf-dev mailing lists.

Eclipse Communication Framework
API
API DocumentationJavadocProvidersECF/Bot Framework
Development
Development GuidelinesIntegrators Guide