Yoake has a scripting engine that closely follows real mIRC's syntax, applied to Telegram and WhatsApp chats. Opens from Tools > Aliases.../Popups.../Remote... (Script Editor), with four tabs: Aliases, Remote (events), Popups, Variables.
Everything is saved as real .ini files inside userData/scripts/ (aliases.ini,
remote.ini, popups.ini, variables.ini) - also editable with an external
text editor; the "Load..." button in the editor imports an external .ini file into the open tab.
Custom commands, callable as /name:
hello {
say Hi $1
}
aliases.ini you only write name { ... }, NEVER
alias name { ... } - that prefix is required only inside Remote below, where it distinguishes an
alias from an on event.Every event runs BEFORE the corresponding default action (as in real mIRC): it can observe it and, where
indicated, suppress it with haltdef (or stop it entirely with halt, only inside
"on message").
Line visible in chat: as in real mIRC, join/part/kick/
op/deop/topic/nick always show a system line in
chat (e.g. --> Mario has joined, * Mario is now an admin) - regardless of
any script you've written, exactly as mIRC does by default. The script still runs, in addition,
not instead of that line.
on start { ... } (no level, no condition: Yoake has
no access levels and its events don't filter by nick/channel, they always fire), the real mIRC syntax
on *:START:{ ... } is also accepted (with a level and any extra conditions, e.g.
on *:TEXT:*:#channel:{ ... }) - handy for pasting a ready-made mIRC script without translating it
by hand. The level and condition are read and discarded (no real matching against them), only the event name
matters.| Event | When it fires | $nick | $chan | $1-$9 / args | haltdef |
|---|---|---|---|---|---|
on start | Once, when Yoake starts. | You | - | - | no |
on load | When you save/close the Script Editor (scripts get recompiled) - not at startup, unlike real mIRC where "on load" fires when an .mrc file is loaded. | You | - | - | no |
on connect | Successful connection to a network (normal login or QR). | your name | - | - | no |
on connectfail | Failed connection attempt. | You | - | the error message, as separate words | no |
on disconnect | Disconnected from a network (manual with /disconnect, or forced e.g. device unlinked from the phone). | You | - | - | no |
on message | An incoming message (never for your own sent messages). | who wrote it | the channel/group, empty in private | message text | yes (doesn't show the message) - halt does the same and also stops the script |
on notice | Synthetic notification (screenshot, pin, missed call...) - see Notifications and system events for the full list of $noticetype values. | who caused it | where (if known) | the notice text | yes |
on whois | Right before printing the result of /whois - our own addition: real mIRC has no dedicated event, it uses the protocol's numeric RAW events instead (301/311/312/317/318/319...), one per piece of data. Our /whois already returns everything together, so a single event with haltdef makes more sense than faking 5-6 separate raw events. | the person looked up | - | $1 = name, $2 = username, $3 = phone, $4 = on/off/empty (online status, empty if unknown), $5 = bio, $6 = profile photo URL, $7 = read-receipts-seen date (both networks, empty if unknown), $8 = last seen (an exact date, or on Telegram sometimes a vague range like "recently"/"last week"/"last month" when Telegram doesn't give an exact time - empty if unknown or if online right now) | yes - suppresses the default lines, the script redraws them however it likes |
on call | A call (audio or video) is coming in - our own addition: notification only, GramJS/Baileys don't implement the actual audio/video at all, you can't really "answer" from here. See /rejectcall in Commands to decline it (optionally with a message to whoever called). | who's calling | - | $1 = video or audio | yes - suppresses the default "Incoming call" line |
on join | Someone joins a group. | who joined | the group | - | no |
on part | Someone leaves a group. | who left | the group | - | no |
on kick | Someone gets removed from a group. | who removed them | the group | $1 = who was removed | no |
on op | Someone becomes admin of a group (with /op, or because another admin did it). | who became admin | the group | - | no |
on deop | Someone loses admin status (with /deop, or because another admin did it). | who lost admin | the group | - | no |
on nick | A contact/user changes their name - fires in Status and in every open window where it's relevant (a private chat with them, or a group they're part of). | the name BEFORE the change | - | $1 = the new name | no |
on notify | A contact on your Notify list (see Address Book) connects. Fires in that network's Status. | the contact's name | - | - | no |
on unotify | A contact on your Notify list disconnects. | the contact's name | - | - | no |
on invite | Two distinct cases, both covered: (1) you receive a message with a real invite link (t.me/joinchat, t.me/+..., chat.whatsapp.com/...) - the case closest to IRC, the notification arrives BEFORE you join; (2) you were added directly to a new group with no link at all (an admin who has your contact can do this on both networks) - here you find out "after the fact", there's no way to know beforehand. | who sent the link (case 1) or empty (case 2) | who sent the message (case 1) or the group (case 2) | $1 = the link (case 1 only) | no |
on topic | A group's topic/name changes. | - | the group | $1 = the old title | no |
on open | Any window opens (channel, group, query, status, or a @window created with /window). | You | the window's title (for a @window: its name, e.g. @log) | - | no |
on close | Any window closes (same, including @windows). | You | the window's title | - | no |
on queryopen | A private chat (query) opens specifically. | You | - | - | no |
on queryclose | A private chat (query) closes. | You | - | - | no |
on input | Every line sent in any window (command or message), before it's even processed. | You | - | the typed text, as separate words | yes - /halt//haltdef here really do cancel the default send (command or message), as in real mIRC: the script has to send something itself with say/msg if it still wants to send modified text |
on filesent | A /dcc send transfer has finished. | the recipient | - | $1 = file name | no |
on filercvd | An incoming media/document has finished downloading (photo/video/audio/document clicked, or automatically loaded in HTML mode). | - | - | $1 = file name (empty for photo/video/audio) | no |
on videoend | Our own addition (real mIRC never had video) - a video open in the viewer (double click, or /playmedia) finishes playing on its own. The window doesn't close on its own: if the script wants that, it decides with /close $wid. | You | - | - | no |
on sockopen | A sockopen connected successfully - see Commands (Sockets section). | - | - | - | no |
on socklisten | An incoming connection on a socklisten - accept it with sockaccept, otherwise it's lost. | - | - | - | no |
on sockread | Data arrived on an open socket - use sockread to read it, otherwise it stays queued (lost when the next data arrives if not drained). | - | - | - | no |
on sockclose | A socket closed (from the other side, or because the connection failed/dropped) - $sockerr is set if there was an error. | - | - | - | no |
on run | Our addition (real /run never returns output - see Commands, External programs section). A program started with /run has exited. | - | - | $1- = the output (split into words) - $runoutput for the full text, line breaks included | no |
on reaction | Our own addition (real mIRC has no reactions - see /react in Commands). Someone reacts with an emoji to one of your messages or to your Story/Status, on Telegram or WhatsApp. Only fires for reactions that are new/changed since Yoake connected, not for reactions already present on old messages. | who reacted | the channel/group (empty in private, or for a reaction to a Story/Status) | $1 = the emoji, $2 = message id (empty for a reaction to a Story/Status) | yes - suppresses the default line, the script redraws it as it prefers |
on join/on part/on kick/on topic/
on op/on deop/on invite work on Telegram and WhatsApp (on invite
doesn't make sense on IRC, which has no invite links). On Telegram there's a limit from the platform itself
though (not Yoake): the protocol only sends these updates to channel/supergroup admins, or to everyone in small
groups - if you don't see them arriving in a large Telegram group you're not an admin of, it's because Telegram
itself isn't sending them to you. On IRC, on join/on part/on kick/
on topic/on op/on deop work without this limit (the server always sends
these events to everyone in the channel, not just admins) - see IRC.on op {
echo $nick became admin of $chan
}
on nick {
echo $nick is now called $1
}
on invite {
echo ⚠️ $nick sent you an invite link: $1
}
on message {
echo $nick wrote in $chan
}
on notice {
if ($noticetype == missedcall) haltdef
}
Custom whois - replaces the default lines with a format of your own:
on whois {
haltdef
echo -a ── $nick ──
echo -a Name: $1
if ($2 != $null) echo -a Username: $2
if ($4 == on) echo -a Status: 🟢 online
elseif ($4 == off) echo -a Status: ⚫ offline
}
Block all calls - decline them right away and let the caller know instead of showing "Incoming call":
on call {
haltdef
rejectcall I don't take calls, message me instead!
}
Automatic video playlist - walks through a channel/group (e.g. a series' episodes) looking for videos with
$msg() (see Identifiers) and moves to the next one on its own with
on videoend:
alias playlist {
set %pl.chan $1
set %pl.idx 0
playlist.next
}
alias playlist.next {
inc %pl.idx
while (%pl.idx <= $msg(%pl.chan,0)) && ($msg(%pl.chan,%pl.idx).type != video) {
inc %pl.idx
}
if (%pl.idx > $msg(%pl.chan,0)) {
echo -a Playlist finished.
return
}
playmedia %pl.chan $msg(%pl.chan,%pl.idx).id
}
on videoend {
playlist.next
}
Then just /playlist #ChannelName (or the window id) to start it. Note: $msg() only
sees the messages already loaded in that window (open the channel and scroll up to load more, if needed).
alias name { ... } - it works
the same as writing it on the Aliases tab, mIRC doesn't separate aliases by file.On the Variables tab, one declaration per line: %name value. Usable as %name
inside aliases/events/popups, anywhere in a script's text.
%greeting Hi from my alias!
hello {
say %greeting $1
}
variables.ini. This applies both to the ones declared by hand on the
Variables tab and to the ones created/modified at runtime with set/inc/dec
while a script runs: they're written to disk automatically (with a short delay, so as not to write on
every single loop iteration - the same principle real mIRC uses, saving periodically instead
of on every /set).Example - a counter that survives restarts, with no need to declare it by hand on the Variables tab:
on message {
set %counter $calc(%counter + 1)
echo Messages received so far: %counter
}
Context menus (right-click) - same syntax as real mIRC, separate sections for each context:
| Section | Where it appears |
|---|---|
[status] | Right-click in the Status window. |
[channel] | Right-click in the middle of a group/channel window. |
[query] | Right-click in the middle of a private chat. |
[nicklist] | Right-click a nick in the user list. |
[menubar] | Popup attachable to the menu bar. |
On the Popups tab, the "View" dropdown (or the View menu at the top of the editor) chooses which section you're editing - each has its own text, as in the real mIRC editor. The "Popup" menu at the top shows a live preview of how the menu will be drawn as you write it.
Syntax: Label:command one entry per line, - for a separator, nested submenus
with one extra dot per level. In [nicklist] popups, $1 and $nick are the
nick you right-clicked:
Greet everyone:say Hi everyone! - More commands .Who am I:whois $1 .Kick:kick $1