Examples
Complete, ready-to-use scripts organized by complexity. Copy any of these into a new script in the Rebind UI to get started.
Beginner
Logger
Logs all input events without modifying them. Great for understanding what key names Rebind uses and debugging your own scripts.
-- rebind: name=Input Logger
function OnDown(key)
Log.Info("DOWN: " .. key)
return true
end
function OnUp(key, duration)
Log.Info("UP: " .. key .. " (held " .. duration .. "ms)")
return true
end
function OnScroll(delta)
Log.Info("SCROLL: " .. delta)
return true
end
Key Remap
Simple global key remap. Block the original key, send a different one. Useful for Vim users or anyone who never uses CapsLock.
-- rebind: name=CapsLock to Escape
function OnDown(key)
if key == "CapsLock" then
HID.Down("Escape")
return false
end
return true
end
function OnUp(key)
if key == "CapsLock" then
HID.Up("Escape")
return false
end
return true
end
Scroll Zoom
Hold a modifier key and scroll to zoom. Works in browsers, editors, image viewers, and most desktop apps.
-- rebind: name=Scroll Zoom
local cfg = UI.Schema({
modifier = UI.Keybind("RAlt", { label = "Modifier Key" }),
})
function OnScroll(delta)
if Input.IsDown(cfg.modifier) then
HID.Down("LCtrl")
HID.Scroll(delta)
HID.Up("LCtrl")
return false
end
return true
end
Clipboard Paste
Paste multi-line text with a single hotkey. Demonstrates Clipboard.Set with combo syntax for reliable bulk text input.
-- rebind: name=Quick Paste
local cfg = UI.Schema({
hotkey = UI.Keybind("F8", { label = "Paste Key" }),
text = UI.Text("Hello World", { label = "Text to Paste", maxLength = 500 }),
})
Bind(cfg.hotkey, Async(function()
Clipboard.Set(cfg.text)
HID.Press("LCtrl+V")
end))
Media Keys
Remap Mouse4/Mouse5 to media controls. Only active on the desktop – passes through normally inside other apps.
-- rebind: name=Mouse Media Keys
local cfg = UI.Schema({
enabled = UI.Toggle(true, { label = "Enable" }),
})
function OnDown(key)
if not cfg.enabled then
return true
end
if key == "Mouse4" then
HID.Down("MediaPrev")
return false
end
if key == "Mouse5" then
HID.Down("MediaNext")
return false
end
return true
end
function OnUp(key)
if key == "Mouse4" then
HID.Up("MediaPrev")
return false
end
if key == "Mouse5" then
HID.Up("MediaNext")
return false
end
return true
end
Intermediate
Expander
Type abbreviations and have them expanded into full text. Triggered by a hotkey after typing the shortcut.
-- rebind: name=Text Expander
local cfg = UI.Schema({
trigger = UI.Keybind("F8", { label = "Expand Key" }),
email = UI.Text("user@example.com", { label = "Email Address", maxLength = 60 }),
sig = UI.Text("Best regards,", { label = "Signature", maxLength = 100 }),
})
local snippets = {}
function OnStart()
snippets = {
["@@"] = cfg.email,
["##"] = cfg.sig,
["/date"] = os.date("%Y-%m-%d"),
["/time"] = os.date("%H:%M"),
}
end
local buffer = ""
function OnDown(key)
if key == cfg.trigger then
for abbr, expansion in pairs(snippets) do
if buffer:sub(-#abbr) == abbr then
-- erase the abbreviation
Run(function()
for i = 1, #abbr do
HID.Press("Backspace")
Sleep(20)
end
HID.Type(expansion, 15)
end)
buffer = ""
return false
end
end
return false
end
-- track typed characters
if #key == 1 then
buffer = buffer .. key
if #buffer > 20 then
buffer = buffer:sub(-20)
end
elseif key == "Backspace" and #buffer > 0 then
buffer = buffer:sub(1, -2)
elseif key == "Space" or key == "Enter" then
buffer = ""
end
return true
end
Audio Feedback
Play sound effects on key events. Useful for toggle confirmations, cooldown timers, or just making your macros feel responsive.
-- rebind: name=Audio Feedback
local cfg = UI.Schema({
toggle = UI.Keybind("F8", { label = "Toggle Key" }),
volume = UI.Slider(0.5, { min = 0, max = 1, label = "Volume" }),
})
local active = false
Bind(cfg.toggle, function()
active = not active
if active then
Audio.Play("on.wav", { volume = cfg.volume })
else
Audio.Play("off.wav", { volume = cfg.volume })
end
end)
function OnBlur()
Audio.StopAll()
end
function OnStop()
Audio.StopAll()
end
Chat Filter
Use Regex to detect patterns in window titles or process names. This example applies different behavior depending on which chat app is active.
-- rebind: name=Chat Filter
local chat_apps = [[discord|slack|teams|telegram]]
local cfg = UI.Schema({
paste_key = UI.Keybind("F9", { label = "Quick Paste" }),
message = UI.Text("", { label = "Message", maxLength = 200 }),
})
Bind(cfg.paste_key, Async(function()
local win = System.Window()
if not Regex.IsMatch(win.process, chat_apps) then
return true
end
Clipboard.Set(cfg.message)
HID.Press("LCtrl+V")
end))
Config-Driven Script
Load settings from a TOML file instead of hardcoding them. Users can edit the config file with any text editor without touching the script.
-- rebind: name=Config Demo
-- default config written on first run
local defaults = {
sensitivity = 0.8,
enabled = true,
weapon = "ak47",
keybinds = { toggle = "F8", reload = "F5" },
}
-- load or create config
local cfg
if File.Exists("settings.toml") then
cfg = Config.ReadTOML("settings.toml")
else
Config.WriteTOML("settings.toml", defaults)
cfg = defaults
end
Log.Info("Loaded config: weapon=" .. cfg.weapon .. " sensitivity=" .. tostring(cfg.sensitivity))
Bind(cfg.keybinds.toggle, function()
cfg.enabled = not cfg.enabled
Config.WriteTOML("settings.toml", cfg)
Log.Info("Enabled: " .. tostring(cfg.enabled))
end)
Photoshop
Custom brush size shortcuts that only activate when Photoshop is in the foreground. Completely inert otherwise – zero overhead.
-- rebind: name=Photoshop Shortcuts
-- rebind: process=Photoshop.exe
local cfg = UI.Schema({
brush_step = UI.Slider(5, { min = 1, max = 20, label = "Brush Size Step" }),
})
function OnFocus()
Log.Info("Photoshop detected -- shortcuts active")
end
function OnScroll(delta)
-- alt+scroll to change brush size
if Input.IsDown("LAlt") then
local steps = cfg.brush_step
Run(function()
for i = 1, steps do
if delta > 0 then
HID.Press("RightBrace")
else
HID.Press("LeftBrace")
end
Sleep(10)
end
end)
return false
end
return true
end
function OnDown(key)
-- mouse4 = undo, mouse5 = redo
if key == "Mouse4" then
Run(function() HID.Press("LCtrl+Z") end)
return false
end
if key == "Mouse5" then
Run(function() HID.Press("LCtrl+LShift+Z") end)
return false
end
return true
end
Browser Tabs
Navigate browser tabs with mouse side buttons. Works with Chrome, Firefox, Edge, and most Chromium-based browsers.
-- rebind: name=Browser Tab Nav
-- rebind: process=chrome.exe
-- rebind: process=firefox.exe
-- rebind: process=msedge.exe
-- rebind: process=brave.exe
function OnDown(key)
-- mouse4 = previous tab, mouse5 = next tab
if key == "Mouse4" then
Run(function() HID.Press("LCtrl+PageUp") end)
return false
end
if key == "Mouse5" then
Run(function() HID.Press("LCtrl+PageDown") end)
return false
end
-- middle-click scroll wheel = close tab
if key == "Mouse3" and Input.IsDown("LAlt") then
Run(function() HID.Press("LCtrl+W") end)
return false
end
return true
end
Sticky Mod
Turn any key into a toggle instead of a hold. Tap Shift once and it stays “held” until you tap it again. Useful for accessibility or one-handed workflows.
-- rebind: name=Sticky Modifier
local cfg = UI.Schema({
target = UI.Keybind("LShift", { label = "Modifier to Toggle" }),
})
local held = false
function OnDown(key)
if key == cfg.target then
held = not held
if held then
HID.Down(cfg.target)
UI.Notify("Modifier locked", "info")
else
HID.Up(cfg.target)
UI.Notify("Modifier released", "info")
end
return false
end
return true
end
function OnUp(key)
if key == cfg.target then
return false
end
return true
end
function OnBlur()
if held then
held = false
HID.Up(cfg.target)
end
end
Precision
Hold a key to temporarily slow down mouse movement for fine positioning. Great for image editing, CAD, or any precision work.
-- rebind: name=Precision Mouse
local cfg = UI.Schema({
hold_key = UI.Keybind("Mouse3", { label = "Precision Key" }),
slowdown = UI.Slider(25, { min = 5, max = 75, suffix = "%", label = "Speed" }),
})
function OnMove(dx, dy)
if Input.IsDown(cfg.hold_key) then
local factor = cfg.slowdown / 100
HID.Move(dx * factor, dy * factor)
return false
end
return true
end
Mouse Inversion
Invert mouse axes. Swallows the original input and sends the negated version. Remove one negation to invert only horizontal or vertical.
-- rebind: name=Mouse Invert
-- rebind: mouse_block=true
function OnMove(dx, dy)
HID.Move(-dx, -dy)
return false
end
Sequence
Demonstrates sequential actions with Run() and Sleep(), plus cancellation. A general pattern for multi-step automation.
-- rebind: name=Sequence Demo
local cfg = UI.Schema({
start_key = UI.Keybind("F9", { label = "Start Sequence" }),
})
local task = nil
function OnDown(key)
if key == cfg.start_key then
task = Run(function()
Log.Info("Starting sequence...")
HID.Press("LCtrl+A") -- select all
Sleep(200)
HID.Press("LCtrl+C") -- copy
Sleep(200)
HID.Press("End") -- move to end
Sleep(100)
HID.Press("Enter")
HID.Press("Enter")
Sleep(100)
HID.Press("LCtrl+V") -- paste
Log.Info("Sequence complete!")
end)
return false
end
if key == "F10" and task and task:IsRunning() then
task:Cancel()
UI.Notify("Cancelled", "info")
return false
end
return true
end
function OnStop()
if task and task:IsRunning() then
task:Cancel()
end
end
Advanced
UI Widgets
Demonstrates all available UI widgets and layout options.
-- rebind: name=UI Showcase
local cfg = UI.Schema({
enabled = UI.Toggle(true, { label = "Enable Feature" }),
strength = UI.Slider(100, {
min = 0,
max = 200,
suffix = "%",
step = 5,
tooltip = "Adjust the strength",
group = "Settings",
}),
hotkey = UI.Keybind("F6", { label = "Toggle Key" }),
mode = UI.Select("Normal", { "Normal", "Fast", "Precise", "Custom" }, {
label = "Operating Mode",
}),
tag = UI.Text("", {
label = "Username",
placeholder = "Enter your name",
maxLength = 20,
}),
sensitivity = UI.Slider(50, {
min = 1,
max = 100,
suffix = "%",
group = "Advanced",
tab = "Controls",
}),
})
function OnStart()
Log.Info("Enabled: " .. tostring(cfg.enabled))
Log.Info("Strength: " .. cfg.strength .. "%")
Log.Info("Mode: " .. cfg.mode)
end
Workflow Hub
A single script that provides different shortcuts for different applications. Demonstrates the power of System.Window() for runtime routing without needing separate scripts for each app.
-- rebind: name=Workflow Hub
local cfg = UI.Schema({
enabled = UI.Toggle(true, { label = "Enable" }),
})
local function isProcess(name)
local win = System.Window()
return win.process:lower():find(name:lower()) ~= nil
end
function OnDown(key)
if not cfg.enabled then
return true
end
-- mouse4/mouse5 do different things per app
if key == "Mouse4" then
if isProcess("Photoshop") then
Run(function() HID.Press("LCtrl+Z") end)
elseif isProcess("chrome") or isProcess("firefox") or isProcess("msedge") then
Run(function() HID.Press("LCtrl+PageUp") end)
elseif isProcess("explorer") then
Run(function() HID.Press("LAlt+Left") end)
else
return true
end
return false
end
if key == "Mouse5" then
if isProcess("Photoshop") then
Run(function() HID.Press("LCtrl+LShift+Z") end)
elseif isProcess("chrome") or isProcess("firefox") or isProcess("msedge") then
Run(function() HID.Press("LCtrl+PageDown") end)
elseif isProcess("explorer") then
Run(function() HID.Press("LAlt+Right") end)
else
return true
end
return false
end
return true
end
Auto-Clicker
A simple auto-clicker that uses Timer.Every instead of a Run/Sleep loop. Demonstrates the timer API and toggle pattern.
-- rebind: name=Auto Clicker
local cfg = UI.Schema({
cps = UI.Slider(5, { min = 1, max = 20, label = "Clicks Per Second" }),
toggle_key = UI.Keybind("F7", { label = "Toggle Key" }),
})
local active = false
local clickTimer = nil
function OnDown(key)
if key == cfg.toggle_key then
active = not active
if active then
local interval = 1000 / cfg.cps
clickTimer = Timer.Every(interval, function()
Run(function() HID.Press("Mouse1", 20) end)
end)
UI.Notify("Auto-clicker ON", "info")
else
if clickTimer then
clickTimer:Cancel()
clickTimer = nil
end
UI.Notify("Auto-clicker OFF", "info")
end
return false
end
return true
end
function OnStop()
if clickTimer then
clickTimer:Cancel()
end
end
function OnBlur()
if active then
active = false
if clickTimer then
clickTimer:Cancel()
clickTimer = nil
end
end
end
Macros
Play pre-defined input sequences with configurable speed. Useful for automating repetitive tasks, form filling, or testing.
-- rebind: name=Macro Demo
local cfg = UI.Schema({
speed = UI.Slider(100, { min = 25, max = 400, suffix = "%", label = "Speed" }),
play_key = UI.Keybind("F9", { label = "Play" }),
stop_key = UI.Keybind("F10", { label = "Stop All" }),
})
-- a keyboard combo macro (explicit format)
local formFill = {
{ action = "press", code = "Tab", holdMs = 30, delay = 100 },
{ action = "type", text = "John Doe", charDelay = 30, delay = 100 },
{ action = "press", code = "Tab", holdMs = 30, delay = 100 },
{ action = "type", text = "john@example.com", charDelay = 30, delay = 100 },
{ action = "press", code = "Tab", holdMs = 30, delay = 100 },
{ action = "press", code = "Tab", holdMs = 30, delay = 100 },
{ action = "press", code = "Enter", holdMs = 50, delay = 0 },
}
function OnDown(key)
if key == cfg.play_key then
local speed = cfg.speed / 100
Macro.Play(formFill, speed, "replace")
UI.Notify("Playing", "info")
return false
end
if key == cfg.stop_key then
Macro.StopAll()
UI.Notify("Stopped", "info")
return false
end
return true
end
function OnStop()
Macro.StopAll()
end
Sidecar Pipe
Communicate with an external Python/Node.js process using shared memory. This lets you bridge Rebind scripts with computer vision, AI models, or any other external tool.
-- rebind: name=Pipe Demo
local pipe = nil
function OnStart()
pipe = Pipe.Open("myapp", { size = 65536 })
Log.Info("Pipe opened: " .. pipe.name)
Timer.Every(10, function()
local msg = pipe:Read()
if msg then
local data = JSON.Parse(msg)
Log.Info("Received command: " .. (data.action or "unknown"))
if data.action == "type" and data.text then
Run(function() HID.Type(data.text, 30) end)
elseif data.action == "press" and data.key then
Run(function() HID.Press(data.key) end)
end
end
end)
end
function OnStop()
if pipe then
pipe:Close()
end
end
The external process connects to the same shared memory region. For example, in Python:
import mmap
import struct
import json
shm = mmap.mmap(-1, 65536, tagname="Local\\Rebind_myapp")
# write to channel B (script's inbox) at offset size/2
offset = 65536 // 2
data = json.dumps({"action": "type", "text": "Hello from Python!"}).encode()
shm.seek(offset)
shm.write(struct.pack('<Q', 1)) # sequence number
shm.write(struct.pack('<I', len(data))) # payload length
shm.write(data)
Macro Recorder
Full macro recording workflow: record input to a file, play it back with configurable speed and smoothing.
-- rebind: name=Macro Recorder
local cfg = UI.Schema({
record = UI.Keybind("F9", { label = "Record / Save" }),
play = UI.Keybind("F10", { label = "Play" }),
stop = UI.Keybind("Escape", { label = "Stop" }),
name = UI.Text("macro", { maxLength = 50 }),
smooth = UI.Toggle(false, { label = "Smooth Playback" }),
speed = UI.Slider(100, { min = 25, max = 400, suffix = "%" }),
})
local isRecording = false
local activeMacro = nil
function OnStart()
File.MkDir("macros")
end
function OnStop()
if isRecording then
Macro.Finish()
end
if activeMacro then
activeMacro:Stop()
end
end
function OnDown(key)
if key == cfg.record then
if isRecording then
local macro = Macro.Finish()
if cfg.smooth then
macro = Math.Spline(macro, 0.5)
end
File.WriteJSON("macros/" .. cfg.name .. ".json", macro)
UI.Notify("Saved", "success")
Audio.Beep()
isRecording = false
else
Macro.Record({ precision = "high" })
UI.Notify("Recording...", "info")
Audio.Beep()
isRecording = true
end
return false
end
if key == cfg.play then
local path = "macros/" .. cfg.name .. ".json"
if File.Exists(path) then
activeMacro = Macro.Play(File.ReadJSON(path), cfg.speed / 100)
UI.Notify("Playing", "info")
else
UI.Notify("Not found", "error")
end
return false
end
if key == cfg.stop and activeMacro then
activeMacro:Stop()
activeMacro = nil
UI.Notify("Stopped", "info")
return false
end
return true
end
function OnBlur()
if activeMacro then
activeMacro:Stop()
activeMacro = nil
end
end
Color Trigger
Click when a target color is detected at the center of the screen. Demonstrates pixel color sampling and polling.
-- rebind: name=Color Trigger
local cfg = UI.Schema({
enabled = UI.Toggle(true),
color = UI.Text("FF0000", { maxLength = 6, label = "Target Color (hex)" }),
tolerance = UI.Slider(20, { min = 0, max = 100 }),
trigger = UI.Keybind("Mouse2", { label = "Hold to Scan" }),
})
local function hexToRgb(hex)
return tonumber(hex:sub(1, 2), 16), tonumber(hex:sub(3, 4), 16), tonumber(hex:sub(5, 6), 16)
end
local function colorDistance(hex1, hex2)
local r1, g1, b1 = hexToRgb(hex1)
local r2, g2, b2 = hexToRgb(hex2)
return math.sqrt((r2 - r1) ^ 2 + (g2 - g1) ^ 2 + (b2 - b1) ^ 2)
end
function OnTick()
if not cfg.enabled then
return
end
if not Input.IsDown(cfg.trigger) then
return
end
local w, h = System.Screen()
local pixel = Screen.GetPixelColor(math.floor(w / 2), math.floor(h / 2))
if colorDistance(pixel, cfg.color) <= cfg.tolerance then
Run(function() HID.Press("Mouse1", 20) end)
end
end
HTTP Remote
Control Rebind from external tools via HTTP. Any program that can send HTTP requests (curl, Python, browser) can trigger actions.
-- rebind: name=HTTP Remote
-- rebind: permission=net
local cfg = UI.Schema({
enabled = UI.Toggle(true),
port = UI.Slider(8080, { min = 1024, max = 65535 }),
})
local server = nil
function OnStart()
server = Net.Listen(cfg.port, function(req)
if req.path == "/click" then
Run(function() HID.Press("Mouse1") end)
return { status = 200, body = "clicked" }
elseif req.path == "/type" and req.body then
Run(function() HID.Type(req.body) end)
return { status = 200, body = "typed" }
elseif req.path == "/move" then
local data = JSON.Parse(req.body)
HID.Move(data.dx or 0, data.dy or 0)
return { status = 200, body = "moved" }
end
return { status = 404, body = "not found" }
end)
Log.Info("Remote control on port " .. cfg.port)
end
function OnStop()
if server then
server:Stop()
end
end
WebSocket Remote
Same idea as HTTP Remote but over a persistent WebSocket connection. The server handles multiple simultaneous clients, broadcasts to all of them, and reacts to messages within a single tick. Use this when you need push events (server → client) or a stable low-latency channel for high-frequency commands.
-- rebind: name=WebSocket Remote
-- rebind: permission=net
local cfg = UI.Schema({
port = UI.Slider(9000, { min = 1024, max = 65535, label = "WS port" }),
})
local server = nil
function OnStart()
server = Net.WSListen(cfg.port, {
OnConnect = function(client)
Log.Info(string.format("client %d connected (%d total)", client.id, server:ClientCount()))
client:Send("welcome " .. client.id)
end,
OnMessage = function(client, payload, is_binary)
local req = JSON.Decode(payload)
if req.t == "click" then
Run(function() HID.Press("Mouse1") end)
client:Send(JSON.Encode({ id = req.id, ok = true }))
elseif req.t == "type" then
Run(function() HID.Type(req.text or "") end)
client:Send(JSON.Encode({ id = req.id, ok = true }))
elseif req.t == "move" then
HID.Move(req.dx or 0, req.dy or 0)
elseif req.t == "broadcast" then
-- forward a message to every connected client
server:Broadcast(payload)
end
end,
OnClose = function(client)
Log.Info(string.format("client %d disconnected", client.id))
end,
})
Log.Info("WebSocket remote listening on ws://0.0.0.0:" .. cfg.port)
end
function OnStop()
if server then
server:Stop()
end
end
Connect from Python with websocket-client:
import json
from websocket import create_connection
ws = create_connection("ws://127.0.0.1:9000")
print(ws.recv()) # "welcome 1"
ws.send(json.dumps({"t": "type", "text": "hello from python"}))
ws.send(json.dumps({"t": "move", "dx": 50, "dy": 0}))
Net.WSListen can expose arbitrary JSON-RPC surfaces — reads (screen pixels,
window state, clipboard, input state), writes (HID commands), and push
subscriptions (mouse position, window changes, input events) all compose
naturally with the same handler pattern shown above. See the WebSocket
performance characteristics in the SDK reference
for throughput and latency bounds.
Twitch Clip Creator
Create Twitch clips on demand with a hotkey. Demonstrates Net.Post for external API calls, Bind with Async for non-blocking execution, and File.Append for logging results.
-- rebind: min_sdk=0.1.0
-- rebind: name=Twitch Clip Creator
-- rebind: permission=net
local cfg = UI.Schema({
trigger = UI.Keybind("F9", { label = "Clip Hotkey" }),
client_id = UI.Text("", { label = "Twitch Client ID", placeholder = "Your Twitch API Client ID" }),
oauth_token = UI.Text("", { label = "OAuth Token", placeholder = "Bearer your_oauth_token" }),
broadcaster_id = UI.Text("", { label = "Broadcaster ID", placeholder = "Your Twitch numeric user ID" }),
clip_cooldown = UI.Slider(5, { min = 1, max = 30, label = "Clip Cooldown", suffix = "sec" }),
})
local lastClipTime = 0
Bind(
cfg.trigger,
Async(function()
local now = System.Time()
local cooldownMs = cfg.clip_cooldown * 1000
if now - lastClipTime < cooldownMs then
UI.Notify("Clip on cooldown", "warning")
return false
end
if not cfg.client_id or not cfg.oauth_token or not cfg.broadcaster_id then
UI.Notify("Missing Twitch credentials", "error")
return false
end
local response =
Net.Post("https://api.twitch.tv/helix/clips", JSON.Stringify({ broadcaster_id = cfg.broadcaster_id }), {
["Client-ID"] = cfg.client_id,
["Authorization"] = cfg.oauth_token,
["Content-Type"] = "application/json",
})
if response.status == 200 then
local clipData = JSON.Parse(response.body)
local clipUrl = clipData.data[1].edit_url:gsub("/edit", "")
UI.Notify("Clip created!", "success")
Log.Info("Clip URL: " .. clipUrl)
File.Append("clips.txt", clipUrl .. "\n")
lastClipTime = now
else
UI.Notify("Clip creation failed", "error")
Log.Error("Clip API Error: " .. response.status)
end
return false
end)
)
Twitch Streamer Toolkit
A comprehensive streaming control panel combining clips, ad breaks, slow mode, and stream markers into a single script. Demonstrates multiple Bind/Async handlers, Net.Patch, shared helper functions, UI groups, and session logging via File.Append.
-- rebind: min_sdk=0.1.0
-- rebind: name=Twitch Streamer Toolkit
-- rebind: permission=net
local cfg = UI.Schema({
-- Credentials
client_id = UI.Text("", {
label = "Twitch Client ID",
placeholder = "Your Twitch API Client ID",
group = "Credentials",
}),
oauth_token = UI.Text("", {
label = "OAuth Token",
placeholder = "Bearer your_oauth_token",
group = "Credentials",
}),
broadcaster_id = UI.Text("", {
label = "Broadcaster ID",
placeholder = "Your Twitch numeric user ID",
group = "Credentials",
}),
moderator_id = UI.Text("", {
label = "Moderator ID",
placeholder = "Moderator's Twitch numeric user ID",
group = "Credentials",
}),
-- Hotkeys
clip_key = UI.Keybind("F9", { label = "Clip Hotkey", group = "Hotkeys" }),
ad_key = UI.Keybind("F10", { label = "Ad Break Hotkey", group = "Hotkeys" }),
slowmode_key = UI.Keybind("F11", { label = "Slow Mode Hotkey", group = "Hotkeys" }),
marker_key = UI.Keybind("F12", { label = "Stream Marker Hotkey", group = "Hotkeys" }),
-- Ad Configuration
ad_length = UI.Select(30, {
30,
60,
90,
120,
150,
180,
label = "Ad Length",
suffix = "sec",
group = "Ad Break",
}),
-- Slow Mode Configuration
slowmode_delay = UI.Slider(5, {
min = 1,
max = 120,
label = "Slow Mode Delay",
suffix = "sec",
group = "Slow Mode",
}),
slowmode_active = UI.Toggle(false, {
label = "Slow Mode Enabled",
group = "Slow Mode",
}),
-- Marker Configuration
marker_desc = UI.Text("", {
label = "Marker Description",
placeholder = "Optional marker description",
group = "Stream Marker",
}),
-- Global Settings
global_cooldown = UI.Slider(5, {
min = 1,
max = 30,
label = "Global Action Cooldown",
suffix = "sec",
group = "General",
}),
})
local lastActionTime = 0
local function isOnCooldown()
local now = System.Time()
local cooldownMs = cfg.global_cooldown * 1000
if now - lastActionTime < cooldownMs then
UI.Notify("Action on cooldown", "warning")
return true
end
lastActionTime = now
return false
end
local function logAction(action, details)
local timestamp = os.date("%Y-%m-%d %H:%M:%S")
local logEntry = string.format("[%s] %s - %s\n", timestamp, action, details or "")
File.Append("stream-session.txt", logEntry)
end
local function checkCredentials()
if not cfg.client_id or not cfg.oauth_token or not cfg.broadcaster_id or not cfg.moderator_id then
UI.Notify("Missing Twitch credentials", "error")
return false
end
return true
end
Bind(
cfg.clip_key,
Async(function()
if isOnCooldown() or not checkCredentials() then
return false
end
local response =
Net.Post("https://api.twitch.tv/helix/clips", JSON.Stringify({ broadcaster_id = cfg.broadcaster_id }), {
["Client-ID"] = cfg.client_id,
["Authorization"] = cfg.oauth_token,
["Content-Type"] = "application/json",
})
if response.status == 200 then
local clipData = JSON.Parse(response.body)
local clipUrl = clipData.data[1].edit_url:gsub("/edit", "")
UI.Notify("Clip created successfully!", "success")
logAction("CLIP_CREATED", clipUrl)
else
UI.Notify("Clip creation failed", "error")
logAction("CLIP_FAILED", "Status: " .. response.status)
end
return false
end)
)
Bind(
cfg.ad_key,
Async(function()
if isOnCooldown() or not checkCredentials() then
return false
end
local response = Net.Post(
"https://api.twitch.tv/helix/channels/commercial",
JSON.Stringify({
broadcaster_id = cfg.broadcaster_id,
length = cfg.ad_length,
}),
{
["Client-ID"] = cfg.client_id,
["Authorization"] = cfg.oauth_token,
["Content-Type"] = "application/json",
}
)
if response.status == 200 then
UI.Notify(cfg.ad_length .. "s Ad Break Started", "success")
logAction("AD_BREAK", tostring(cfg.ad_length) .. " seconds")
else
UI.Notify("Ad Break Failed", "error")
logAction("AD_BREAK_FAILED", "Status: " .. response.status)
end
return false
end)
)
Bind(
cfg.slowmode_key,
Async(function()
if isOnCooldown() or not checkCredentials() then
return false
end
cfg.slowmode_active = not cfg.slowmode_active
local response = Net.Patch(
"https://api.twitch.tv/helix/chat/settings",
JSON.Stringify({
broadcaster_id = cfg.broadcaster_id,
moderator_id = cfg.moderator_id,
slow_mode = cfg.slowmode_active,
slow_mode_wait_time = cfg.slowmode_active and cfg.slowmode_delay or 0,
}),
{
["Client-ID"] = cfg.client_id,
["Authorization"] = cfg.oauth_token,
["Content-Type"] = "application/json",
}
)
if response.status == 200 then
local status = cfg.slowmode_active and "ENABLED" or "DISABLED"
UI.Notify("Slow Mode " .. status, cfg.slowmode_active and "warning" or "info")
logAction("SLOWMODE_" .. status, tostring(cfg.slowmode_delay) .. " seconds")
else
UI.Notify("Slow Mode Toggle Failed", "error")
logAction("SLOWMODE_FAILED", "Status: " .. response.status)
cfg.slowmode_active = not cfg.slowmode_active
end
return false
end)
)
Bind(
cfg.marker_key,
Async(function()
if isOnCooldown() or not checkCredentials() then
return false
end
local response = Net.Post(
"https://api.twitch.tv/helix/streams/markers",
JSON.Stringify({
user_id = cfg.broadcaster_id,
description = cfg.marker_desc or "Stream Marker",
}),
{
["Client-ID"] = cfg.client_id,
["Authorization"] = cfg.oauth_token,
["Content-Type"] = "application/json",
}
)
if response.status == 200 then
UI.Notify("Stream Marker Created", "success")
logAction("STREAM_MARKER", cfg.marker_desc or "Unnamed Marker")
else
UI.Notify("Stream Marker Failed", "error")
logAction("MARKER_FAILED", "Status: " .. response.status)
end
return false
end)
)
Accessibility
Tremor Smoothing
Smooths mouse movement for users with hand tremors. Filters small jittery movements and applies exponential smoothing to larger ones.
-- rebind: name=Steady Hand
local cfg = UI.Schema({
enabled = UI.Toggle(true),
smoothing = UI.Slider(50, {
min = 0,
max = 90,
suffix = "%",
tooltip = "Higher = smoother but more latency",
}),
threshold = UI.Slider(5, {
min = 1,
max = 20,
suffix = "px",
tooltip = "Filter movements smaller than this",
}),
})
local buffer = { x = 0, y = 0 }
function OnMove(dx, dy)
if not cfg.enabled then
return true
end
local magnitude = math.sqrt(dx * dx + dy * dy)
if magnitude < cfg.threshold then
return false
end
local s = cfg.smoothing / 100
buffer.x = buffer.x * s + dx * (1 - s)
buffer.y = buffer.y * s + dy * (1 - s)
HID.Move(buffer.x, buffer.y)
return false
end
function OnBlur()
buffer.x = 0
buffer.y = 0
end
Click Assist
Multiple click modes for users with difficulty clicking or holding. Hold Assist auto-releases after a timer, Toggle Click makes single clicks act as hold toggles, Double Click fires two clicks from one.
-- rebind: name=Click Assist
local cfg = UI.Schema({
enabled = UI.Toggle(true),
mode = UI.Select("Hold Assist", { "Hold Assist", "Toggle Click", "Double Click" }),
hold_time = UI.Slider(500, {
min = 100,
max = 3000,
suffix = "ms",
showIf = "mode:Hold Assist",
}),
double_delay = UI.Slider(50, {
min = 20,
max = 200,
suffix = "ms",
showIf = "mode:Double Click",
}),
})
local toggleState = false
function OnStop()
if toggleState then
HID.Up("Mouse1")
end
end
function OnDown(key)
if key ~= "Mouse1" or not cfg.enabled then
return true
end
if cfg.mode == "Hold Assist" then
Run(function()
HID.Down("Mouse1")
Audio.Beep()
Sleep(cfg.hold_time)
HID.Up("Mouse1")
end)
return false
elseif cfg.mode == "Toggle Click" then
toggleState = not toggleState
if toggleState then
HID.Down("Mouse1")
Audio.Beep()
else
HID.Up("Mouse1")
end
return false
elseif cfg.mode == "Double Click" then
Run(function()
HID.Press("Mouse1", 30)
Sleep(cfg.double_delay)
HID.Press("Mouse1", 30)
end)
return false
end
return true
end
function OnBlur()
if toggleState then
HID.Up("Mouse1")
toggleState = false
end
end
Dwell Click
Click by hovering the cursor in one spot. For users who cannot physically click a mouse button.
-- rebind: name=Dwell Click
local cfg = UI.Schema({
enabled = UI.Toggle(true),
dwell_time = UI.Slider(1000, { min = 300, max = 3000, suffix = "ms" }),
tolerance = UI.Slider(10, { min = 5, max = 50, suffix = "px" }),
click_type = UI.Select("Left Click", { "Left Click", "Right Click", "Double Click" }),
sound = UI.Toggle(true, { label = "Audio Feedback" }),
})
local dwellStart = nil
local dwellPos = { x = 0, y = 0 }
function OnTick()
if not cfg.enabled then
dwellStart = nil
return
end
local pos = Input.GetMousePos()
local dx = pos.x - dwellPos.x
local dy = pos.y - dwellPos.y
local distance = math.sqrt(dx * dx + dy * dy)
if distance > cfg.tolerance then
dwellPos = pos
dwellStart = System.Time()
return
end
if not dwellStart then
dwellStart = System.Time()
return
end
if System.Time() - dwellStart >= cfg.dwell_time then
if cfg.click_type == "Left Click" then
Run(function() HID.Press("Mouse1") end)
elseif cfg.click_type == "Right Click" then
Run(function() HID.Press("Mouse2") end)
elseif cfg.click_type == "Double Click" then
Run(function()
HID.Press("Mouse1", 30)
Sleep(50)
HID.Press("Mouse1", 30)
end)
end
if cfg.sound then
Audio.Beep()
end
dwellStart = nil
end
end
function OnBlur()
dwellStart = nil
end