From Second Life Wiki
Jump to navigation Jump to search
KBnote.png Note: Due to licensing issues, all contributions to this wiki have stopped and the articles that we posted are just being maintained. This is one of the projects that has gone further and for updates you are cordially invited to the project page on our wiki.

Web-Related Tree

+-------------+ +-------------+ +---------+ +-----------------------------+ +--------------------------+ | Prowler | | Gremlin | | N2K | | Permanent Primitive URL | | Collaborative Coding | +------+------+ +-------------+ +---------+ +------------+----------------+ +--------------------------+ | | +--------+--------+ +-------------------+-------------------+ | SIM Status | | Population Genetics and Selection | +-----------------+ +-------------------+-------------------+ | +------------+-------------+ | Interactive Bacteria | +--------------------------+


We have gone through some possibilities of extracting data from Second Life and, more recently, a system to centralize messages. Our first exploration was syslog which, albeit a standard of log centralization, it proves to be inflexible and frequently insecure. Newly, it has been replaced with other, more modern counterparts. However, they are still not portable enough, considering that Windows users will be forced to use Cygwin or similar.

Furthermore, we were looking for something that is truly portable. We had something in mind similar to the PUSH feature on modern devices. For users who are unfamiliar with the PUSH feature of modern devices, it is really a rebrand of the good old Fetchmail with a prettier interface. It is not really a PUSH but rather a PULL. Very misleading; very profitable that confusion.

Puns aside, we bottom lined it and wanted a method of delivering a message (a string, if you will) from Second Life to mobile devices regardless where you may find yourself in the world. The applications are numerous, we guess, starting from in-game messaging systems and more advanced features which will be made more concrete by the end of this article page.

After some searches, we stumbled onto something called Prowl, which apparently is a pusher for iOS devices. Behind the scenes though, given their API, any HTTP client capable of doing GET or POST is able to both store messages on the Prowl servers, as well as retrieve them (fetchmail, pretty much).

The system probably work like the following:

  • A computer or a client capable of HTTP, pushes a "message" which can be anything to the Prowl servers.
  • A mobile device (may be a computer as well, why not) after connecting to the Internet, runs a thread in the background that fetches the messages from the Prowl servers. If there is a new message there, it usually pops it up as a notification.

The Prowl name is not incidental, it is in fact an extension to what Macintosh users may know as Growl (another nice rebrand of syslog, meant for end-user applications this time). The latter is used on a computer to send messages across the network. Given multiple machines, it is convenient to have all the notifications centralized on your main working machine. Growls does just that an syslog used to do that back when the giants roamed the earth for massive datacentres.

The YouTube video below is a demonstration using the scripts you will find further on of sending a message from a Second Life primitive to an iPad. For completeness, we use Veency to access the iPad via VNC in order to shoot the clip. The soundtrack is called Corruption by John Molloy (Magnetic Scrolls).

YouTube Video



