This allows a Node.js bot like irc-framework to control UnrealIRCd via the JSON-RPC interface.
- Install:
npm i unrealircd-rpc-node - Code a little by integrating it with IRC-framework or another library.
- Download https://github.com/Madriix/unrealircd-rpc-node.git
- Rename the folder
unrealircd-rpc-node-maintounrealircd-rpc-node - Add
unrealircd-rpc-nodeto the same folder as your node bot - Install ws:
npm install ws - Code a little by integrating it with IRC-framework or another library.
Bot setup (with IRC-framework)
UnrealIRCd 6.0.6 or later is needed and you need to enable JSON-RPC in it. After doing that, be sure to rehash the IRCd.
Here is an example with IRC-framework
const { UnrealIRCdRpc, unrealircdRpc } = require('unrealircd-rpc-node');
// Set the correct address and port for your UnrealIRCd RPC.
UnrealIRCdRpc.address = "wss://ApiUser:api-user-password@127.0.0.1:8600/";
// ...
bot.on('message', async function (event) {
console.log('<' + event.nick + '>', event.message);
console.log(event);
if (!/^#/.test(event.target) && /^!test_unrealircd_rpc_1$/.test(event.message)) {
await unrealircdRpc.serverBanAdd(
"~account:test",
"gline",
"60",
"Abuse"
);
}
if (!/^#/.test(event.target) && /^!test_unrealircd_rpc_2$/.test(event.message)) {
const bans = await unrealircdRpc.serverBanGetAll();
for (const ban of bans) {
bot.raw(`PRIVMSG ${event.nick} :There's a ${ban.type} on ${ban.name}`);
}
}
if (!/^#/.test(event.target) && /^!test_unrealircd_rpc_3$/.test(event.message)) {
await unrealircdRpc.sendPrivmsg("TestNick", "Test message");
}
if (!/^#/.test(event.target) && /^!test_unrealircd_rpc_4$/.test(event.message)) {
await unrealircdRpc.sendNumeric(
"Nick",
318,
"End of /WHOIS list."
);
}
if (!/^#/.test(event.target) && /^!test_unrealircd_rpc_5$/.test(event.message)) {
const securitygroups = await unrealircdRpc.listSecurityGroups();
for (const group of securitygroups) {
bot.raw(`PRIVMSG ${event.nick} :Security-Group : ${group.name}`);
}
}
if (!/^#/.test(event.target) && /^!test_unrealircd_rpc_6$/.test(event.message)) {
const group = await unrealircdRpc.getSecurityGroup(
"unknown-users"
);
if (group) {
bot.raw(`PRIVMSG ${event.nick} Security-Group ${group.name}`);
for (const [key, value] of Object.entries(group)) {
bot.raw(`PRIVMSG ${event.nick} :${key} = ${value}`);
}
}
}
});Just go to the bot's private account and type "!test_unrealircd_rpc_1", it will answer you and add a gline to ~account:test.
When testing the command "!test_unrealircd_rpc_2", you will see the list of bans.
By testing "!test_unrealircd_rpc_3", you will receive a message from the IRC server if you replace the nick TestNick with your own nick.
You can also test "!test_unrealircd_rpc_4" and others.
If the example does not work, then make sure you have configured your
UnrealIRCd correctly, with the same API username and password you use
here, with an allowed IP, and changing the wss://127.0.0.1:8600/ too
if needed.
I was inspired by the code unrealircd-rpc-php by copying. I use it on an irc-framework bot, it works well for ServerBan (add/del/list) and Message (send_privmsg, send_notice, send_numeric).
await unrealircdRpc.serverBanAdd(
"~account:test",
"gline",
3600, // or "3600"
"Abuse"
);await unrealircdRpc.serverBanDelete("~account:test", "gline");await unrealircdRpc.gline(
"~account:baduser",
600,
"Flood"
);await unrealircdRpc.kline(
"baduser@host",
0,
"Permanent ban"
);const bans = await unrealircdRpc.serverBanGetAll();const ban = await unrealircdRpc.serverBanGet(
"~account:test",
"gline"
);await unrealircdRpc.serverBanExceptionAdd(
"~account:trusted",
["gline", "kline"],
"Trusted user",
"admin",
3600
);await unrealircdRpc.serverBanExceptionDelete("~account:trusted");const elines = await unrealircdRpc.serverBanExceptionGetAll();const eline = await unrealircdRpc.serverBanExceptionGet(
"~account:trusted"
);const users = await unrealircdRpc.listUsers();const user = await unrealircdRpc.getUser("Nick");await unrealircdRpc.setNick("OldNick", "NewNick");await unrealircdRpc.setUsername("Nick", "newuser");await unrealircdRpc.setRealname("Nick", "Real Name");await unrealircdRpc.setVhost("Nick", "user.example.org");await unrealircdRpc.setUserMode("Nick", "+i");await unrealircdRpc.setSnomask("Nick", "+s");await unrealircdRpc.setOper(
"Nick",
"oper_account",
"netadmin"
);await unrealircdRpc.joinChannel("Nick", "#channel");await unrealircdRpc.partChannel("Nick", "#channel");await unrealircdRpc.quitUser("Nick", "Bye");await unrealircdRpc.killUser("Nick", "Policy violation");const channels = await unrealircdRpc.listChannels();const channel = await unrealircdRpc.getChannel("#channel");await unrealircdRpc.setChannelMode("#channel", "+m", []);await unrealircdRpc.setChannelTopic(
"#channel",
"New topic"
);await unrealircdRpc.kick(
"#channel",
"Nick",
"Off-topic"
);await unrealircdRpc.spamfilterAdd(
"badword",
"simple",
["privmsg", "notice"],
"block",
0,
"Forbidden word"
);await unrealircdRpc.spamfilterDelete(
"badword",
"simple",
["privmsg", "notice"],
"block"
);const filters = await unrealircdRpc.spamfilterGetAll();const filter = await unrealircdRpc.spamfilterGet(
"badword",
"simple",
["privmsg"],
"block"
);await unrealircdRpc.namebanAdd(
"BadNick",
"Reserved nickname",
3600
);await unrealircdRpc.namebanDelete("BadNick");const namebans = await unrealircdRpc.namebanGetAll();const nameban = await unrealircdRpc.namebanGet("BadNick");const stats = await unrealircdRpc.getStats();const history = await unrealircdRpc.whowasGet("OldNick");await unrealircdRpc.logSubscribe(["server", "oper"]);await unrealircdRpc.logUnsubscribe();const logs = await unrealircdRpc.logGetAll();await unrealircdRpc.sendPrivmsg(
"Nick",
"Hello world"
);await unrealircdRpc.sendNotice(
"Nick",
"This is a notice"
);await unrealircdRpc.sendNumeric(
"Nick",
123,
"Custom numeric"
);await unrealircdRpc.sendStandardReply(
"Nick",
"error",
"NO_ACCESS",
{},
"Access denied"
);const groups = await unrealircdRpc.listSecurityGroups();const group = await unrealircdRpc.getSecurityGroup(
"unknown-users"
);- All methods return the raw UnrealIRCd RPC response
- Errors are propagated as-is
- Optional parameters follow the official UnrealIRCd API
- Not all commands have been tested by me, except for a few
- If you update it or find something that works, please let me know
Commmands available (not all tested)
// let rpc = await urpc.connection;
// serverban : The server_ban.* JSON RPC calls can add, remove and list server bans such as KLINE, GLINE, etc.
await rpc.serverban().add("~account:test", "gline", "60", "no reason");
await rpc.serverban().delete("~account:test", "gline");
await rpc.serverban().getAll();
await rpc.serverban().get("~account:test", "gline");
// serverbanexception : The server_ban_exception.* JSON RPC calls can add, remove and list server ban exceptions (ELINEs).
await rpc.serverbanexception().add(name, types, reason, set_by = null, duration = null)
await rpc.serverbanexception().delete(name)
await rpc.serverbanexception().getAll()
await rpc.serverbanexception().get(name)
// user : The user.* JSON RPC calls can list and retrieve information about users.
await rpc.user().getAll(object_detail_level = 2)
await rpc.user().get(nick, object_detail_level = 4)
await rpc.user().set_nick(nick, newnick)
await rpc.user().set_username(nick, username)
await rpc.user().set_realname(nick, realname)
await rpc.user().set_vhost(nick, vhost)
await rpc.user().set_mode(nick, mode, hidden = false)
await rpc.user().set_snomask(nick, snomask, hidden = false)
await rpc.user().set_oper(nick, oper_account, oper_class, classVal = null, modes = null, snomask = null, vhost = null)
await rpc.user().join(nick, channel, key = null, force = false)
await rpc.user().part(nick, channel, force = false)
await rpc.user().quit(nick, reason)
await rpc.user().kill(nick, reason)
// channel : The channel.* JSON RPC calls can list and retrieve information about channels.
await rpc.channel().getAll(object_detail_level = 1)
await rpc.channel().get(channel, object_detail_level = 3)
await rpc.channel().set_mode(channel, modes, parameters)
await rpc.channel().set_topic(channel, topic, set_by = null, set_at = null)
await rpc.channel().kick(channel, nick, reason)
// spamfilter : The spamfilter.* JSON RPC calls can add, remove and list spamfilters.
await rpc.spamfilter().add(name, match_type, spamfilter_targets, ban_action, ban_duration, reason)
await rpc.spamfilter().delete(name, match_type, spamfilter_targets, ban_action)
await rpc.spamfilter().getAll()
await rpc.spamfilter().get(name, match_type, spamfilter_targets, ban_action)
// nameban : The name_ban.* JSON RPC calls can add, remove and list banned nicks and channels (q-lines).
await rpc.nameban().add(name, reason, duration = null, set_by = null)
await rpc.nameban().delete(name)
await rpc.nameban().getAll()
await rpc.nameban().get(name)
// stats : Get some quick basic statistics. This is for example used by the admin panel for the 'Overview' page.
await rpc.stats().get(object_detail_level = 1)
// whowas : The whowas.* JSON RPC calls retrieve whowas history of users.
await rpc.whowas().get(nick = null, ip = null, object_detail_level = 2)
// log : The log.* JSON RPC calls allow you to subscribe and unsubscribe to log events (real-time streaming of JSON logs).
await rpc.log().subscribe(sources)
await rpc.log().unsubscribe()
await rpc.log().getAll(sources = null)
// message : The message.* JSON RPC calls can send_privmsg, send_notice, send_numeric, send_standard_reply.
await rpc.message().send_privmsg("nick", "Test message");
await rpc.message().send_notice("nick", "Test notice");
await rpc.message().send_numeric(nick, numeric, message);
await rpc.message().send_standard_reply(nick, type, code, context, description);
// securitygroup : The security_group.* JSON RPC calls can list security groups
await rpc.securitygroup().getAll();
await rpc.securitygroup().get("unknown-users");