-
Notifications
You must be signed in to change notification settings - Fork 2
RESTbot API
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>
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&128&152&
).
If successful, this call will return a session identification key:
<restbot><success><session_id>5defa00c-1590-410b-a9e1-98066abd5ae4</session_id></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)
Other errors preventing the session to be instantiated might be possible (not tested as of 20220111!).
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>
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>
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).
Parameters: key
curl http://localhost:9080/avatar_key/<session_id>/ -d key=d2cdf457-5027-4887-abd8-573c62a85226
Returns:
<restbot><name>Gwyneth Llewelyn</name></restbot>
Parameters: name
curl http://localhost:9080/avatar_key/<session_id>/ -d name=Gwyneth%20Llewelyn
Returns:
<restbot><key>d2cdf457-5027-4887-abd8-573c62a85226</key></restbot>
Parameters: key
curl http://localhost:9080/avatar_online/<session_id>/ -d key=d2cdf457-5027-4887-abd8-573c62a85226
Returns:
<restbot><online>False</online></restbot>
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>
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>
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>
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 a least until LL decides to evict them).
Function unknown. Seems to have no parameters. My guess is that it shows if the Reaper process is running or not.
curl http://localhost:9080/dilation/<session_id>
Returns:
<restbot><dilation>0,9987054</dilation></restbot>
where the value is the current sim's dilation.
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>
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.
curl http://localhost:9080/say/<session_id> -d message="I am not yelling" -d channel=0 -d chattype=normal
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>
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>
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>
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>
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>
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>
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>
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>
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>
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.
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.
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 isFALSE
)
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>
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 isFALSE
)
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>
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 tooff
, the 'bot stops following the currently selected target.
curl http://localhost:9080/follow/<session_id> -d target=<string>
Returns:
<restbot><follow>on</follow></restbot>
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, defaultFALSE
.
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).
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>
Contributed by @otakup0pe
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>