Offline Messaging

From OpenSimulator

Jump to: navigation, search

Offline Messaging makes it possible to send IM's to people who are not online.

Instead, the messages are saved to a database and delivered the next time the recipient logs in.

NOTE: Diva Canto has contributed a new Offline Instant Messaging v2 module in 0.7.6 dev revision r/22086 which does not need an external PHP script.

You can find a newer script thats useing mysqli that replace the deprecated mysql commands with PHP 5.5.0 here


Please note that these are third party modules which you use at your own risk!
OpenSimulator takes no responsibility for these modules.

OfflineMessagingModule Configuration Steps

The OfflineMessagingModule is already compiled and ready for use in current versions of OpenSimulator.

However, you will need to setup the "back-end" database and PHP connector scripts to support the OfflineMessagingModule.

  1. Configure the Offline_IM database table in your MySQL using commands in Offline_IM.sql (below)
  2. Upload the mysql.php (below) into your web server
  3. Upload the offline.php (below) into your web server
  4. Enable the OfflineMessagingModule in your OpenSim.ini file

STEP 1: Offline_IM.sql

Save these SQL commands to an Offline_IM.sql file on your MySQL server.

 `uuid` varchar(36) NOT NULL,
 `message` text NOT NULL,
  KEY `uuid` (`uuid`)

Connect to your MySQL (Linux commands shown):

$ mysql --user=$mysqluser --password=$mysqlpassword $databasename

Replace $mysqluser, $mysqlpassword, and $databasename with your specific configuration.

At the mysql prompt, source the Offline_IM.sql file to configure your database to hold offline IMs:

mysql> source Offline_IM.sql
... ensure no error messages appear here ...
mysql> quit

STEP 2: mysql.php

Copy this PHP script to a file called mysql.php and upload the script file to your web server.

No edits of the script should be necessary.

 * Copyright (c) 2007, 2008 Contributors,
 * See CONTRIBUTORS for a full list of copyright holders.
 * See LICENSE for the full licensing terms of this file.
// This looks like its lifted from
// I'd contact the original developer for licensing info, but his website is broken.
class DB
	var $Host = C_DB_HOST;				// Hostname of our MySQL server
	var $Database = C_DB_NAME;			// Logical database name on that server
	var $User = C_DB_USER;				// Database user
	var $Password = C_DB_PASS;			// Database user's password
	var $Link_ID = 0;				// Result of mysql_connect()
	var $Query_ID = 0;				// Result of most recent mysql_query()
	var $Record	= array();			// Current mysql_fetch_array()-result
	var $Row;					// Current row number
	var $Errno = 0;					// Error state of query
	var $Error = "";
	function halt($msg)
		echo("</TD></TR></TABLE><B>Database error:</B> $msg<BR>\n");
		echo("<B>MySQL error</B>: $this->Errno ($this->Error)<BR>\n");
		die("Session halted.");
	function connect()
		if($this->Link_ID == 0)
			$this->Link_ID = mysql_connect($this->Host, $this->User, $this->Password);
			if (!$this->Link_ID)
				$this->halt("Link_ID == false, connect failed");
			$SelectResult = mysql_select_db($this->Database, $this->Link_ID);
				$this->Errno = mysql_errno($this->Link_ID);
				$this->Error = mysql_error($this->Link_ID);
				$this->halt("cannot select database <I>".$this->Database."</I>");
 	function escape($String)
 		return mysql_escape_string($String);
	function query($Query_String)
		$this->Query_ID = mysql_query($Query_String,$this->Link_ID);
		$this->Row = 0;
		$this->Errno = mysql_errno();
		$this->Error = mysql_error();
		if (!$this->Query_ID)
			$this->halt("Invalid SQL: ".$Query_String);
		return $this->Query_ID;
	function next_record()
		$this->Record = @mysql_fetch_array($this->Query_ID);
		$this->Row += 1;
		$this->Errno = mysql_errno();
		$this->Error = mysql_error();
		$stat = is_array($this->Record);
		if (!$stat)
			$this->Query_ID = 0;
		return $this->Record;
	function num_rows()
		return mysql_num_rows($this->Query_ID);
	function affected_rows()
		return mysql_affected_rows($this->Link_ID);
	function optimize($tbl_name)
		$this->Query_ID = @mysql_query("OPTIMIZE TABLE $tbl_name",$this->Link_ID);
	function clean_results()
		if($this->Query_ID != 0) mysql_freeresult($this->Query_ID);
	function close()
		if($this->Link_ID != 0) mysql_close($this->Link_ID);

