WebQuery discussion/help (3.12.0 onwards)

Discuss the new HTTP query method here:

Click here to see a mini tutorial about WebQuery .

How to use:

  • start ts3server with WebQuery enabled ./ts3server query_protocols=raw,ssh,http,https
  • create a universal API key. (BAByFoiEXZfnSJyE6dbXFiW_nn_SdwkclpKNz9j in the example)
    $ nc -q1 localhost 10011 <<EOF
    login serveradmin password
    apikeyadd scope=manage lifetime=0
    EOF
    
    TS3
    Welcome to the TeamSpeak 3 ServerQuery interface, type "help" for a list of commands and "help <command>" for information on a specific command.
    error id=0 msg=ok
    apikey=BAByFoiEXZfnSJyE6dbXFiW_nn_SdwkclpKNz9j id=4 sid=0 cldbid=1 scope=manage time_left=unlimited created_at=1582102492 expires_at=1582102492
    error id=0 msg=ok
    
  • testing the API key
    $ curl -H 'x-api-key: BAByFoiEXZfnSJyE6dbXFiW_nn_SdwkclpKNz9j' 'http://127.0.0.1:10080/gm?msg=Hello+World'
    
    {"status":{"code":0,"message":"ok"}}
    
    $ curl -H 'x-api-key: BAByFoiEXZfnSJyE6dbXFiW_nn_SdwkclpKNz9j' 'http://127.0.0.1:10080/1/channellist?-topic&-icon'
    
    {"body":[{"channel_icon_id":"0","channel_name":"Default Channel","channel_needed_subscribe_power":"0","channel_order":"0","channel_topic":"Default Channel has no topic","cid":"1","pid":"0","total_clients":"1"}],"status":{"code":0,"message":"ok"}}
    
