1 | ## Creating New Modules
|
2 | ### General Nodes
|
3 | For a "Hello World" example see [here](https://github.com/mrkno/HelloKassy).
|
4 |
|
5 | The basic module for a Kassy module will contain the following files:
|
6 | - `someModule.js` - a javascript file that will be the basis of the module.
|
7 | - `kassy.json` - a file describing your module, that can be used by Kassy to start it.
|
8 |
|
9 | Correctly created modules once in a public git repository can automatically be installed using the `kpm` command.
|
10 |
|
11 | #### File Locations
|
12 |
|
13 | - Modules should be created as their folder within the `modules` (<b>not `node_modules`</b>) subdirectory.
|
14 | - Each module folder should contain a `kassy.json` file (see existing modules for examples).
|
15 |
|
16 | #### `require('module')`
|
17 | Any modules that depend on an `npm` package should include it as usual using the `require` function. Note: if the package that has been required is not installed, the latest version will be installed for you.
|
18 |
|
19 | Additional methods are also avalible with require:
|
20 |
|
21 | * ~~require.safe('module')~~ __Deprecated__ available for backwards compatibility.
|
22 | * ~~require.once('module')~~ __Internal__ required to allow seemless code hotswap.
|
23 |
|
24 | ### Methods
|
25 |
|
26 | Every module must provide the same basic methods, which can then be expanded to perform whatever tasks are required. These are as follows:
|
27 |
|
28 | #### `exports.match(event, commandPrefix)`
|
29 | <i>Optional if implemented in `kassy.json`, see below.</i>
|
30 | This method is used to test whether your module should be run on the given message.
|
31 |
|
32 | Arguments:
|
33 | - `event`. The event representing the data that has been received See the Event section below. Object.
|
34 | - `commandPrefix`. The command prefix of the integration that received the message. String.
|
35 | - <i>returns</i>. `true` if the module should run, `false` otherwise. Boolean.
|
36 |
|
37 | For example, if you were creating a weather module that runs whenever the text `/weather` is written, `match` would return `true` if `event.body` was `/weather some data here` and `false` if it was `not what you are wanting`.
|
38 |
|
39 | <i>Note:
|
40 |
|
41 | For backwards compatibility reasons, if the `event` argument is renamed to `text`, `event.body` will be passed rather than the `event` object.</i>
|
42 |
|
43 |
|
44 | #### `exports.help(commandPrefix)`
|
45 | <i>Optional if implemented in `kassy.json`, see below.</i>
|
46 | This method should return an array of arrays containing help to be used with the `/kassy` command.
|
47 |
|
48 | Each sub-array should contain:
|
49 | - 1st Index: the command help is being provided for as a string. E.g. '/example'.
|
50 | - 2nd Index: a short description of what the command does as a string. E.g. 'Is an example command.'.
|
51 | - 3rd Index: (optional) a long description of what the command does as a string. E.g. 'Is an example command that can be used to do foo.'.
|
52 |
|
53 | Arguments:
|
54 | - 'commandPrefix'. The command prefix of the integration that received the message. String.
|
55 | - <i>returns</i>. An array of arrays containing help. Array.
|
56 |
|
57 | ~~this.commandPrefix~~ __Deprecated__ available for backwards compatibility.
|
58 |
|
59 | For example, with a weather module you might return `[[commandPrefix + 'weather', 'Gets the weather of your current location.']]`.
|
60 |
|
61 | #### `exports.run(api, event)`
|
62 | This method is called whenever the module should be run.
|
63 |
|
64 | Arguments:
|
65 | - `api`. The API to output data to the current output module. See API section below. Object.
|
66 | - `event`. An object containing information about the message received. See event section below. Object.
|
67 |
|
68 | For example, with a weather module you might call `api.sendMessage('The weather is nice here today!', event.thread_id);`.
|
69 |
|
70 | #### `exports.unload()`
|
71 | <i><b>Almost</b>-Optional</i>.
|
72 | This method is called once when the program is shutting down. No output module is guaranteed to be available at this point. Should be used to unload files and cancel any timers. Failure to use this method correctly can prevent a successful restart.
|
73 |
|
74 | Arguments:<br />
|
75 | <i>None</i>
|
76 |
|
77 | #### `exports.load()`
|
78 | <i>Optional</i>.
|
79 | This method is called once when the program is first starting up. No output module is guaranteed to be running at this point. Should be used to initialise variables or load files, etc as appropriate.
|
80 |
|
81 | Arguments:<br />
|
82 | <i>None</i>
|
83 |
|
84 | ### API
|
85 | <i>Please note that not all methods are guaranteed to work as described if the platform does not support the feature. A fallback will be provided in this case.</i>
|
86 |
|
87 | The `api` object contains the following methods:
|
88 | #### `sendMessage(message, thread)`
|
89 | Sends a message to the specified thread.
|
90 |
|
91 | Arguments:
|
92 | - `message`. The message to send. String.
|
93 | - `thread`. The thread to send it to. String.
|
94 |
|
95 | Returns:
|
96 | - `undefined`
|
97 |
|
98 | #### `sendPrivateMessage(message, thread, senderId)`
|
99 | Sends a message to an individual.
|
100 |
|
101 | Arguments:
|
102 | - `message`. The message to send. String.
|
103 | - `thread`. The thread which the associated command which sends the private message. String.
|
104 | - `senderId`. The sender to send the message to. String.
|
105 |
|
106 | Returns:
|
107 | - `undefined`
|
108 |
|
109 | #### `sendUrl(url, thread)`
|
110 | Sends a url to the specified thread. If url linking is not supported, will behave like `sendMessage`.
|
111 |
|
112 | Arguments:
|
113 | - `url`. The url to send. String.
|
114 | - `thread`. The thread to send it to. String.
|
115 |
|
116 | Returns:
|
117 | - `undefined`
|
118 |
|
119 | #### `sendImage(type, image, description, thread)`
|
120 | Sends an image to the specified thread. If image is a URL it will behave like `sendUrl`, otherwise it will behave like `sendFile`.
|
121 |
|
122 | Arguments:
|
123 | - `type`. The type of image being sent. `"url"` for a URL to an image or `"file"` for a local file. String.
|
124 | - `image`. The image to send. String (url or file location). String.
|
125 | - `description`. The description to associate with the image. String
|
126 | - `thread`. The thread to send it to. String.
|
127 |
|
128 | Returns:
|
129 | - `undefined`
|
130 |
|
131 | #### `sendFile(type, file, description, thread)`
|
132 | Sends a file to the specified thread. If file is a URL it will behave like `sendUrl`, otherwise it will send directly.
|
133 |
|
134 | Arguments:
|
135 | - `type`. The type of file being sent. `"url"` for a URL to a file or `"file"` for a local file. String.
|
136 | - `file`. The file to send. String (url or file location). String.
|
137 | - `description`. The description to associate with the file. String
|
138 | - `thread`. The thread to send it to. String.
|
139 |
|
140 | Returns:
|
141 | - `undefined`
|
142 |
|
143 | #### `sendTyping(thread)`
|
144 | Sends a typing indicator to the specified thread. Will either time out or cancel when the next call to `api` occurs.
|
145 |
|
146 | Arguments:
|
147 | - `thread`. The thread to send it to. String.
|
148 |
|
149 | Returns:
|
150 | - `undefined`
|
151 |
|
152 | #### `setTitle(title, thread)`
|
153 | Sets the title of the specified thread.
|
154 |
|
155 | Arguments:
|
156 | - `title`. The title to set. String.
|
157 | - `thread`. The thread to set it on. String.
|
158 |
|
159 | Returns:
|
160 | - `undefined`
|
161 |
|
162 | #### `commandPrefix`
|
163 | Is a static variable containing the command prefix that should be used for the platform.
|
164 |
|
165 | ### `kassy.json`
|
166 | `kassy.json` is a file of the following format:
|
167 | ```
|
168 | {
|
169 | "name": "<yourModuleNameHere>",
|
170 | "version": 1.0,
|
171 | "startup": "<yourModuleJSFileHere.js>",
|
172 | "command": "<(optional) someCommandHere>",
|
173 | "help": [
|
174 | ["{{commandPrefix}}<whateverCommandYouProvide>", "<some brief help>", "<(optional) some longer help>"]
|
175 | ]
|
176 | }
|
177 | ```
|
178 |
|
179 | Notes:
|
180 | - Both the `command` and `help` sections are optional and can be used instead of their equivilent code methods.
|
181 | - The `command` section is equivilent to doing a basic command check in `exports.match`
|
182 | - The `help` section is equivilent to returning a constant array in `exports.help`
|
183 |
|
184 |
|
185 | ### Event
|
186 | The `event` object contains the following fields:
|
187 | - `body`. The body of the message received. String.
|
188 | - `arguments`. `body` split at spaces except where the spaces are inside double quotes. Array of Strings.
|
189 | - `arguments_body`. `body` with the command removed from the beginning. String.
|
190 | - `thread_id`. The ID of the thread the message was received from. String.
|
191 | - `sender_name`. The name of the sender that the message was received from. String.
|
192 | - `sender_id`. The ID of the sender who sent the message. String.
|
193 |
|
194 | ### Persistence
|
195 | Any data stored in `exports.config` within the scope of a module will automatically be persistent between restarts of the program, provided a safe shutdown and an error free startup. Note that data in this variable is not gaurenteed to be set before `load()` is called on your module.
|
196 |
|
197 | ### Logging and Errors
|
198 | Any logging and errors should <b>NOT</b> be logged to the console using any methods other than:
|
199 | - `console.debug(str)` - logs `str` to the console if and only if debugging is enabled.
|
200 | - `console.critical(exception)`- logs the message and trace of an Exception (`exception`) to the console if and only if debugging is enabled.
|
201 |
|
202 | This is to prevent spamming users with information that is not relevant.
|
203 |
|
204 | ### Loading Modules
|
205 | New modules will be automatically detected and loaded after a restart of the application. This can be performed using the special `/restart` command.
|
206 |
|
207 | Kassy can also be updated, pulling new pre-installed modules down with it. This can be performed using a combination of the `/update` and `/restart` commands.
|
208 |
|
209 | ### Special Commands
|
210 | Please note that special commands cannot be overriden by any other command.
|
211 |
|
212 | ### Core Modules
|
213 | Within Kassy there is the concept of "Core" modules. These are modules that provide core functionality of Kassy. If possible creating these should be avoided as any incorrect code within them can cause total system failure (traditional modules have additional protections). Further they have the ability to access and alter core components of the system that should not ever be required in a traditional module.
|
214 |
|
215 | Core modules are located in `core/core_modules`. Use existing modules as documentation on how they work - it is subject to frequent change.
|