Skip to content

進階運算式

自訂指令回覆支援安全版 $(eval ...) 與區域變數宣告 $(let name = ...)。它是功能受限的運算語法,不會執行任意 JavaScript,也不能連線到網站或呼叫 Twitch API。

線上測試

可以在這裡使用與 HannyaStudio 自訂指令相同的安全運算式引擎測試結果。Playground 只支援本頁列出的變數、運算子與函式。

立即試算

輸出結果尚無結果

基本用法

text
1 + 2 = $(eval 1 + 2)
text
$(eval {args} == "" ? "請輸入內容" : "你輸入了:" + {args})
text
今天的幸運數字是 $(eval randomInt(1, 100))
text
$(eval choose("大吉", "中吉", "小吉"))

一則回覆最多可以放 4 個區塊,包含 $(let ...)$(eval ...)。任何一個運算式發生錯誤時,該次指令不會送出不完整的訊息。

可用變數

變數內容
{command}本次使用的指令名稱,包含 !
{args}指令後方的完整文字;沒有參數時是空字串。
{user}使用者的 Twitch 顯示名稱。
{user_id}使用者的 Twitch 數字 ID。
{login}使用者的 Twitch ID(login)。

變數會以資料形式交給運算式,不會被當成程式碼執行。例如使用者輸入引號、括號或分號,也只會是普通文字。

字串中的變數名稱不會展開:"{args}" 代表文字 {args};要讀取參數請直接寫 {args}

運算子

  • 數字:+-*/%
  • 比較:<<=>>===!=
  • 邏輯:!&&||
  • 條件:條件 ? 成立時的值 : 不成立時的值
  • 群組:(...)

==!= 會比較型別;文字 "1" 不等於數字 1。除了 + 可以串接文字,其餘數學與大小比較都需要數字。若參數是數字文字,請先使用 number({args})

text
$(eval number({args}) >= 100 ? "達標" : "尚未達標")

數字函式

函式說明
number(value)將數字或數字文字轉成有限數字。
min(a, ...) / max(a, ...)從 1~16 個數字找最小值或最大值。
abs(value)絕對值。
round(value)四捨五入到整數。
floor(value) / ceil(value)無條件捨去/進位到整數。
clamp(value, min, max)把數字限制在指定範圍內。
randomInt(min, max)產生包含上下限的隨機整數。

randomInt 的上下限必須是整數,最大範圍差為 1,000,000。

randomInt 只接受兩個參數,每次呼叫都會重新抽取。若要重用同一次結果,先用 $(let ...) 保存。

本次回覆的區域變數

$(let score = randomInt(0,100)) 會計算一次並把結果保存為 score,宣告區塊本身不輸出文字。後續使用 $(eval score) 顯示結果,或在其他運算式中直接寫 score,不能用 {score} 讀取。

  • 變數只存在於本次回覆;下次觸發指令會重新計算。
  • 必須先宣告再使用,不能重複宣告或重新賦值;值可以是數字、文字、布林值或 null
  • 名稱須以 ASCII 英文字母開頭,後面只能接英文字母、數字或底線,長度為 1~32 個字元,且區分大小寫。
  • 不能使用系統變數名稱(例如 userargs)、函式名稱(例如 randomInt)或 JavaScript 保留字(例如 if)。
  • let 是本功能限定的宣告語法,不代表能執行 JavaScript;仍只能使用本頁支援的運算子與函式。

文字函式

函式說明
string(value)轉成文字;null 會變成空字串。
lower(value) / upper(value)轉成小寫/大寫。
trim(value)移除文字前後空白。
length(value)計算 Unicode 字元數,emoji 算一個字元。
contains(text, search)是否包含指定文字。
startsWith(text, search)是否以指定文字開頭。
endsWith(text, search)是否以指定文字結尾。
before(text, delimiter)取得第一個分隔文字之前的內容;找不到時保留原文字。
after(text, delimiter)取得第一個分隔文字之後的內容;找不到時回傳空字串。

