Skip to content
Gwyneth Llewelyn edited this page Mar 22, 2023 · 24 revisions

Introduction

The original instructions are minimalistic, they just deal with establishing a connection and exiting a bot.

Except for establishing a connection, the original REST API is as follows:

Call http://your-host-where-RESTbot-lives.com:9080/<command_name>/<session_id>

while on the POST data, you put the actual parameters.

Establishing a connection will give you the <session_id>

Establishing a Connection

using cURL:

curl http://localhost:9080/establish_session/<RESTbot password> -d first=<BotFirstName> -d last=<BotLastName> -d pass=<md5ʼed bot password> -d start=<starting location>

RESTbot password: the default is simply pass. You can (and should!) change it on configuration.xml.

The avatar password is another story. Under OpenSimulator, you can get away with your own generated MD5'ed password; the underlying libraries will add the "$1$" prefix (that properly identifies MD5 encoding as, well, MD5 encoding) and it works fine. Second Life, however, mumbles and grumbles and ultimately refuses to use your MD5'd password. Why that happens is completely beyond my knowledge and understanding.

However, LibreMetaverse has added a neat feature — if a password is passed in plaintext (i.e. not MD5-encoded), then it will go through all proper steps to ensure that the Second Life Grid gets a properly MD5'd password that SL accepts. Weird, but it certainly works! So, if you are unable to login to SL with your MD5'd password, try to use your non-encoded password instead. A safety issue? Sure, if you connect via http and not https to your RESTbot instance. The truth is that MD5 is easily breakable anyway, so encoding a password with MD5 and passing it unencrypted is not really safe these days (it might have been the case in 2003, but today it's reasonably easy to crack.

start allows the avatar to start from its last location using the parameter value last (this is the default starting location), or optionally home (avatar will get rezzed at their previously set home position, if possible) or even using a specially formatted URI (allows teleport to a specific region and point inside that region), such as: Either "last", "home", or a string encoded URI with the body part (like this: uri:hooper&amp;128&amp;152&amp;).

If successful, this call will return a session identification key:

<restbot><success><session_id>5defa00c-1590-410b-a9e1-98066abd5ae4</session_id><key>53d9df15-7d7e-4422-b65f-f7f286d2c54d</key></success></restbot>

If the wrong username or password was sent, you'll get (for Second Life):

<restbot>
	<error fatal="true">Sorry! We couldn't log you in.

Please check to make sure you entered the right

	* Username (like bobsmith12 or steller.sunshine)

	* Password

Also, please make sure your Caps Lock key is off. If you feel this is an error, please contact support@secondlife.com.</error>
</restbot>

(of course, Linden Lab may change the message at any time)

If this bot avatar had already been logged in by RESTbot, it detects that the session already exists, and returns:

<restbot>
	<existing_session>true</existing_session>
	<session_id>aa3c8fad-32fd-4347-8ed8-15026354df71</session_id>
	<key>11817ab3-dafa-4ad7-98cc-0f454910f332</key>
</restbot>

Notes

  • Starting with v8.2.0, the session identification key (session_id) and avatar key (key, a UUID) are also returned.

  • Other errors preventing the session to be instantiated might be possible (not tested as of 20220111!), they're usually returned within <error>...</error> tags.

Exiting

curl http://localhost:9080/exit/<session_id>

where session_id is the session identification key received on the previous call.

Returns

<restbot><disposed>true</disposed></restbot>

Quitting the server (soft kill)

I discovered an Easter Egg 😁 There is a way to shut down the RESTbot server gracefully, using what has been, so far, an undocumented feature, which, however, has been in the code for over a decade.

The server_quit command will first gracefully close all active sessions (if any) and schedule a 'soft' termination of the RESTbot server, once all sessions have logged out successfully.

curl http://localhost:9080/server_quit/<RESTbot password>

Returns

<restbot><status>success - all bot sessions very logged out and a request for queued shutdown</status></restbot>

Caveat

This functionality will only queue the request for server termination; this means that the server, although it will tell all bots to log out, continues to run — until a new request (whatever it might be; can be a simple ping) comes in. Then it shuts the whole application down (i.e. that means you will always need to wait for the next request).

Avatar Plugin

avatar_name

Parameters: key

curl http://localhost:9080/avatar_name/<session_id>/ -d key=d2cdf457-5027-4887-abd8-573c62a85226

Returns

<restbot><name>Gwyneth Llewelyn</name></restbot>

avatar_key

Parameters: name

curl http://localhost:9080/avatar_key/<session_id>/ -d name=Gwyneth%20Llewelyn

Returns

<restbot><key>d2cdf457-5027-4887-abd8-573c62a85226</key></restbot>

avatar_online

Parameters: key

curl http://localhost:9080/avatar_online/<session_id>/ -d key=d2cdf457-5027-4887-abd8-573c62a85226

Returns

<restbot><online>False</online></restbot>

avatar_profile

Parameters: key

curl http://localhost:9080/avatar_profile/<session_id>/ -d key=d2cdf457-5027-4887-abd8-573c62a85226

Returns

<restbot>
	<profile>
		<publish>True</publish>
		<firstlife>
			<text>***

In RL I work for Beta Technologies: https://betatechnologies.info

What should I say more? I'm 40 and in a stable relationship, currently living in Portugal, at Europe's westernmost tip.</text>
			<image>0488b909-b5d7-dd58-fe96-600a801d6c6f</image>
		</firstlife>
		<partner>00000000-0000-0000-0000-000000000000</partner>
		<born>7/31/2004</born>
		<about>I'm accused by immersionists of being an augmentist; and augmentists believe I'm an immersionist. But I'm really just a virtual girl in a virtual world, enjoying this space just like you :)

Second Life mirrors the real life. The good and the bad of it.

Email me at gwyneth.llewelyn@gwynethllewelyn.net

... and in real life, I'm the European Operations Manager for Beta Technologies.

Joaz Janus: A rose by any other name would render so slowly

Distorted image? Well, I'm using a viewer that likes it!</about>
		<charter>Resident</charter>
		<profileimage>71416a9e-25a2-6e95-f96f-31bfb88ea7bc</profileimage>
		<mature>False</mature>
		<identified>True</identified>
		<transacted>True</transacted>
		<url>https://gwynethllewelyn.net/</url>
	</profile>
</restbot> 

avatar_groups

Parameters: key

curl http://localhost:9080/avatar_groups/<session_id>/ -d key=d2cdf457-5027-4887-abd8-573c62a85226

Returns

<restbot>
	<groups>
		<group>
			<name>Fashion Consolidated</name>
			<key>0726f59a-ca0c-9e73-7c1e-075c5242eb5b</key>
			<title>FashConnoisseur</title>
			<notices>True</notices>
			<powers>SendNotices, ReceiveNotices, VoteOnProposal</powers>
			<insignia>349d1efa-176d-9995-a3f2-ffd4f61cc0e3</insignia>
		</group>
		<group>
			<name>Neufreistadt</name>
			<key>1436766e-2212-1062-fe69-f43b0095c890</key>
			<title>Neufreistadter</title>
			<notices>True</notices>
			<powers>18446744073709551615</powers>
			<insignia>31c58113-f7e7-f282-acf8-6265acab8285</insignia>
		</group>
		<group>
		...
		</group>
	</groups>
</restbot>

touch

Attempts to touch a given prim.

Parameters:

  • prim: Prim UUID for 'bot to touch; should be in the same region.
curl http://localhost:9080/touch/<session_id> -d prim=<UUID>

Returns

<restbot><touch>touching 1aeefc47-01b5-4ffc-a593-92f9e6df84b8 (Button)</touch></restbot>

Reaper Plugin

This plugin, originally developed by Pleiades and not documented, attempts to clean up stalled sessions every hour.

Since 8.1.5 it's possible to change some of its settings via the configuration.xml config file, even to turn it off completely (bots will stay in-world 'forever', or at least until LL decides to evict them).

reaper_info

Function unknown. Seems to have no parameters. My guess is that it shows if the Reaper process is running or not.

Stats Plugin

dilation

curl http://localhost:9080/dilation/<session_id>

Returns

<restbot><dilation>0,9987054</dilation></restbot>

where the value is the current sim's dilation.

sim_stat

curl http://localhost:9080/sim_stat/<session_id>

Returns

<restbot>
	<stats>
		<dilation>0,9964779</dilation>
		<inbps>459</inbps>
		<outbps>210</outbps>
		<resentout>0</resentout>
		<resentin>0</resentin>
		<queue>0</queue>
		<fps>45</fps>
		<physfps>44,90754</physfps>
		<agentupdates>2</agentupdates>
		<objects>82</objects>
		<scriptedobjects>2</scriptedobjects>
		<agents>2</agents>
		<childagents>0</childagents>
		<activescripts>20</activescripts>
		<lslips>0</lslips>
		<inpps>31</inpps>
		<outpps>29</outpps>
		<pendingdownloads>0</pendingdownloads>
		<pendinguploads>0</pendinguploads>
		<virtualsize>0</virtualsize>
		<residentsize>0</residentsize>
		<pendinglocaluploads>0</pendinglocaluploads>
		<unackedbytes>106</unackedbytes>
		<time>
			<frame>22.24652</frame>
			<image>0.009069572</image>
			<physics>0.2268104</physics>
			<script>0.1629531</script>
			<other>0.1085776</other>
		</time>
	</stats>
</restbot>

Chat Plugin

say

Sends a message to chat. Any channel can be chosen (default is 0, also known as 'public chat') as well as the chat type: normal, shout or whisper.

Since v8.3.0, this call also includes the ability to use the 'realism' mode, hidden deep in LibreMetaverse, and which attempts to mimic how a human normally types. Default is off (realism=false). charspersecond is by default 3, which, according to the LibreMetaverse developers, is about the average typing time of humans. The 'bot avatar will engage the typing animation during this time (and a viewer with bubbles enabled will see the three dots until the 'bot avatar stops typing).