Here is an overview for the scopes and the commands that can be used with these scopes
{ "apikeyadd",                   { manage_scope, } },
  { "apikeydel",                   { manage_scope, } },
  { "apikeylist",                  { manage_scope, } },
  { "banadd",                      { manage_scope, write_scope, } },
  { "banclient",                   { manage_scope, write_scope, } },
  { "bandel",                      { manage_scope, write_scope, } },
  { "bandelall",                   { manage_scope, write_scope, } },
  { "banlist",                     { manage_scope, write_scope, read_scope, } },
  { "bindinglist",                 { manage_scope, read_scope } },
  { "channeladdperm",              { manage_scope, } },
  { "channelclientaddperm",        { manage_scope, } },
  { "channelclientdelperm",        { manage_scope, } },
  { "channelclientpermlist",       { manage_scope, write_scope, read_scope, } },
  { "channelcreate",               { manage_scope, write_scope, } },
  { "channeldelete",               { manage_scope, write_scope, } },
  { "channeldelperm",              { manage_scope, } },
  { "channeledit",                 { manage_scope, write_scope, } },
  { "channelfind",                 { manage_scope, write_scope, read_scope, } },
  { "channelgroupadd",             { manage_scope, write_scope, } },
  { "channelgroupaddperm",         { manage_scope, } },
  { "channelgroupclientlist",      { manage_scope, write_scope, read_scope, } },
  { "channelgroupcopy",            { manage_scope, } },
  { "channelgroupdel",             { manage_scope, } },
  { "channelgroupdelperm",         { manage_scope, } },
  { "channelgrouplist",            { manage_scope, write_scope, read_scope, } },
  { "channelgrouppermlist",        { manage_scope, write_scope, read_scope, } },
  { "channelgrouprename",          { manage_scope, } },
  { "channelinfo",                 { manage_scope, write_scope, read_scope, } },
  { "channellist",                 { manage_scope, write_scope, read_scope, } },
  { "channelmove",                 { manage_scope, write_scope, } },
  { "channelpermlist",             { manage_scope, write_scope, read_scope, } },
  { "clientaddperm",               { manage_scope, } },
  { "clientdbdelete",              { manage_scope, write_scope, } },
  { "clientdbedit",                { manage_scope, write_scope, } },
  { "clientdbfind",                { manage_scope, write_scope, read_scope, } },
  { "clientdbinfo",                { manage_scope, write_scope, read_scope, } },
  { "clientdblist",                { manage_scope, write_scope, read_scope, } },
  { "clientdelperm",               { manage_scope, } },
  { "clientedit",                  { manage_scope, write_scope, } },
  { "clientfind",                  { manage_scope, write_scope, read_scope, } },
  { "clientgetdbidfromuid",        { manage_scope, write_scope, read_scope, } },
  { "clientgetids",                { manage_scope, write_scope, read_scope, } },
  { "clientgetnamefromdbid",       { manage_scope, write_scope, read_scope, } },
  { "clientgetnamefromuid",        { manage_scope, write_scope, read_scope,} },
  { "clientgetuidfromclid",        { manage_scope, write_scope, read_scope, } },
  { "clientinfo",                  { manage_scope, write_scope, read_scope, } },
  { "clientkick",                  { manage_scope, write_scope, } },
  { "clientlist",                  { manage_scope, write_scope, read_scope, } },
  { "clientmove",                  { manage_scope, write_scope, } },
  { "clientpermlist",              { manage_scope, write_scope, read_scope, } },
  { "clientpoke",                  { manage_scope, write_scope, } },
  { "clientsetserverquerylogin",   { manage_scope, write_scope, } },
  { "clientupdate",                { manage_scope, write_scope, } },
  { "complainadd",                 { manage_scope, write_scope, } },
  { "complaindel",                 { manage_scope, write_scope, } },
  { "complaindelall",              { manage_scope, write_scope, } },
  { "complainlist",                { manage_scope, write_scope, read_scope, } },
  { "custominfo",                  { manage_scope, write_scope, read_scope, } },
  { "customsearch",                { manage_scope, write_scope, read_scope, } },
  { "customset",                   { manage_scope, write_scope, } },
  { "customdelete",                { manage_scope, write_scope, } },
  { "ftcreatedir",                 not_supported },
  { "ftdeletefile",                not_supported },
  { "ftgetfileinfo",               not_supported },
  { "ftgetfilelist",               not_supported },
  { "ftinitdownload",              not_supported },
  { "ftinitupload",                not_supported },
  { "ftlist",                      not_supported },
  { "ftrenamefile",                not_supported },
  { "ftstop",                      not_supported },
  { "gm",                          { manage_scope, } },
  { "help",                        { manage_scope, write_scope, read_scope, } },
  { "hostinfo",                    { manage_scope, write_scope, read_scope, } },
  { "instanceedit",                { manage_scope, } },
  { "instanceinfo",                { manage_scope, write_scope, read_scope, } },
  { "logadd",                      { manage_scope, write_scope, } },
  { "login",                       not_supported },
  { "logout",                      not_supported },
  { "logview",                     { manage_scope, write_scope, read_scope, } },
  { "messageadd",                  { manage_scope, write_scope, } },
  { "messagedel",                  { manage_scope, write_scope, } },
  { "messageget",                  { manage_scope, write_scope, read_scope, } },
  { "messagelist",                 { manage_scope, write_scope, read_scope, } },
  { "messageupdateflag",           { manage_scope, write_scope, } },
  { "permfind",                    { manage_scope, write_scope, read_scope, } },
  { "permget",                     { manage_scope, write_scope, read_scope, } },
  { "permidgetbyname",             { manage_scope, write_scope, read_scope, } },
  { "permissionlist",              { manage_scope, write_scope, read_scope, } },
  { "permoverview",                { manage_scope, write_scope, read_scope, } },
  { "permreset",                   { manage_scope, } },
  { "privilegekeyadd",             { manage_scope, write_scope, } },
  { "privilegekeydelete",          { manage_scope, write_scope, } },
  { "privilegekeylist",            { manage_scope, write_scope, read_scope, } },
  { "privilegekeyuse",             { manage_scope, write_scope, } },
  { "queryloginadd",               { manage_scope, write_scope, } },
  { "querylogindel",               { manage_scope, write_scope, } },
  { "queryloginlist",              { manage_scope, write_scope, read_scope } },
  { "quit",                        not_supported },
  { "sendtextmessage",             { manage_scope, write_scope, } },
  { "servercreate",                { manage_scope, } },
  { "serverdelete",                { manage_scope, } },
  { "serveredit",                  { manage_scope, write_scope, } },
  { "servergroupadd",              { manage_scope, } },
  { "servergroupaddclient",        { manage_scope, } },
  { "servergroupaddperm",          { manage_scope, } },
  { "servergroupautoaddperm",      { manage_scope, } },
  { "servergroupautodelperm",      { manage_scope, } },
  { "servergroupclientlist",       { manage_scope, } },
  { "servergroupcopy",             { manage_scope, } },
  { "servergroupdel",              { manage_scope, } },
  { "servergroupdelclient",        { manage_scope, } },
  { "servergroupdelperm",          { manage_scope, } },
  { "servergrouplist",             { manage_scope, } },
  { "servergrouppermlist",         { manage_scope, } },
  { "servergrouprename",           { manage_scope, } },
  { "servergroupsbyclientid",      { manage_scope, } },
  { "serveridgetbyport",           { manage_scope, } },
  { "serverinfo",                  { manage_scope, } },
  { "serverlist",                  { manage_scope, } },
  { "servernotifyregister",        not_supported },
  { "servernotifyunregister",      not_supported },
  { "serverprocessstop",           { manage_scope, } },
  { "serverrequestconnectioninfo", { manage_scope, write_scope, read_scope, } },
  { "serversnapshotcreate",        { manage_scope, } },
  { "serversnapshotdeploy",        { manage_scope, } },
  { "serverstart",                 { manage_scope, } },
  { "serverstop",                  { manage_scope, } },
  { "servertemppasswordadd",       { manage_scope, write_scope, } },
  { "servertemppassworddel",       { manage_scope, write_scope, } },
  { "servertemppasswordlist",      { manage_scope, write_scope, read_scope, } },
  { "setclientchannelgroup",       { manage_scope, write_scope, } },
  { "tokenadd",                    { manage_scope, write_scope, } },
  { "tokendelete",                 { manage_scope, write_scope, } },
  { "tokenlist",                   { manage_scope, write_scope, read_scope, } },
  { "tokenuse",                    { manage_scope, write_scope, } },
  { "use",                         not_supported },
  { "version",                     { manage_scope, write_scope, read_scope, } },
  { "whoami",                      { manage_scope, write_scope, read_scope, } },
