Offline Instant Messaging with php Mysqli

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.

Contents

Disclaimer

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

STEP 1: offline.sql

Save these SQL commands to an offline.sql file on your MySQL server.
Or copy the sql query to phpmyadmin and after execute the query, go to step 2.

CREATE TABLE `offline` (
  `ID` MEDIUMINT NOT NULL AUTO_INCREMENT,
  `PrincipalID` char(36) NOT NULL DEFAULT '',
  `Message` text NOT NULL,
  `TMStamp` char(14) NOT NULL DEFAULT '',
  PRIMARY KEY  (`ID`),
  KEY `PrincipalID` (`PrincipalID`)
) ENGINE=MyISAM;

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.sql file to configure your database to hold offline IMs:

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

STEP 2: offline.php

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

Open the offline.php file to set the following parameters.
C_DB_HOST, C_DB_DATABASE, C_DB_USER, C_DB_PASS, C_DB_TABLE
Add the required data between the ""

C_DB_HOST = the hostname of the server thats running mysql
C_DB_DATABASE = is the database where the offline table is stored
C_DB_USER = database user you are useing for accesing the offline table
C_DB_PASS = user passwd that belongs to the use that you set in C_DB_USER
C_DB_TABLE = table name for offline. default it's offline.
<?php
 
/* Script based on the code you can find at http://opensimulator.org/wiki/Offline_Messaging 
 * @author: Richardus Raymaker -> http:\\www.simsquaremetaverse.nl
 * @date: 2013-03-23
*/
 
define("C_DB_HOST"      ,"localhost"); 
define("C_DB_DATABASE"  ,""); 
define("C_DB_USER"      ,""); 
define("C_DB_PASS"      ,""); 
define("C_DB_TABLE"     ,"");
 
/*---*/
    function SplitIM($httpRaw)
    {
        $ImHeaderStartFunc = strpos($httpRaw,"?>");
        if ($ImHeaderStartFunc!=-1)
        {
            $ImHeaderStartFunc+=2;
            $httpRawFunc = substr($httpRaw,$ImHeaderStartFunc);
            $ImPartsFunc = preg_split('[<|>]',$httpRaw);
 
            return $ImPartsFunc;
        }    
    }
/*---*/
 
/*----------*/
if (isset($_SERVER["PATH_INFO"]))
{
    $urlPath = $_SERVER["PATH_INFO"];
    $httpRaw = $HTTP_RAW_POST_DATA;
 
    if ($urlPath=="/SaveMessage/")
    {
        $start=strpos($httpRaw,"?>");
        if ($start!=-1)
        {
            $httpRaw=substr($httpRaw,$start+2);
 
            /*Open offline database*/
            $link = mysqli_connect(C_DB_HOST, C_DB_USER, C_DB_PASS, C_DB_DATABASE);
            if (!$link) { die('Connect Error (' . mysqli_connect_errno() . ') '. mysqli_connect_error()); error_log("SaveMessage died"); exit; } 
            mysqli_set_charset($link, "utf8");
 
            /*find toAgent UUID*/
            $ImParts = SplitIM($httpRaw);
            $toAgentID=$ImParts[array_search("toAgentID",$ImParts)+1];
            $TMStamp=$ImParts[array_search("timestamp",$ImParts)+1];
 
            /* Store messgae in database and inform user the message is saved */
            mysqli_query($link,"insert into ".C_DB_TABLE." (PrincipalID, Message, TMStamp) values ('" . mysqli_real_escape_string($link,$toAgentID) . "',
                                                                                                   '" . mysqli_real_escape_string($link,$httpRaw). "',
                                                                                                   '" . mysqli_real_escape_string($link,$TMStamp) . "')");
            echo "<?xml version=\"1.0\" encoding=\"utf-8\"?><boolean>true</boolean>";            
 
            /*Close offline database*/
            mysqli_close($link);      
        }
        else
        {   
            echo "<?xml version=\"1.0\" encoding=\"utf-8\"?><boolean>false</boolean>";
        }    
        exit;   
    } 
 
    if ($urlPath=="/RetrieveMessages/")
    { 
        error_log($httpRaw);
        $ImParts = SplitIM($httpRaw);
        $toAgentID=$ImParts[array_search("Guid",$ImParts)+1];
        error_log($toAgentID);     
 
        /*Open offline database*/
        $link = mysqli_connect(C_DB_HOST, C_DB_USER, C_DB_PASS, C_DB_DATABASE);
        if (!$link) { die('Connect Error (' . mysqli_connect_errno() . ') '. mysqli_connect_error()); error_log("RecieveMessage died"); exit; } 
        mysqli_set_charset($link, "utf8");
 
        $queryresult=mysqli_query($link,"select Message from ".C_DB_TABLE." where PrincipalID='" . mysqli_real_escape_string($link,$toAgentID) . "' ORDER BY ID ASC, TMStamp ASC");        
 
        /* Send offline IM messgaes to user */
        echo "<?xml version=\"1.0\" encoding=\"utf-8\"?><ArrayOfGridInstantMessage xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">";
 
        while ($row =  mysqli_fetch_array($queryresult, MYSQL_NUM)) 
        {
            echo $row[0];
        }
        echo "</ArrayOfGridInstantMessage>"; 
 
        /* Delete message after send it to user */
        $queryresult=mysqli_query($link,"delete from ".C_DB_TABLE." where PrincipalID='" . mysqli_real_escape_string($link,$toAgentID) . "'");
 
        /*Close offline database*/
        mysqli_close($link); 
 
        exit;          
    }     
}  
 
?>

STEP 3: OfflineMessageModule

Shutdown your simulator.

Edit the OpenSim.ini [Messaging] block.

An example configuration is shown below:

[Messaging]
; 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 mod_rewrite.so 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]
General
About This Wiki