Here is a quick and dirty opensim region module that uses the Twitterizer library to access the Twitter API.
For each visitor that enters a region, the module posts a Twitter update with the visitor’s name. Each visitor is only recorded once in a one hour period to avoid the spam that could result from avatars logging in repeatedly or flying back and forth across borders.
Visitors can also post comments or suggestions to the Twitter page by chatting on channel 15.
Here is a quick opensim region module that lets you do a couple basic tasks using the Twitterizer library to access the Twitter API.
For each visitor that enters a region, the module posts a Twitter update with the visitor’s name. Each visitor is only recorded once in a one hour period to avoid the spam that could result from avatars logging in repeatedly or flying back and forth across borders.
Visitors can also post comments or suggestions to the Twitter page by chatting on channel 15. This could be misused for griefing so there is a limit on the number of comments that can be posted in a 24 hour period.
I could see this module being useful in an orientation or help-desk type region where the owners would like to be able to personally greet as many visitors as possible without having to keep a viewer logged in all the time. A dedicated twitter account would be set up for the region, and by following that twitter account a region owner (or a team) could keep tabs on what is happening in the region and log in when visitors arrive. It could also be useful for a special-interest region like mine. I have a very small target audience, so the visitors are few and far between but most are likely people I want to meet.
I could have done this with emails instead of a twitter feed (I wrote that module too) but I like the openness of this system. Visitors are free to view the comments left by others – perhaps even stimulating an ongoing dialogue. And it seems a little less “big brother” to make visitor tracking public. Though if you prefer, you can change the settings of the twitter feed to only allow specific people to view. (Added 9/19/09) It probably isn’t something you’d want to follow, but you can see the twitter page for my region here.
Anyway, here is the code if anyone wants to use/modify it. You’ll need to download the Twitterizer.framework.dll and place it in your opensim/bin folder. Comments and suggestions are appreciated (here on the blog or on channel 15 of Fern Seed Info in ScienceSim!).
//An opensim region module to send a twitter "tweet" update announcing each visitor.
//Visitors can also record comments on channel 15.
//Aaron M. Duffy
//aduffy70@gmail.com
//September 2009
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Timers;
using log4net;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using Twitterizer.Framework;
namespace VisitLoggerModule {
public class VisitLoggerModule : IRegionModule {
Twitter twit = new Twitter("YourTwitterID", "yourpassword");
string twitteraddress = "twitter.com/YourTwitterFeedURL";
Dictionary<string, DateTime> recentvisits = new Dictionary<string, DateTime>();
int blocktime = 3600; //If an avatar re-visits within this many seconds, do not tweet
int maxcomments = 20; //If we get more comments than this in 24 hours it is probably griefing
int commentstoday = 0;
Timer mytimer = new Timer();
private Scene m_scene;
#region IRegionModule interface
public void Initialise(Scene scene, IConfigSource config) {
m_scene = scene;
}
public void PostInitialise() {
m_scene.EventManager.OnMakeRootAgent += new EventManager.OnMakeRootAgentDelegate(OnVisit);
m_scene.EventManager.OnChatFromClient += new EventManager.ChatFromClientEvent(OnChat);
mytimer.Elapsed += new ElapsedEventHandler(TimerEvent);
mytimer.Interval = 86400000;
mytimer.Start();
}
public void Close(){
}
public string Name{
get { return "VisitLoggerModule"; }
}
public bool IsSharedModule {
get { return false; }
}
#endregion
void OnVisit(ScenePresence presence) {
string visitorname = presence.Firstname + "_" + presence.Lastname;
if (recentvisits.ContainsKey(visitorname)) {
if (DateTime.Now.Subtract(recentvisits[visitorname]).TotalSeconds > blocktime) {
twit.Status.Update("Welcome " + presence.Firstname + " " + presence.Lastname + "!");
recentvisits[visitorname] = DateTime.Now;
}
else {
recentvisits[visitorname] = DateTime.Now;
}
}
else {
twit.Status.Update("Welcome " + presence.Firstname + " " + presence.Lastname + "!");
recentvisits.Add(visitorname, DateTime.Now);
}
}
void OnChat(Object sender, OSChatMessage chat) {
if (chat.Channel != 15)
return;
else if (commentstoday <= maxcomments) {
string sendername = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(chat.SenderUUID).UserProfile.Name;
//There must be a better way to get the avatar's name, but chat.Name returns null...
string firstinitial = sendername.Substring(0,1);
string lastinitial = sendername.Split(' ')[1].Substring(0,1);
twit.Status.Update(firstinitial + lastinitial + ":" + chat.Message);
IDialogModule dialogmod = m_scene.RequestModuleInterface<IDialogModule>();
if (dialogmod != null) {
dialogmod.SendGeneralAlert("Thanks for the feedback! View comments at " + twitteraddress);
commentstoday++;
}
}
else {
IDialogModule dialogmod = m_scene.RequestModuleInterface<IDialogModule>();
if (dialogmod != null)
dialogmod.SendGeneralAlert("Too many comments today. Message not sent.");
}
}
void TimerEvent(object source, ElapsedEventArgs e) {
commentstoday = 0;
}
}
}