Here's how to use the native HTTPS support

These parameters are needed to enable the feature.
And you must add your own .pem files to make it work.

query_protocols=https
query_https_ip=0.0.0.0,::
query_https_port=10443
query_https_certificate_file=your_cert.pem
query_https_private_key_file=your_key.pem

This command can be used to create a own certification on Linux .

openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365

2 Likes

I think would be better if the @staff could create a new topic just and only to discuss the new WebQuery API. :smiley:

Cheers

In what language is the library? And is it open souce (and open for contributions)?

This should work but I would prefer if I could override the name of the serveradmin like it is possible with the “use” query command (parameter client_nickname).

/EDIT: Just created another query client on sid=0 and added an api key for that. Now I got the name I wanted :stuck_out_tongue:

Currently it is closed source as it is currently very specific to our needs and only implements the most important for us calls yet. It is written in PHP for the Laravel Framework. But I’m open to make it open source.

Hi,

I started the server with this command:

./ts3server query_protocols=raw,ssh,http,https

But I get this error:

2020-05-02 18:53:37.933269|ERROR |Query | |to use https 'query_https_certificate_file' and 'query_https_private_key_file ' must be specified

Can someone explain me why? How I need to start the server to use https? I want to send with php curl some requests to my server.

Thanks,
JAY

To use https you need to provide a certificate + key. You could either do that, use HTTP (although I’d only advise doing that on an internal network), or setup an HTTPS proxy of some type.

