Skip to content

Instantly share code, notes, and snippets.

@thorwe
Last active August 27, 2018 22:14
  • Star 3 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save thorwe/8916476 to your computer and use it in GitHub Desktop.
Teamspeak 3 Channel Join Monitor - Lua script
-- written by https://github.com/thorwe aka philosound in the teamspeak forums
-- Installation:
-- Go to your Teamspeak program folder -> plugins -> lua_plugin
-- Create a new folder, rename it to "notifier"
-- Put this init.lua file in the "notifier" folder
-- Adjust user config below to your needs
-- Start Teamspeak, make sure the lua plugin is enabled in options->plugins
-- Enter the plugin settings, enable the notifier script
require("ts3init")
require("ts3defs")
require("ts3errors")
-- user config
local ChannelsToNotify = {
["Jianji"] = {
["Eingangshalle"] = {
--["_anyServerGroup"] = "sound/azuno.wav",
["Guest"] = "sound/azuno.wav"
}
},
["Homebase der KEYBOARD SM4SHERs"] = {
["Allgemeiner Support - Wartebereich"] = {
["_anyServerGroup"] = "sound/beep.mp3"
},
["RDM/VDM - Wartebereich"] = {
["_anyServerGroup"] = "sound/beep.mp3"
},
["Fehler/Bugs - Wartebereich"] = {
["_anyServerGroup"] = "sound/beep.mp3"
},
["Fragen zu Spenden - Wartebereich"] = {
["_anyServerGroup"] = "sound/beep.mp3"
}
}
}
-- /user config
-- Compatibility: Lua-5.1
local function split(str, pat)
local t = {} -- NOTE: use {n = 0} in Lua-5.0
local fpat = "(.-)" .. pat
local last_end = 1
local s, e, cap = str:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(t,cap)
end
last_end = e+1
s, e, cap = str:find(fpat, last_end)
end
if last_end <= #str then
cap = str:sub(last_end)
table.insert(t, cap)
end
return t
end
--[[local function debugPrint(msg)
if type(msg) == "table" then
for k,v in pairs(msg) do
debugPrint(""..k.."="..v..";")
end
else
print(msg)
end
end]]--
local monitorCache = {}
local serverGroupMap = {}
local MODULE_NAME = "notifier"
local function errorNotify(errorCode,serverConnectionHandlerID)
local errorMessage, errorCodeB = ts3.getErrorMessage(errorCode)
if (errorCodeB ~= ts3errors.ERROR_ok) then
errorMessage = "Error getting Error Message: " .. errorCodeB .. " for error code: " .. errorCode
end
local errorCodeC = ts3.logMessage(errorMessage, ts3defs.LogLevel.LogLevel_ERROR, MODULE_NAME, serverConnectionHandlerID)
ts3.printMessage(serverConnectionHandlerID, (MODULE_NAME .. errorMessage), 0)
end
local function checkNotify(serverConnectionHandlerID, clientID, channelID, visibility)
if (visibility == ts3defs.Visibility.LEAVE_VISIBILITY) then return end -- we don't care about leaves
local sMonitorCache = monitorCache[serverConnectionHandlerID]
if (not sMonitorCache) then return end -- we don't care about this server
if (clientID == sMonitorCache.myClientID) then return end -- we don't care about our own moves
local channelConfig = sMonitorCache.channels[channelID]
if (not channelConfig) then return end -- we don't care about this channel
local grps, errorCode = ts3.getClientVariableAsString(serverConnectionHandlerID, clientID, ts3defs.ClientProperties.CLIENT_SERVERGROUPS)
if (errorCode ~= ts3errors.ERROR_ok) then
errorNotify(errorCode,serverConnectionHandlerID)
return
end
grps = split(grps,",")
local sServerGroupMap = serverGroupMap[serverConnectionHandlerID]
local waveFile
for _,v in pairs(grps) do
waveFile = channelConfig[sServerGroupMap[v]]
if (waveFile) then
break
end
end
if (not waveFile) then
waveFile = channelConfig["_anyServerGroup"]
end
if (waveFile ~= nil) then
errorCode = ts3.playWaveFile(serverConnectionHandlerID, waveFile)
if (errorCode ~= ts3errors.ERROR_ok) then
errorNotify(errorCode,serverConnectionHandlerID)
return
end
end
end
local function onConnectStatusChangeEvent(serverConnectionHandlerID, status, errorNumber)
if (status == ts3defs.ConnectStatus.STATUS_CONNECTED) then -- at this point we can get server infos, which is before any onNewChannel Event gets triggered
-- now we check if we connected to a server we're actually want to monitor
local result, errorCode = ts3.getServerVariableAsString(serverConnectionHandlerID, ts3defs.VirtualServerProperties.VIRTUALSERVER_NAME)
if (errorCode ~= ts3errors.ERROR_ok) then
ts3.printMessage(serverConnectionHandlerID, (MODULE_NAME .. ": Error getting server name: " .. errorCode), 0)
return
end
if (ChannelsToNotify[result]) then
local myClientID, errorCode = ts3.getClientID(serverConnectionHandlerID)
if (errorCode ~= ts3errors.ERROR_ok) then
errorNotify(errorCode,serverConnectionHandlerID)
return
end
monitorCache[serverConnectionHandlerID] = {
["name"] = result,
["myClientID"] = myClientID
} -- using the existence of the object later onNewChannelEvent
ts3.printMessage(serverConnectionHandlerID, (MODULE_NAME .. ": Monitoring " .. result), 0)
end
elseif (status == ts3defs.ConnectStatus.STATUS_DISCONNECTED) then
monitorCache[serverConnectionHandlerID] = nil -- clean up
serverGroupMap[serverConnectionHandlerID] = nil
end
end
local function onNewChannelEvent(serverConnectionHandlerID, channelID, channelParentID)
local sMonitorCache = monitorCache[serverConnectionHandlerID]
if (not sMonitorCache) then return end -- since we tested the server name on connect we don't need to get the string everytime, which would be more expensive
local channelName, errorCode = ts3.getChannelVariableAsString(serverConnectionHandlerID, channelID, ts3defs.ChannelProperties.CHANNEL_NAME)
if (errorCode ~= ts3errors.ERROR_ok) then
errorNotify(errorCode,serverConnectionHandlerID)
return
end
local channelConfig = ChannelsToNotify[sMonitorCache.name][channelName]
if (not channelConfig) then return end
if (not sMonitorCache.channels) then sMonitorCache.channels = {} end
sMonitorCache.channels[channelID] = channelConfig
ts3.printMessage(serverConnectionHandlerID, (MODULE_NAME .. ": Monitoring " .. channelName), 0)
end
local function onUpdateChannelEditedEvent(serverConnectionHandlerID, channelID, invokerID, invokerName, invokerUniqueIdentifier)
local sMonitorCache = monitorCache[serverConnectionHandlerID]
if (not sMonitorCache) then return end
if sMonitorCache.channels[channelID] then sMonitorCache.channels[channelID] = nil end -- clear the channel since it was somehow edited
onNewChannelEvent(serverConnectionHandlerID, channelID, 0) -- check for (re)addition; more sophisticated solutions with subchannel sensitivity would need to get the parent channel here
end
local function onClientMoveEvent(serverConnectionHandlerID, clientID, oldChannelID, newChannelID, visibility, moveMessage)
checkNotify(serverConnectionHandlerID, clientID, newChannelID, visibility)
end
local function onClientMoveMovedEvent(serverConnectionHandlerID, clientID, oldChannelID, newChannelID, visibility, moverID, moverName, moverUniqueIdentifier, moveMessage)
checkNotify(serverConnectionHandlerID, clientID, newChannelID, visibility)
end
local function onServerGroupListEvent(serverConnectionHandlerID, serverGroupID, name, groupType, iconID, saveDB)
if (not serverGroupMap[serverConnectionHandlerID]) then serverGroupMap[serverConnectionHandlerID] = {} end
serverGroupMap[serverConnectionHandlerID][tostring(serverGroupID)] = name
end
--[[local function onServerGroupListFinishedEvent(serverConnectionHandlerID)
if (serverGroupMap[serverConnectionHandlerID]) then
debugPrint(serverGroupMap[serverConnectionHandlerID])
end
end]]--
local registeredEvents = {
["onNewChannelEvent"] = onNewChannelEvent,
["onConnectStatusChangeEvent"] = onConnectStatusChangeEvent,
["onClientMoveEvent"] = onClientMoveEvent,
["onClientMoveMovedEvent"] = onClientMoveMovedEvent,
["onServerGroupListEvent"] = onServerGroupListEvent --,
--onServerGroupListFinishedEvent = onServerGroupListFinishedEvent
}
ts3RegisterModule(MODULE_NAME, registeredEvents)
-- test
notifier = {}
notifier.test = function(serverConnectionHandlerID)
onClientMoveEvent(serverConnectionHandlerID,23,0,1,1,"Move It.")
end
@Brunsben
Copy link