curl http://localhost:9080/say/<session_id> -d message="I am not yelling" -d channel=0 -d chattype=normal -d realism=true -d charspersecond=3

Returns what was sent in chat (or an error if it failed):

<restbot><say><channel>0</channel><message>I am not yelling</message><chattype>normal</chattype></say></restbot>

instant_message

Sends an instant message to either an avatar name (first name, last name) or an avatar key (UUID).

Note: Truncates message to 1023 bytes (the limit set by Linden Lab).

curl http://localhost:9080/instant_message/<session_id> -d message="Hello there" -d first="Philip" -d last="Linden"
curl http://localhost:9080/instant_message/<session_id> -d message="Hey you" -d key="a2e76fcd-9360-4f6d-a924-000000000003"

Returns what was sent in chat (or an error if it failed):

<instant_message><key>a2e76fcd-9360-4f6d-a924-000000000003</key><message>Hey you</message></instant_message>

Groups Plugin

group_key_activate

Used to set the avatar to an active group, using the group UUID. Returns active group and, in parenthesis, the group's role that is shown on the title.

Can be set to NULL key (00000000-0000-0000-0000-000000000000) to unset group.

curl http://localhost:9080/group_key_activate/<session_id> -d key=150829ee-a295-4ef6-3965-9f5c77ac3b52