3 Likes

Hmm… Okay…

  1. How I will get the api key?
  2. where I have to install the ssl certificate to use https?
  3. How can I start the server with this parameters using. /ts3server_startscript instead of. /ts3server

Thanks
Jay

I guess you are referring to the bit about “query_https_private_key_file”?
That does not mean an API-key but the private key of the SSL certificate.

You have to provide the certificate itself and the private key that comes with it.

You don’t need to install the certificate itself - You just need to point teamspeak to the certificate file and the corresponding private-key by specifying “query_https_certificate_file” and “query_https_private_key_file” accordingly.

Now on how to obtain one:

  1. You can either buy a certificate for a specific domain
  2. You can just use let’s encrypt to generate a free certificate. For this you will have to setup a webserver for certificate generation/validation. Configuration depends on your OS and preferred webserver.
  3. You can generate a self-signed certificate.

Option 3 will provide you with a free certificate without the need to setup a webserver. However because it is self-signed other clients will not accept it which brings a whole load of issues with it. So I’d suggest against it.

But, luckily, as davinciTS has already pointed out:

Which should be your preferred method anyway if you ask me.
It effectively takes away the hussle to run the query itself via HTTPS and outsources that task to the webserver.

For that to work you will only need a working webserver (preferably on the same machine as the TS-Server) with a valid SSL-Certificate configured that proxies all requests for a certain domain, directory or port directly to the “query endpoint” effectively leaving you with something like this:
[Your PC] <–HTTPS–> [Your Webserver <–HTTP–> The Teamspeak-Query]

And because everything that happens to the right of the webserver is internal traffic anway you don’t need to worry about encrypting it.

4 Likes

Thank you for your detailed explanation. I already have a web server running on the same machine and also SSL certificates for domains. Is that enough? If so, what exactly do I have to do now? Generate the file and store the keys in the file? Can I then start the TeamSpeak server with the parameters? If yes, how do I start the server with . /ts3server_startscript.sh instead of. /ts3server? That would be my last question :slight_smile: )

Then you can use the ts3server in native HTTP mode and use your web server as a proxy for it (as LKNickname says), which I also (speaking purely for myself here) recommend as the better method.

For ts3server_startscript, if I remember you need to edit COMMANDLINE_PARAMETERS= line and add whatever you need in there!

1 Like

Hey guys,

I already asked this in the release note thread, but never got an answer.
Will we get something similar to servernotifyregister? Something with modern technology like ws or sse?

Btw: I always wondered why you not get a client db id on cliententer and clientleft

Thanks for now.
It’s working now. One last question:

  1. I have started the server with the respective parameters (but via http)
  2. I checked if the query works and sent a php cURL request. The server has responded.
  3. The API key also works

Well, it seems to be working. The last question: Is it enough if I send the request to a domain (web server) where an SSL certificate is set up?

Would definitely like to, but no promises/timescales/etc.

(looks at code) Just an omission, I guess. Would that be useful to you?

3 Likes

Oh definitely. When I wrote a ts3 viewer a few years ago I always needed to cache the active id to be able to identify which user left the server. Sometimes this system failed or it could not identify the user left, because the active id was not cached. This was very annoying :slight_smile:

@davinciTS, would be cool in the future a way to disconnect the connection like we can do now in the normal ServerQuery.
Im programming (transfering from the old PHP Framework) a lot of stuff already over the new WebQuery API and the unique thing I miss is precisely the disconnect.

And… After study a little bit, in my opinion reduce the ServerQuery timeout is not a solution at all.

It is something that we can expect really soon? :slight_smile:

Cheers

Hello, everyone.

Should the WebQuery actually replace the old PHP framework?

Is there a documentation somewhere, which parameters are expected to send a message to a client? (For example …)

I cannot do anything with the overview of the scopes. How do the others here proceed as developers?

The php framework is AFAIK not officially developed by TeamSpeak but a (now) former developer.
So the webquery is like the official http query. This however could be used as a new backend for the framework.
Keep in mind they are essentially different.

