SinusBot Scripting Engine

1.0.4

registerPlugin

This is the first and only top-level function that should be called in your script, everything else will be done in the function that is passed to it.

registerPlugin(manifest: Manifest, mainFunction: mainFunction)
Parameters
manifest (Manifest) The manifest determines which features are available to the script and contains metadata and variables that will be shown in the web interface.
mainFunction (mainFunction) If the script is activated this function is called when the scripts are loaded. The function receives three parameters, the first one ( sinusbot ) is deprecated and should not be used anymore.
Example
registerPlugin({
    name: 'Demo Script',
    version: '1.0',
    description: 'This example actually does nothing',
    author: 'Author <author@example.com>',
    vars: []
}, function(sinusbot, config) {
    // your code goes here
});

Manifest

Manifest
Parameters
name (string) Short name of your script
author (string) Your name and your email address in the form of: your name <your-email@example.com>
description (string) A longer description - tell the user what exactly your script does
version (string) Start with something like 1.0 and increase it with every release
autorun (boolean?) Set to true, if you want the script to be run on every instance, without the option to disable it.
backends (Array<string>?) Per default scripts will only be available on TS3 instances. If your script supports Discord (or in the future maybe other backends) as well, you have to specify this explicitly by setting this variable to an array containing all backends: backends: ["ts3", "discord"]
enableWeb (boolean?) If your script required own web content, you can set enableWeb to true and put files into the ./scripts/scriptname/html directory. After restart, the script title will be clickable and lead to an index.html inside that html-directory you just created.

From there you have access to the localStorage variables containing the login and may communicate with the bot api from your own pages.

engine (string?) Sets the required engine version (bot version). This uses Semantic Versioning . Example: engine: ">= 0.9.16"
hidden (boolean?) Hides the script from the settings page. Should be used together with autorun.

Hidden scripts can not have variables (vars), since they'd never be shown and thus not configurable.

requiredModules (Array<string>?) Using this, you can define which restricted modules the script wants to use. If it's not allowed via the config, the script will not load at all but instead return an error on startup. If you only optionally use features from restricted modules, don't use this but provide a fallback in your script.
vars (Array<object>?) More information about the usage of variables can be found here .
voiceCommands (Array<string>?) This parameter is only used for the speech recognition feature and may contain one or more strings that are to be detected for the given script. You can find more details on how to use it here: Speech Recognition

mainFunction

mainFunction(sinusbot: object?, config: object, manifest: object)

Type: Function

Parameters
sinusbot (object?) This is deprecated and should not be used anymore.
config (object) Configuration of the plugin that the user set from within the web interface (given you have added anything to the vars field of your script manifest).
manifest (object) Manifest as specified in registerPlugin.

Engine

Engine
Example
var engine = require('engine');
engine.log('Hello from a script!');
Instance Members
getInstanceID()
getBotID()
getBackend()
setInstanceLogLevel(level)
setBotLogLevel(level)
getInstanceLogLevel()
getBotLogLevel()
reloadScripts()
getNick()
setNick(nick)
setDefaultChannelID(channelID)
isRunning()
notify(message)
saveConfig(config)
log(log)
export(obj)
removeAvatar()
setAvatarFromTrack(track)
setDefaultAvatar()
setAvatarFromBanner(bannerName)
setAvatarFromURL(url)
getUsers()
getUserById(id)
getUserByName(name)
setCommandPrefix(prefix)
getCommandPrefix()

Store

Store
Example
var store = require('store');
store.set('foo', 'bar');
Instance Members
set(key, value)
get(key)
unset(key)
getKeys()
getAll()
setGlobal(key, value)
getGlobal(key)
unsetGlobal(key)
getKeysGlobal()
getAllGlobal()
setInstance(key, value)
getInstance(key)
unsetInstance(key)
getKeysInstance()
getAllInstance()

Backend

Backend
Instance Members
connect()
disconnect()
isConnected()
getBotClientID()
getBotClient()
getNick()
getChannelByID(id)
getCurrentChannel()
getChannelByName(name)
getChannelsByName(name)
getChannelCount()
getChannels()
getClients()
getClientByID(id)
getClientByName(name)
getClientByNick(name)
getClientByUniqueID(uniqueID)
getClientByUID(uniqueID)
chat(msg)
createChannel(channelParams)
getServerGroupByID(id)
getChannelGroupByID(id)
getServerGroups()
getChannelGroups()

Media

Media
Instance Members
playURL(url)
getCurrentTrack()
getTrackByID(id)
search(searchString)
enqueue(url)
playAsNext(url)
playNext()
playPrevious()
stop(trackID)
getQueue()
getPlaylists()
getPlaylistByID(id)
getActivePlaylist(id)
removeFromQueue(index)
clearQueue()
clearPlaylist()
yt(url)
ytdl(url, play)
enqueueYt(url)
enqueueYtdl(url)

Audio

Audio
Instance Members
setAudioFilter(filter)
setAudioReturnChannel(flags)
startRecording()
stopRecording()
streamToServer(url, username, password)
stopStream()
isRepeat()
setRepeat(val)
isShuffle()
setShuffle(val)
getVolume()
setVolume(volume)
getTrackPosition()
seek(pos)
isMute()
setMute(mute)
isPlaying()
say(text, locale?)
getClientCount()
setStreamVolume(streamID, volume)