文字比較會區分大小寫。如需忽略大小寫,可以先使用 lowerupper

text
$(eval contains(lower({args}), "hello") ? "Hello!" : "找不到 hello")

beforeafter 可以組合使用。例如從 Twitch 頻道網址取出帳號,並移除網址參數:

text
$(eval before(after(trim({args}), "https://www.twitch.tv/"), "?"))

輸入 https://www.twitch.tv/aumimimi?ref=test 時,結果會是 aumimimi

隨機選擇

choose(value, ...) 可以從 1~16 個值中隨機挑選一個:

text
{user} 今天適合 $(eval choose("唱歌", "打遊戲", "早點睡"))

依數字區間回覆

range(value, 上限1, "回覆1", 上限2, "回覆2", ..., "最後回覆") 可以依同一次取得的數字選擇回覆。從最小上限開始判斷,數字小於或等於該上限時使用對應文字;超過所有上限時使用最後回覆。

例如隨機抽取 0~100,顯示抽到的數字,再依五個區間回覆評語。先用 let 保存為 score,再讀取同一個值,確保數字和評語來自同一次抽樣:

text
$(let score = randomInt(0,100)) {user} 抽到 $(eval score) 分,$(eval range(score,20,"太低了吧",40,"再加油",60,"還可以",80,"不錯","太神啦"))
抽到的數字回覆
0~20太低了吧
21~40再加油
41~60還可以
61~80不錯
81~100太神啦

例如抽到 60,會顯示「測試觀眾 抽到 60 分,還可以」。0~20 有 21 個整數,其他區間各有 20 個,所以五種回覆並非各 20%。如果想讓這五個區間機率相同,將宣告改成 $(let score = randomInt(1,100)) 即可。

如果只需要評語,不顯示數字,可以使用較短的寫法:

text
$(eval range(randomInt(0,100),20,"太低了吧",40,"再加油",60,"還可以",80,"不錯","太神啦"))

第一個參數也可以使用其他數字運算式,例如依觀眾輸入的數字評分:

text
$(eval range(number({args}),20,"太低了吧",40,"再加油",60,"還可以",80,"不錯","太神啦"))

輸入 20 回覆「太低了吧」,輸入 21 回覆「再加油」。第一個區間也涵蓋比第一個上限更低的所有數字;這個寫法不會把輸入限制在 0~100。

  • 支援 2~8 個區間,包含最後回覆;仍須符合每個運算式 160 字元、整則回覆 200 字元的限制。
  • 上限必須直接填有限數字常數,可以是負數或小數,且必須由小到大、不能重複。不能用變數、函式或計算式當上限。
  • 每段回覆和最後回覆都必須是加上引號的文字常數。字串中的 {args} 等變數不會展開,也不能用文字串接式代替。
  • 參數數量、上限順序或回覆格式不正確時,儲存指令會提示錯誤。
  • range() 只回傳選中的文字。若要另外顯示同次抽到的數字,先用 $(let score = randomInt(0,100)) 保存,再讀取 score;另外呼叫 randomInt() 會重新抽取,可能與評語不一致。

限制與不支援項目

  • 自訂指令回覆仍以 200 個 Unicode 字元為上限。
  • 每則回覆最多 4 個區塊(leteval 合計),每個區塊內容最多 160 個字元。
  • 不支援屬性存取、陣列、物件、正規表示式、宣告以外的賦值、迴圈、自訂函式或非白名單函式。
  • 不支援 fetch、網路請求、檔案、環境變數或日期時間。
  • 不支援巢狀 $(eval ...)$(let ...)
  • 除以零、無效數字、未知變數/函式或超過資源限制時,本次訊息不會送出。
  • 運算結果仍會通過系統的封鎖字詞檢查與 Twitch 訊息長度限制。

這項功能只適用於「指令管理 → 自訂指令」的回覆內容;其他事件、模組、贊助與排程訊息不會解析 $(eval ...)$(let ...)