Baphomet is the dedicated bot for nulloctet matrix
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
3.9 KiB

  1. let { logger } = require('./logging');
  2. let { modules } = require('./module/index');
  3. let trie = require('trie-prefix-tree');
  4. let { getShortestPrefix } = require('./utility');
  5. let help = require('./module/help');
  6. let message = require('./message');
  7. let utility = require('./utility');
  8. let sentinelValue = '!';
  9. class Engine {
  10. constructor(config, bot, modules) {
  11. this.config = config;
  12. this.bot = bot;
  13. this.modules = modules;
  14. this.moduleMap = new Map();
  15. this.commandMap = new Map();
  16. this.commandRadixTree = trie([]);
  17. }
  18. initModules() {
  19. this.modules.forEach((module) => {
  20. logger.info("Loading module: %s", module.name);
  21. this.moduleMap.set(module.command, module);
  22. this.commandMap.set(module.command, module);
  23. this.commandRadixTree.addWord(module.command);
  24. });
  25. this.modules.forEach((module) => {
  26. let shortCommand = getShortestPrefix(this.commandRadixTree, module.command, 3);
  27. logger.info("Adding short command %s for module: %s", shortCommand, module.name);
  28. this.commandMap.set(shortCommand, module);
  29. });
  30. this.helpModule = help.create(this.moduleMap)
  31. this.commandMap.set('help', this.helpModule);
  32. logger.info("Bound modules to keywords: %o", this.moduleMap);
  33. }
  34. init() {
  35. logger.info("Initializing modules");
  36. this.initModules();
  37. /* Bind Message Parsing */
  38. let engine = this;
  39. let handleMessages = (event, room, toStartOfTimeline) => {
  40. /* Don't process messages from self */
  41. if (event.sender.userId !== this.config.userId) {
  42. /* don't process messages that aren't of type m.room.message */
  43. if (event.getType() !== "m.room.message") {
  44. logger.debug("Recieved message of type: %s", event.getType());
  45. return;
  46. } else {
  47. let messageBody = event.event.content.body;
  48. logger.debug("[%s] %s", room.name, messageBody);
  49. if (messageBody.indexOf(sentinelValue) === 0) {
  50. let command = messageBody.split(' ')[0].substring(1);
  51. var responseMessage = null;
  52. if (engine.commandMap.has(command)) {
  53. responseMessage = engine.commandMap.get(command).handleMessage(event, room);
  54. } else {
  55. responseMessage = engine.helpModule.help();
  56. }
  57. logger.debug("Responding to room: %s", room.roomId);
  58. if (responseMessage instanceof Object) {
  59. engine.bot.client.sendMessage(room.roomId, responseMessage);
  60. } else if (utility.isString(responseMessage)) {
  61. engine.bot.client.sendMessage(room.roomId, message.createBasic(responseMessage));
  62. } else {
  63. logger.error("Unable to process response message: %s", responseMessage);
  64. }
  65. }
  66. }
  67. }
  68. }
  69. this.bot.init(handleMessages);
  70. /* Capture Exit Conditions */
  71. ["SIGINT", "SIGTERM"].forEach((signature) => {
  72. process.on(signature, async () => {
  73. await this.bot.sendStatusShutdown()
  74. .then(() => {
  75. logger.info("Gracefully stopping Matrix SDK Client")
  76. this.bot.client.stopClient();
  77. });
  78. process.exit(0);
  79. });
  80. });
  81. process.on('exit', () => {
  82. logger.info("Shutting Down");
  83. });
  84. return this;
  85. }
  86. run() {
  87. this.bot.connect();
  88. return this;
  89. }
  90. }
  91. function create(config, bot) {
  92. return new Engine(config, bot, modules)
  93. }
  94. exports.create = create;