Returns

<restbot><active>Beta Technologies (Beta Technologies)</active></restbot>

group_name_activate

Used to set the avatar to an active group, using the group name. Returns active group and, in parenthesis, the group's role that is shown on the title.

curl http://localhost:9080/group_name_activate/<session_id> -d name=Beta%20Technologies

Returns

<restbot><active>Beta Technologies (Beta Technologies)</active></restbot>

group_im

Sends messages in Group IM Chat (on any group the 'bot has joined). Returns just if the message was sent or not.

Parameters are the UUID key for the group and a text message (urlencoded)

curl http://localhost:9080/group_im/<session_id> -d key=<group UUID> -d message="This%20is%20a%20test"

Returns

<restbot><message>message sent</message></restbot>

Inventory Plugin

list_inventory

Returns the whole inventory of this avatar. With an empty key, it starts from the root folder; add a folder key to just list that folder instead.

Parameters: key for the folder where it should start

curl http://localhost:9080/list_inventory/<session_id> -d key=<folder UUID>

Returns

<restbot>
	<inventory>
		<item>
			<name>...</name>
			<itemid>...</itemid>
		</item>
		...
	</inventory>
</restbot>

list_item

Returns information from a single item in the inventory of this avatar.

Parameters: key for the item ID

curl http://localhost:9080/list_item/<session_id> -d key=<item ID>

Returns

<restbot>
	<item>
		<AssetUUID>251ff15a-25c5-ebd7-ea13-c45e4e520f23</AssetUUID>
		<PermissionsOwner>---</PermissionsOwner>
		<PermissionsGroup>---</PermissionsGroup>
		<AssetType>Texture</AssetType>
		<InventoryType>Texture</InventoryType>
		<CreatorID>d2cdf457-5027-4887-abd8-573c62a85226</CreatorID>
		<Description>(No Description)</Description>
		<GroupID>00000000-0000-0000-0000-000000000000</GroupID>
		<GroupOwned>False</GroupOwned>
		<SalePrice>10</SalePrice>
		<SaleType>Not</SaleType>
		<Flags>0</Flags>
		<CreationDate>19-06-2009 18:20:35</CreationDate>
		<LastOwnerID>00000000-0000-0000-0000-000000000000</LastOwnerID>
	</item>
</restbot>

give_item

Transfers a single item from the inventory of this avatar to another avatar.

Parameters:

  • itemID for the item ID to give
  • avatarKey for the recipient's avatar UIID
curl http://localhost:9080/list_item/<session_id> -d itemID=<item ID> -d avatarKey=<avatar UUID>

Returns

<restbot>
	<item>
		<name>BetaTech_OV_RGB</name>
		<assetType>Texture</assetType>
		<itemID>6e89002b-6788-ecc5-c314-95f795b08cd8</itemID>
		<avatarKey>d2cdf457-5027-4887-abd8-573c62a85226</avatarKey>
	</item>
</restbot>

create_notecard

Creates a notecard on the 'bot's inventory with name, text, and optionally an attachment (for some reasons the attachment seems to be broken)

Parameters:

  • name (name for the notecard; if empty, a default name will be selected)
  • notecard (text for the notecard's content; not tested with UTF-8 and special formatting yet)
  • key (itemID for the attachment)
curl http://localhost:9080/create_notecard/<session_id> -d name=<string> -d notecard=<string> -d key=<item UUID>

Returns

<restbot>
	<notecard>
		<ItemID>f2890f40-44ba-d123-0709-ec73ca42f237</ItemID>
		<AssetID>093dea8c-8231-8515-decc-0f13ee0abada</AssetID>
		<name>Notecard name</name>
	</notecard>
</restbot>

Movement Plugin

location

Shows the current region name, the IP and port addresses of that region, and the actual position of the 'bot inside it.

Parameters: none

curl http://localhost:9080/location/<session_id>

Returns

<restbot>
	<location>
		<CurrentSim>Beta Technologies (216.82.45.92:13000)</CurrentSim>
		<Position>103.0242,211.2815,30.03234</Position>
	</location>
</restbot>

Note: The <CurrentSim> parameter includes not only the name, but also the IP address of the simulator, for reasons unknown. Future versions might separate such information with different XML sub-tags, to ease parsing (important for LSL scripts, which might not have good XML parsing ability). There are a few more elements that can be returned, such as the global position, the simulator version that is currently running on this region, and other statistics that are not currently being reported by the Stats Plugin.

goto

Teleports 'bot to a specific simulator and a position (x,y,z) inside that sim. Position coordinates are floats.

Parameters:

  • sim for the simulator name (spaces should work fine if properly quoted)
  • x, y, z Position inside the simulator to teleport to
curl http://localhost:9080/goto/<session_id> -d sim=<string> -d x=<float> -d y=<float> -d z=<float>

Returns

<restbot>
	<teleport>
		<CurrentSim>Beta Technologies (216.82.45.92:13000)</CurrentSim>
		<Position>103.0242,211.2815,30.03234</Position>
	</teleport>
</restbot>

Note: The result is now consistent with the Location plugin. See also the note about the simulator IP address.

moveto

Moves 'bot to the position (x,y,z) inside the current sim. Position coordinates are floats. The movement uses Second Life's own 'autopilot' algorithm to move avatars to a certain position and which is notoriously bad (unless there is a clear line-of-sight to the target) and gets the 'bot easily stuck in corners, etc. To avoid infinite loops, the number of autopilot steps is deliberately set to a certain threshold (currently, 20 'steps'), after which the 'bot stops in its tracks and does not move further. Optionally, the 'bot may be instructed to run (as opposed to walking).

Parameters:

  • x, y, z: Position inside the simulator for the 'bot to move to
  • run: TRUE if the avatar should run towards the destination (default is FALSE)
curl http://localhost:9080/moveto/<session_id> -d x=<float> -d y=<float> -d z=<float> -d run=<boolean>

Returns

<restbot><moveto>12.55, 125.43, 20.0</moveto></restbot>

moveto-avatar

Moves 'bot to the position of another avatar inside the current region, and stops when within a certain distance. The movement uses Second Life's own 'autopilot' algorithm to move avatars to a certain position; see comment on autopilot for moveto. Optionally, the 'bot may be instructed to run (as opposed to walking).

Parameters:

  • avatar: Avatar name (inside the same region) for the 'bot to move to
  • run: TRUE if the avatar should run towards the destination (default is FALSE)
curl http://localhost:9080/moveto-avatar/<session_id> -d avatar=<string> -d run=<boolean>

Returns

<restbot><moveto-avatar>12.55, 125.43, 20.0</moveto-avatar></restbot>

follow

Attempts to follow another avatar (can be a 'bot, too), specified by its name, keeping a certain distance.

The movement uses Second Life's own 'autopilot' algorithm to move avatars to a certain position; see comment on autopilot for moveto.

Parameters:

  • target: Avatar name to follow (should start in the current region); if empty or set to off, the 'bot stops following the currently selected target.
curl http://localhost:9080/follow/<session_id> -d target=<string>

Returns

<restbot><follow>on</follow></restbot>

siton

Attempts to sit the 'bot on a given prim.

Parameters:

  • target: Prim UUID for 'bot to sit on; should be in the same region.
  • force: Optionally force the avatar to sit on a known, existing prim. Boolean, default FALSE.
curl http://localhost:9080/siton/<session_id> -d target=<UUID> -d force=<boolean>

Returns

<restbot><siton>sitting on 44f73cfb-e424-4e4d-85b8-c516a5ed24f6 (Chair)</siton></restbot>

Note: The function will, by default (force=false), check the bot avatar interest list first before allowing the avatar to sit on the prim. However, if the interest list is empty, or the avatar is not looking towards the prim where it's going to sit upon, this operation may fail. Using force=true will get the avatar to sit on the desired prim (so long as it exists, obviously).

stand

Attempts to make the 'bot stand up (from either sitting on a prim or on the ground).

Parameters: none

curl http://localhost:9080/stand/<session_id>

Returns

<restbot><stand>standing</stand></restbot>

Prims Plugin

Contributed by @otakup0pe

nearby_prims

Gets a list of primitives in the neighbourhood of the 'bot, in a certain radius.

Parameters:

  • type (it will do a partial search on the prim name; leave empty to retrieve all prims; it's case-sensitive)
  • radius (in meters around the avatar)
curl http://localhost:9080/nearby_prims/<session_id> -d type=<string> -d radius=<float>

Returns

<restbot>
	<nearby_prims>
		<prim>
			<name>{0}</name>
			<pos>{1},{2},{3}</pos>
		</prim>
	</nearby_prims>
</restbot>