Format

Format
Instance Members
color(text, color)
italic(text)
bold(text)
underline(text)
code(text)

Helpers

Helpers
Instance Members
getRandom(max)
toString(input)
base64Encode(input)
base64Decode(input)
hexEncode(input)
hexDecode(input)
MD5Sum(input)
SHA1Sum(input)
SHA256Sum(input)

Event

Event
Example
var event = require('event');
var engine = require('engine');

event.on('chat', function(ev) {
    engine.log('Got message "'+ev.text +'" from '+ ev.client.name());
})
Instance Members
on(eventName, callback)
emit(eventName, data)
broadcast(eventName, data)
Events
api:$eventName
chat
poke
typing
track
trackInfo
trackEnd
ytdl.success
ytdl.error
connect
connectionFailed
disconnect
clientMove
clientNick
clientVisible
clientInvisible
clientKicked
clientKickedFromChannel
clientIPAddress
clientAway
clientBack
clientRecord
clientRecordStop
clientMute
clientUnmute
clientDeaf
clientUndeaf
serverGroupAdded
serverGroupRemoved
channelCreate
channelUpdate
channelDelete
speech
talkerCount
unload
load
discord:$eventName
ws.connect
ws.close
ws.error
ws.data

APIEvent

This type is passed to the api:$eventName-event, see Event.api:eventName for more.

APIEvent
Instance Members
name()
data()
user()
remoteAddr()

Message

Message
Properties
text (string) : Text of the message
channel (Channel) : Channel (if given) this message has been sent on
client (Client) : Client that sent the message
mode (number) : Number representing the way this message has been sent (1 = private, 2 = channel, 3 = server)

MoveInfo

MoveInfo
Properties
fromChannel (Channel?) : Old channel (or null if the client just got online / changed visibility)
toChannel (Channel?) : New channel (or null if the client just went offline / changed visibility)
client (Client) : Client that was moved
invoker (Client) : Client that invoked the move

Client

Note: if the client is inivisible to the bot, some fields might not be available.

Client
Instance Members
name()
nick()
phoneticName()
id()
uid()
uniqueId()
databaseID()
country()
description()
setDescription(description)
getTotalConnectionsCount()
isSelf()
isRecording()
isMuted()
isDeaf()
isAway()
getServerGroups()
getChannelGroup()
getAwayMessage()
getPing()
getIPAddress()
getOnlineTime()
getIdleTime()
getPacketLoss()
getBytesReceived()
getBytesSent()
getTotalConnections()
getCreationTime()
getChannels()
getAudioChannel()
getURL()
equals(otherClient)
chat(msg)
poke(msg)
ban(time, msg)
kick(msg)
kickFromServer(msg)
kickFromChannel(msg)
addToServerGroup(group)
removeFromServerGroup(id, group)
moveTo(target, password?)
setSubscription(val)
getPlatform()
getVersion()
type()

ClientServergroupEvent

ClientServergroupEvent
Properties
client (client) : Client that has been added / removed
invoker (client) : Client that added client to the group
serverGroup (serverGroup) : Server Group

Channel

Channel
Instance Members
id()
name()
parent()
position()
delete()
moveTo(parent, order)
setName(name)
type()
topic()
setTopic(topic)
description()
setDescription(description)
codec()
setCodec(codec)
codecQuality()
setCodecQuality(quality)
maxClients()
setMaxClients(maxClients)
maxFamilyClients()
setMaxFamilyClients(maxFamilyClients)
isPermanent()
setPermanent(permanent)
isSemiPermanent()
setSemiPermanent(permanent)
isDefault()
isPassworded()
isEncrypted()
setEncrypted(encrypted)
equals(otherChannel)
chat(msg)
getClients()
getClientCount()
setSubscription(val)
update(channelParams)
setChannelGroup(client, channelGroup)
getPermissions()
addPermission(id)

ChannelParams

Used to update or create a channel; When creating a channel parent and name are mandatory for TS3; When updating a channel parent will be ignored (use moveTo instead)

ChannelParams
Properties
name (string) : Displayname of the channel; mandatory on create
parent ((Channel | number | string)) : Parent channel (you can also use the channelId); ignored on update, mandatory on create
description (string)
topic (string)
password (string)
codec (number) : See codec types for explanation
codecQuality (number)
encrypted (boolean) : True by default
permanent (boolean)
semiPermanent (boolean)
position (number)
maxClients (number) : Set to -1 for unlimited clients
maxFamilyClients (number)
default (boolean) : Whether the channel is the default channel
neededTalkPower (number) : TS only; 0.9.19+
deleteDelay (number) : TS only; 0.9.19+
icon (number) : TS only; 0.9.19+

ServerGroup

ServerGroup
Instance Members
id()
name()
icon()
addClientByDatabaseId(client)
getPermissions()
addPermission(id)

ChannelGroup

ChannelGroup
Instance Members
id()
name()
icon()
getPermissions()
addPermission(id)