STEP 3: offline.php

Copy this PHP script to a file called offline.php and upload the script file to your web server.

Edit the $dbName, $dbHost, $dbUser, and $dbPassword lines at the top of the script to match your database and server information.

$dbName = "comunity";
$dbHost = "localhost";
$dbUser = "root";
$dbPassword ="";
define("C_OFFLINE_IM_TBL", "Offline_IM");
$DbLink = new DB;
$method = $_SERVER["PATH_INFO"];
if ($method == "/SaveMessage/")
$start = strpos($msg, "?>");
if ($start != -1)
$msg = substr($msg, $start);
$parts = split("[<>]", $msg);
$to_agent = $parts[12];
$DbLink->query("insert into ".C_OFFLINE_IM_TBL." (uuid, message) values ('" .
mysql_escape_string($to_agent) . "', '" .
mysql_escape_string($msg) . "')");
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?><boolean>true</boolean>";
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?><boolean>false</boolean>";
if ($method == "/RetrieveMessages/")
$parts = split("[<>]", $parms);
$agent_id = $parts[6];
$DbLink->query("select message from ".C_OFFLINE_IM_TBL." where uuid='" .
mysql_escape_string($agent_id) . "'");
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?><ArrayOfGridInstantMessage xmlns:xsi=\"\" xmlns:xsd=\"\">";
while(list($message) = $DbLink->next_record())
echo $message;
echo "</ArrayOfGridInstantMessage>";
$DbLink->query("delete from ".C_OFFLINE_IM_TBL." where uuid='" .
mysql_escape_string($agent_id) . "'");

STEP 4: OfflineMessageModule

Shutdown your simulator.

Edit the OpenSim.ini [Messaging] block.

An example configuration is shown below:

; Control which region module is used for instant messaging.
; Default is InstantMessageModule (this is the name of the core IM module as well as the setting)
InstantMessageModule = InstantMessageModule
; MessageTransferModule = MessageTransferModule
OfflineMessageModule = OfflineMessageModule
OfflineMessageURL = http://yourserver/offline.php
MuteListModule = MuteListModule
MuteListURL = http://yourserver/mute.php
ForwardOfflineGroupMessages = true

P.D: The MuteListModule and URL must be uncommented in order for the offline module to work, even if there is no mute.php file in the web folder.

Once the edits are made, save your OpenSim.ini and restart your simulator.

Using the OfflineMessageModule

Login and try to send a message to an offline person. You should see the message: "System: User is not logged in. Message saved."

If you see "Message not saved." check your web server error log.

If you are using XAMPP or WAMP or other apache based webserver and you get error

messages like, File does not exist: /var/www/offline_im/RetrieveMessages/.

Then you need to enable the module in apache.

You also need to create .htaccess file that's placed inside the directory where you have also the offline php files.

the .htaccess file would look like this.

RewriteEngine On
RewriteCond %{REQUEST_URI}  "!^/index.php$"
RewriteRule "^(.*)$" "index.php" [L]

Check the database Offline_IM table to verify whether or not offline.php has written a record there.

Next time the person you messaged logs in, they will get the message and the database will be updated.

Testing Notes

These steps and configuration tested working on 2013-Jan-13 with:

  • OpenSimulator 0.7.5 r21607 from 2013-Jan-09
  • Nant 0.90
  • Mono 2.10.8
  • MySQL 5.5.28
  • PHP XMLRPC 5.4.10
  • PHP 5.4.1
  • Apache 2.2.22
  • Linux Kernel 3.6.11
  • Fedora Linux 17 (Beefy Miracle)
Personal tools
About This Wiki