Respond to instant messages

From libopenmetaverse - libomv - Developer Wiki

Jump to: navigation, search

Contents

Prerequisites

The following prerequisites are required in order for you to create your first bot by following this tutorial.

Real World

  • This tutorial assumes that you were able to successfully build libsecondlife! If you have not compiled libsl, please follow the instructions on the Getting Started wikipage.
  • Also, if you have no experience with the C# (c-sharp) programming language, I highly recommend that you stop now and please follow the list of links to csharp tutorials located here.

The Code

Note: We are assuming that our main "GridClient" instance is named "Client." If you have a different name for this variable, please substitute the name accordingly

 
// put this somewhere when you want to start processing instant messages
Client.Self.OnInstantMessage += new AgentManager.InstantMessageCallback(Self_OnInstantMessage); 
 
//(...) then define the Self_OnInstantMessage method
 
static void Self_OnInstantMessage(InstantMessage im, Simulator sim)
{
      //there are a variety of InstantMessageDialog choices.. MessageFromObject and MessageFromAgent would be the two most common
      if (im.Dialog == InstantMessageDialog.MessageFromAgent) 
      {
           Client.Self.InstantMessage(im.FromAgentID, im.Message, im.IMSessionID); 
           //send them an instant message back (this thing will copy any message the bot recieves in an IM)
      }
}
 

If you get a compile error on InstantMessage (The type or namespace name `InstantMessage' could not be found). Try this:

 
Client.Self.OnInstantMessage += new AgentManager.InstantMessageCallback(Self_OnInstantMessage); 
static void Self_OnInstantMessage(UUID fromAgentID, string fromAgentName, UUID toAgentID, 
            uint parentEstateID, UUID regionID, Vector3 position, AgentManager.InstantMessageDialog dialog, 
            bool groupIM, UUID imSessionID, DateTime timestamp, string message, 
            AgentManager.InstantMessageOnline offline, byte[] binaryBucket)
{
	if (dialog == AgentManager.InstantMessageDialog.MessageFromAgent)
	{
		Client.Self.InstantMessage(fromAgentID, message, imSessionID);
	}
}
 

With thanks to jradford@#libsl-dev, this example shows how to respond a a group invite, friend request or teleport lure.

 
void Self_OnInstantMessage(InstantMessage im, Simulator simulator)
    {
        switch (im.Dialog)
        {
 
            case InstantMessageDialog.FriendshipOffered:
                    Client.Friends.AcceptFriendship(im.FromAgentID, im.IMSessionID); // Accept Friendship Offer
                    //Client.Friends.DeclineFriendship(im.FromAgentID, im.IMSessionID); // Decline Friendship Offer
                break;
            case InstantMessageDialog.GroupInvitation:
                    // Accept Group Invitation (Join Group)
                    Client.Self.InstantMessage(client.Self.Name, im.FromAgentID, string.Empty, im.IMSessionID, 
                    	InstantMessageDialog.GroupInvitationAccept, InstantMessageOnline.Offline, client.Self.SimPosition, 
                    	UUID.Zero, new byte[0]);
                    
                    // Decline Group Invitation
                    //Client.Self.InstantMessage(client.Self.Name, im.FromAgentID, string.Empty, im.IMSessionID, 
                    //	InstantMessageDialog.GroupInvitationDecline, InstantMessageOnline.Offline, client.Self.SimPosition, 
                    //	UUID.Zero, new byte[0]); 
                break;
 
            // someone sent a teleport lure
            case InstantMessageDialog.RequestTeleport:
                    Client.Self.TeleportLureRespond(im.FromAgentID, true);
                break;
 
          case InstantMessageDialog.InventoryOffered:
                    // Accept an Inventory Offer
                    Client.Self.InstantMessage(Client.Self.Name, im.FromAgentID, String.Empty, im.IMSessionID, InstantMessageDialog.InventoryAccepted,
                        InstantMessageOnline.Offline, Client.Self.SimPosition, UUID.Zero, new byte[0]);
                        if (im.BinaryBucket.Length == 17)
                        {
                            assettype = (AssetType)im.BinaryBucket[0];
                            objectID = new UUID(im.BinaryBucket, 1);
                        }
                        Console.WriteLine("{0} Has Given me Inventory {1}", im.FromAgentName, im.Message);
 
                      // Decline Inventory Offer
                      //Client.Self.InstantMessage(Client.Self.Name, im.FromAgentID, String.Empty, im.IMSessionID, InstantMessageDialog.InventoryDeclined,
                      //  InstantMessageOnline.Offline, Client.Self.SimPosition, UUID.Zero, new byte[0]);
          break;
            default:
                break;
        }
    }
 

Important: Please notice the IMSessionID parameter of InstantMessage(). It is optional, but if you do not include it when you are replying to an instant message, it will open a new tab on the actual client instead of keeping the conversation on one tab. If you are too lazy, you can use LLUUID.Zero as the sessionID and it should work most of the time, but it is not guaranteed

See this This documentation page for a listing of InstantMessageDialog enumerations

The above link is broken, the trunk (development build) is found at: http://lib.openmetaverse.org/docs/trunk/html/T_OpenMetaverse_InstantMessageDialog.htm

Notes

  • There are many tasks you can accomplish with Instant Message processing.. in fact, "Instant Messages" are not just IMs to and from avatars, but it also handles green IM text from objects, the 'Alpha Zaius is typing...' text, Teleport Requests, Friend Requests, sending a URL open request, and much more. There are already wrapper classes for most of these functions though
  • If we didn't check for the Dialog type, it will IM the avatar "typing" whenever they type. Notice the InstantMessageDialog.StartTyping/StopTyping enumerations.