User

User
Instance Members
id()
name()
privileges()
tsUid()
tsGroupId()
isAdmin()
setPassword(password)
setTSUid(tsUid)
setPrivileges(privileges)
addPrivilege(privilege)
removePrivilege(privilege)
delete()

Permission

handles channel, channelgroup and servergroup permissions; mainly for TS3

Permission
Version: 0.13.37
Instance Members
id()
name()
value()
skip()
negated()
setNegated(value)
setSkip(value)
setValue(value)
save()
delete()

Track

Track
Instance Members
id()
url()
type()
title()
artist()
tempTitle()
tempArtist()
album()
genre()
duration()
trackNumber()
thumbnail()
filename()
play()
enqueue()
setThumbnailFromURL(url)
removeThumbnail()

Playlist

Playlist
Instance Members
id()
name()
getTracks()
setActive()

PlaylistTrack

Track in a Playlist

PlaylistTrack
Instance Members
title()
artist()
album()
url()
play()

Bytes

Bytes
Version: 0.9.16
Instance Members
toString()

Http

Http
Instance Members
simpleRequest(config, callback)
simpleRequestCallback(error?, response?)

ConnectParams

ConnectParams
Version: 0.9.16
Properties
host (string?) : Host to connect to; required for mysql / postgres
port (number?) : Port to use
url (string?) : WebSocket URL to use
protocol (string?) : can be udp, tcp or ws (websocket)

NetClient

NetClient
Version: 0.9.16
Instance Members
write(bytes, format?)
on(event, callback)
close()
Events
data
close
error

Net

The net module is protected, it needs the following entry per script in your config.ini:

[Scripts.Privileges]
scriptname = ["net"]
Net
Version: 0.9.16
Example
var net = require('net');
var engine = require('engine');
var conn = net.connect({ host: '127.0.0.1', port: 80 }, function(err) {
    if (err) { engine.log(err); }
});
conn.on('data', function(x) {
    engine.log('got data');
    engine.log(x.toString());
})
if (conn) conn.write("GET / HTTP/1.1\r\nHost: localhost\r\n\r\n");
Instance Members
connect(params, callback)
connectCallback(error?)

DBParams

DBParams
Version: 0.9.16
Properties
driver (string) : Database driver to use, currently sqlite3 (currently in-memory only), mysql or postgres
host (string?) : Database server to connect to, required for mysql / postgres
username (string?)
password (string?)
port (number?)

connect

connect(params: DBParams, callback: function): DBConn?
Parameters
params (DBParams) Connection parameters
callback (function) Callback gets called on success / error; If an error occured, exactly one parameter containing the error will be handed to the callback
Returns
DBConn?: Database connection or null if failed

DBConn

DBConn
Version: 0.9.16.4
Instance Members
query(queryString, parameter1, parameter2, callback)
exec(queryString, parameter1?, parameter2?, callback?)
queryCallback(error?, result?)

DB

The database module is protected, it needs the following entry per script in your config.ini:

[Scripts.Privileges]
scriptname = ["db"]

Use additional parameters to exec / query whenever you use untrusted/unknown data, as those will automatically be escaped and avoid SQL injection.

DB
Version: 0.9.16.4
Example
var db = require('db');
var engine = require('engine');
var helpers = require('helpers');
var dbc = db.connect({ driver: 'mysql', host: '127.0.0.1', username: 'demo', password: 'blah', database: 'foo' }, function(err) {
    if (err) {
         engine.log(err);
    }
});
if (dbc) dbc.exec("INSERT INTO blah (foo, foo2) VALUES (?, ?)", 'bar', 'bar2');
if (dbc) dbc.query("SELECT * FROM blah", function(err, res) {
    if (!err) {
         res.forEach(function(row) {
             engine.log(helpers.toString(row.foo));
         });
    }
});

WS

Websocket Server: The ws module is protected, it needs the following entry per script in your config.ini:

[Scripts.Privileges]
scriptname = ["ws"]
WS
Version: 0.9.20
Example
SinusBot script:
var ws = require('ws');
var engine = require('engine');
var event = require('event');

event.on('ws.connect', function(id) {
    engine.log('new websocket connection; id ' + id);
    ws.broadcast(1, { blubb: 'blubb' });
});
event.on('ws.disconnect', function(id) {
    engine.log('websocket connection disconnected; id ' + id);
});
event.on('ws.data', function(id, type, data) {
    engine.log('ws.data: id ' + id + '; data: ' + data.toString());
    ws.write(id, type, data.toString());
});
Client Side (served html files via the enableWeb script option):
var proto = (window.location.protocol == 'https:') ? 'wss' : 'ws';
var conn = new WebSocket(proto + "://" + document.location.host + "/api/v1/b/" + botId + "/i/" + instanceId + "/ws");
conn.onclose = function (evt) {
console.log('close', evt);
    alert('Closed.');
};
conn.send(JSON.stringify({ type: 'ping' }));
conn.onmessage = function (evt) {
    var data = JSON.parse(evt.data);
};
Instance Members
write(connectionId, messageType, message)
broadcast(messageType, message)
close(connectionId)