import std.stdio: writeln; import std.net.curl; import asdf: deserialize, serializeToJson; import util; void main() { import std.process: environment; alias env = environment.get; homeserver = env("SKUNKYBOT_HOMESERVER"); init(env("SKUNKYBOT_TOKEN")); sync; } HTTP http; string syncUrl; string initialBatch; void init(string token) { http = HTTP(); http.addRequestHeader("Authorization", "Bearer " ~ token); http.tcpNoDelay = true; // initial sync writeln("starting initial sync.."); syncUrl = homeserver ~ "/_matrix/client/v3/sync?set_presence=online"; initialBatch = (get(syncUrl, http).deserialize!Sync).next_batch; syncUrl ~= "&since="; writeln("done!"); } void send(T)(T content, string roomid, string type = "m.room.message") { import std.random: uniform; put(homeserver~"/_matrix/client/v3/rooms/" ~ roomid ~ "/send/" ~ type ~ "/skunky-" ~ intToStr(uniform(1111_1111, 9999_9999)), content.serializeToJson, http); } // void join(string roomid) { // post(homeserver~"/_matrix/client/v3/rooms/"~roomid~"/join", http); // } import commands; static MSG helpgen() { string buf; static foreach (member; __traits(allMembers, commands)) { static foreach (attr; __traits(getAttributes, __traits(getMember, commands, member))) { static if (is(typeof(attr) == Command)) buf ~= member ~ ": " ~ attr.description ~ '\n'; } } return MSG(buf); } void sync() { auto content = Sync(); content.next_batch = initialBatch; for (;;) { string bthUrl = syncUrl ~ content.next_batch; try content = get(bthUrl, http).deserialize!Sync; catch (Exception e) { writeln("ERR: ", e.msg); continue; } foreach (room, _; content.rooms.invite) { writeln("Joining to room: ", room); post(homeserver~"/_matrix/client/v3/rooms/"~room~"/join", null, http); send(MSG("Йа криведко"), room); } foreach (room, roomContent; content.rooms.join) { foreach(event; roomContent.timeline.events) { if (event.type == "m.room.message") { try { auto evt = deserialize!MSG(event.content.raw); if (!evt.body.length) break; auto argz = parseMsg(evt.body); if (argz.command == "hlp") { send(helpgen, room); break; } foreach (member; __traits(allMembers, commands)) { if (argz.command == member) { alias command = __traits(getMember, commands, member); foreach (attr; __traits(getAttributes, command)) { static if (is(typeof(attr) == Command)) { static if (is(typeof(command) == function)) auto content = command(argz, &event); else static if (__traits(isStaticArray, command)) auto content = MSG(command[0], command[1]); else auto content = MSG(command); send(content, room); } } } } } catch (Exception e) { writeln(e.msg); send(MSG(e.msg), room); } } } } } }