To use this system in its basic form, you will need to:

  • Sign-up on Prowl with a username and a password.
  • Log-in with the username and password you signed-up with and navigate to Prowl's API Key generator and generate a new API key.
  • If you are on an iDevice, you will need to purchase (or steal, up to you, we don't want to hear about it, nor do we care - we do however recommend purchasing though since you will get proper updates and if you do use this on a regular basis, even combined with Growl, which is free, you will love this application) the Prowl: Growl Client from the AppStore.
  • Log-in to Prowl from your iDevice.
  • Create a new primitive in Second Life and dump the scripts below inside it.
  • Edit the [K] Injector script below and change API_KEY to the key that you generated at Prowl's API Key generator.
  • To test, you can touch the primitive you created and an llTextBox dialog will pop-up (Imprudence users beware, it is still not implemented) which will ask for a message.
  • Type your message and if you followed the previous successfully, you should see that message appear on screen.

Additionally, you may also customize the EVENT, DESCRIPTION and APPLICATION to something that suits your needs. Those fields assume that an application, triggering an event with a description is sending the message. However, given that you are sending this from Second Life, those fields could perhaps be some description of your build, or the location of it, or visitors on your simulator.


The service that Prowl provides by storing your notifications is that you do not have to be connected permanently with your mobile device to the Internet. Whenever your mobile device connects, it will retrieve the messages from Prowl and will even list them in the application.

For iOS5 (we don't know, we gave up on it and back at 4.x) users, this may be even nicer since it will show up in the notification center, making it a pretty good offline messaging system.

Finally, it does not even require a jailbroken device. Everything HTTP, that's the beauty of it...


The Prowl API mentions limitations to be at:

IP addresses are limited to 1000 API calls per hour which begins from the start of the first call.

We do not think that more than that is really necessary and if you do need to take out more than 1000 events per hour, then you probably would want a separate database to store them.

The following limitations apply to the fields:

apikey -> unlimited (well, duh)
application -> 256 characters
event -> 1024 characters
description -> 10000 characters.

As you can see, the system is quite generous: 10000 characters is quite a bit.

Please bear in mind, that the messages should be escaped with llEscapeURL.


Wizardry and Steamworks is not affiliated in any way with Prowl. We believe it is a nice feature! However, bear in mind that this relies on a 3rd party service to store your notifications. We cannot confirm nor deny (nor care, to add some redundant sincerity...) if the folks at prowl do anything dodgy with your data. If your messages are of the utmost privacy (like, if you are one of those peeps without a facebook account), then this is probably not recommended. You document yourself, you decide whom to trust. We just provide the mechanism of using it (the only thing we will ever be interested in).

The calls between LSL and Prowl are done over HTTPS meaning (assuming) that the traffic between the script and Prowl is encrypted.


Only the [K] Prowl script is necessary if you want to integrate this script into a bigger build. The [K] Prowl script listens for linked messages and you can access them by sending a comma-separated list of parameters.

Two parameters are mandatory:

PROWL_API_KEY -> your api key (mandatory)
PROWL_APPLICATION -> some name you want to give to your message (appears as the Title usually) (mandatory)

The remaining two are optional:

PROWL_EVENT -> some event name, anything you wish
PROWL_DESCRIPTION -> this is usually a large portion of text, anything you wish

An example link-message would look like this (assuming that the two scripts are in the same primitive): <lsl> llMessageLinked(LINK_THIS, comChannel, "PROWL_API_KEY,6f5902ac237024bdd0c176cb93063dc4,PROWL_APPLICATION,Prowler,PROWL_EVENT,I got tickled!,PROWL_DESCRIPTION,Stop that!", id); </lsl> which will pop-up something like the following on a device:

|    Prowler     |
| I got tickled! |
|   Stop that!   |

The only observation is that usually the title takes precedence, then the event name and then the message which is usually much longer (may be) than the previous two.

[K] Prowl

This is the actual Prowl module which could be integrated in a larger build.

<lsl> ////////////////////////////////////////////////////////// // [K] Kira Komarov - 2011, License: GPLv3 // // Please see: // // for legal details, rights of fair usage and // // the disclaimer and warranty conditions. // //////////////////////////////////////////////////////////

key kReq = NULL_KEY; list pLoad = [];

default {

   link_message(integer sender_num, integer num, string str, key id) {
       integer cha = ((integer)("0x"+llGetSubString((string)llGetOwner(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
       if(num != cha) return;
       pLoad = [];
       pLoad = llCSV2List(str);
       state notify;
   on_rez(integer num) {


state notify {

   state_entry() {
       string sLoad = "";
       integer itra=llGetListLength(pLoad)-1;
       do {
           string in = llList2String(pLoad, itra);
           if(in == "PROWL_API_KEY") {
               sLoad += "&" + "apikey=";
               sLoad += llEscapeURL(llList2String(pLoad,itra+1));
               jump add;
           if(in == "PROWL_APPLICATION") {
               sLoad += "&" + "application=";
               sLoad += llEscapeURL(llList2String(pLoad,itra+1));
               jump add;
           if(in == "PROWL_EVENT") {
               sLoad += "&" + "event=";
               sLoad += llEscapeURL(llList2String(pLoad,itra+1));
               jump add;
           if(in == "PROWL_DESCRIPTION") {
               sLoad += "&" + "description=";
               sLoad += llEscapeURL(llList2String(pLoad,itra+1));
               jump add;


       } while(--itra>=0);
       kReq = llHTTPRequest("", [HTTP_METHOD,"POST",HTTP_MIMETYPE,"application/x-www-form-urlencoded"], sLoad);
   http_response(key id, integer status, list metadata, string body) {
       if(kReq != id) return;
       state default;

} </lsl>

[K] Injector

This is just a test script that delivers link messages but feel free to expand on it.

Please replace:

                 *                       *                 *                       *
                 |                       |                 |                       |
            your API key          anything under     anything under        anything under 10000
                                  256 characters     1024 characters

in the llMessageLinked call below.

<lsl> ////////////////////////////////////////////////////////// // [K] Kira Komarov - 2011, License: GPLv3 // // Please see: // // for legal details, rights of fair usage and // // the disclaimer and warranty conditions. // //////////////////////////////////////////////////////////

integer comChannel = 0;

default {

   touch_start(integer total_number) {
       comChannel = ((integer)("0x"+llGetSubString((string)llGetOwner(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
       llListen(comChannel, "", llGetOwner(), "");
       llTextBox(llGetOwner(), "\nPlease enter a test-string to broadcast to growl-enabled devices:\n", comChannel);
   listen(integer channel, string name, key id, string message) {
       llMessageLinked(LINK_THIS, comChannel, "PROWL_API_KEY,6f5902ac237024bdd0c176cb93063dc4,PROWL_APPLICATION,Prowler,PROWL_EVENT,Tickled!,PROWL_DESCRIPTION," + message, id);

} </lsl>