1 Like

Thanks for the info. But for me, the question still remains, where is the documentation for the API? For example, if I want to send a message to a special client, how do I know which endpoint to use and most importantly, which parameters I have to provide?

There is none at this moment and you can send the most commands with their parameters as in the ServerQuery. Look there is you need to get more details for each available command

1 Like

Take a look in here:

Regarding to the request to do stuff with PHP:

There are code snippets out there how to use PHP’s cURL.

If you run the code locally on the server TeamSpeak runs on, your URL is: http://127.0.0.1:10080

You have to send the generated API key within the header:

$c_header = array( 'Content-Type: application/json', 'Accept: application/json', 'x-api-key: BAByFoiEXZfnSJyE6dbXFiW_nn_SdwkclpKNz9j' );

curl_setopt( $ch, CURLOPT_HTTPHEADER, $c_header );

You will have to add the command to the URL you’re requesting. For example: channellist

$c_url = "http://127.0.0.1:10080/";
$c_url .= "1/channellist";

curl_setopt( $ch, CURLOPT_URL, $c_url );

1/channellist will for example catch all the existing channels for the virtual server (ID 1).

The result should be a serialized JSON string.
You have to decode the string with json_decode().

$result = curl_exec( $ch );
$json = json_decode( $result, true );

As in the example your (parsed) response will be like:

array (
  'body' => 
  array (
    0 => 
    array (
      'channel_icon_id' => '0',
      'channel_name' => 'Default Channel',
      'channel_needed_subscribe_power' => '0',
      'channel_order' => '0',
      'channel_topic' => 'Default Channel has no topic',
      'cid' => '1',
      'pid' => '0',
      'total_clients' => '1',
    ),
  ),
  'status' => 
  array (
    'code' => 0,
    'message' => 'ok',
  ),
)

If the array contains the array body and if status['code'] = 0 the request was successful.
You can now work this one.

You can find the list of available commands in the first post.

(the most serverquery commands are possible to use)

You can add parameters to the command by adding them to the request URL.
(URL-parameters - HTTP GET method)

For example:

$c_url .= "1/clientmove?clid=9&cid=29";

clid and cid are both serverquery parameters.

The serverquery documention will show you which command requires which parameters.

This example would move client ID 9 into channel ID 29 if the user is online.


As written above you will have to do the following steps:

(1) Requesting the client list

$c_url = "http://127.0.0.1:10080/1/clientlist";

(1/ is your server ID and clientlist the command - no parameters needed)

Example array response
array (size=2)
  'body' => 
    array (size=2)
      0 => 
        array (size=5)
          'cid' => string '1' (length=1)
          'clid' => string '3' (length=1)
          'client_database_id' => string '1' (length=1)
          'client_nickname' => string 'Server' (length=6)
          'client_type' => string '1' (length=1)
      1 => 
        array (size=5)
          'cid' => string '37' (length=2)
          'clid' => string '9583' (length=4)
          'client_database_id' => string '3' (length=1)
          'client_nickname' => string 'FakE' (length=4)
          'client_type' => string '0' (length=1)
  'status' => 
    array (size=2)
      'code' => int 0
      'message' => string 'ok' (length=2)

Note: client_type => 0 is a “phsical” client, 1 is a serverquery client

(2) Sending your message

$msg = "Hello,+I've+seen+you+many+times+on+our+server+already.+That's+nice."

$c_url = "http://127.0.0.1:10080/1/sendtextmessage?targetmode=1&target=" . $cid . "&msg=" . $msg;

Note: $cid (client ID) needs to be defined.

You are “going through” your client list and search the client which you wanna send a message.
You can use the cid (client ID) to send him a pre-defined message.

If you wanna identify the client by it’s myTeamSpeakID for example you will have to use the more detailed serverquery command clientinfo.


That’s already more detailed than planned.

However it requires to know the basics to work with PHP and it’s extension cURL.

1 Like
twitch instagram twitter facebook