Hallo,
können sie mir evtl. dabei helfen das Plugin so anzupassen, das es mich bei usern in den beiden rot makierten Channeln informiert?
https://dl.dropboxusercontent.com/u/18486029/ts3.png

Mit freundlichen Grüßen,
Benjamin Bruns

@thorwe
Copy link
Author

thorwe commented May 10, 2016

Hi,
was auf jeden Fall dafür fehlt, wäre Subchannel Unterstützung.
Werde ich mir übers Wochenende spätestens mal anschauen.

Sorry für die späte Antwort, bekam irgendwie keine Notification
Thorsten Weinz

@JesperTheDane
Copy link

Hi.

This is awesome and exactly what I'm looking for BUT.... I SUCK at the technical things..

What do i need to change if it sould play a sound to my staff when people joins the help channel: "Hvis du skal tale med staff så VENT HER!" ?

@taelon875
Copy link

I am having trouble with this. same as Jesper. it will not play a sound. I made a custom sound and have it named correctly. Where should i put that?

@FallenCookie
Copy link

Hallöchen ^^

Erst einmal großen Dank an dich, für dieses geniale Script! Allerdings habe ich bei der Anpassung an unseren TS leichte Probleme ^^

Könntest du mir eventuell helfen, es anzupassen? :)

Hier der Channel, bei dem man eine Benachrichtigung bekommen muss: http://prntscr.com/bwyt0w (Rot markiert, Name: ╔● Hilfe | Warteraum)

Ich danke dir schon einmal vielmals für deine Zeit und wünsche noch einen angenehmen Abend! ^^

@liveuser1
Copy link

liveuser1 commented Oct 18, 2017

Great, thank you for sharing!
Just 2 things:

  1. Is it possible to monitor client connection to server instead of client joining channel event?
  2. How hard is it to add monitoring users (by user unique ID), not groups?

=======
UPD: figured it out, it can be done with client enter_visibility in onClientMoveEvent.

@consgames
Copy link

Hey, I've configured the script for the server I'm using it on but it won't play sound files, could anyone help please? The configured script:
https://gist.github.com/consgames/41d34d921007817ff633f16fa59c851a

Thanks.

@1cecold
Copy link

1cecold commented Jan 25, 2018

I couldn't get this work with the current version, I set the channel name and server and mp3 file and nothing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment