Commit b2ac5be0 authored by Tim Kinnane's avatar Tim Kinnane
Browse files

feat(api): Add exported Rocket.Chat API client

- Add docs and tests for API
- Update tests using old utils api
- Use setup script pretest instead of each spec
parent 27f7bd41
......@@ -5,5 +5,4 @@
/.env
/shrinkwrap.yaml
/package-lock.json
/docs/*
!/docs/.gitkeep
\ No newline at end of file
/docs/
\ No newline at end of file
[asteroid]: https://www.npmjs.com/package/asteroid
[lru]: https://www.npmjs.com/package/lru
[rest]: https://rocket.chat/docs/developer-guides/rest-api/
# Rocket.Chat Node.js SDK
......@@ -36,7 +37,7 @@ const SSL = true; // server uses https ?
const ROOMS = ['GENERAL', 'myroom1'];
var myuserid;
// this simple bot does not handle errors, different messsage types, server resets
// this simple bot does not handle errors, different message types, server resets
// and other production situations
const runbot = async () => {
......@@ -110,9 +111,9 @@ We have more bot features and adapters on the roadmap and encourage the
community to implement this SDK to provide adapters for their bot framework
or platform of choice.
## API
## Docs
Full API documentation can be generated locally using `yarn docs`.
Full documentation can be generated locally using `yarn docs`.
This isn't in a format we can publish yet, but can be useful for development.
Below is just a summary:
......@@ -122,25 +123,30 @@ Below is just a summary:
Currently, there are two modules exported by the SDK:
- `driver` - Handles connection, method calls, room subscriptions (via Asteroid)
- `methodCache` - Manages results cache for calls to server (via LRU cache)
- `api` - Provides a client for making requests with Rocket.Chat's REST API
Access these modules by importing them from SDK, e.g:
For Node 8 / ES5
`const { driver, methodCache } = require('@rocket.chat/sdk')`
`const { driver, methodCache, api } = require('@rocket.chat/sdk')`
For ES6 supporting platforms
`import { driver, methodCache } from '@rocket.chat/sdk'`
See [Asteroid][asteroid] docs for methods that can be called from that API.
`import { driver, methodCache, api } from '@rocket.chat/sdk'`
Any Rocket.Chat server method can be called via `driver.callMethod`,
`driver.cacheCall` or `driver.asyncCall`. Server methods are not fully
documented, most require searching the Rocket.Chat codebase.
Driver methods use an [Asteroid][asteroid] DDP connection. See its own docs for
more advanced methods that can be called from the `driver.asteroid` interface.
Rocket.Chat REST API calls can be made via `api.get` or `api.post`, with
parameters defining the endpoint, payload and if authorization is required
(respectively). See the
#### MESSAGE OBJECTS
## MESSAGE OBJECTS
---
......@@ -154,11 +160,11 @@ The `driver.prepareMessage` method (documented below) provides a helper for
simple message creation and the `message` module can also be imported to create
new `Message` class instances directly if detailed attributes are required.
#### DRIVER METHODS
## DRIVER METHODS
---
### `driver.connect(options, cb?)`
### `driver.connect(options[, cb])`
Connects to a Rocket.Chat server
- Options accepts `host` and `timeout` attributes
......@@ -233,11 +239,17 @@ Fires callback after filters run on subscription events.
- Third argument is additional attributes, such as `roomType`
Accepts options object, that parallels respond filter env variables:
- options.allPublic : respond to messages on all channels (or just joined)
- options.rooms : respond to messages in joined rooms
- options.allPublic : respond to messages on all channels
- options.dm : respond to messages in DMs with the SDK user
- options.livechat : respond to messages in Livechat rooms
- options.edited : respond to edited messages
If rooms are given as option or set in the environment with `ROCKETCHAT_ROOM`
but have not been joined yet this method will join to those rooms automatically.
If `allPublic` is true, the `rooms` option will be ignored.
### `driver.asyncCall(method, params)`
Wraps server method calls to always be async
......@@ -296,7 +308,7 @@ Join the logged in user into a room
As above, with array of room names/IDs
### `driver.prepareMessage(content, roomId?)`
### `driver.prepareMessage(content[, roomId])`
Structure message content for sending
- Accepts a message object or message text string
......@@ -326,7 +338,7 @@ As above, with username for DM instead of ID
---
### METHOD CACHE
## METHOD CACHE
[LRU][lru] is used to cache results from the server, to reduce unnecessary calls
for data that is unlikely to change, such as room IDs. Utility methods and env
......@@ -340,7 +352,7 @@ Set the instance to call methods on, with cached results
- Accepts an Asteroid instance (or possibly other classes)
- Returns nothing
### `methodCache.create(method, options?)`
### `methodCache.create(method[, options])`
Setup a cache for a method call
- Accepts method name and cache options object, such as:
......@@ -366,7 +378,7 @@ Get results of a prior method call
- Accepts method name and key (argument method called with)
- Returns results at key
### `methodCache.reset(method, key?)`
### `methodCache.reset(method[, key])`
Reset a cached method call's results
- Accepts a method name, optional key
......@@ -380,7 +392,64 @@ Reset a cached method call's results
---
## Getting Started
### API CLIENT
[node-rest]: https://www.npmjs.com/package/node-rest-client
[rest-api]: https://rocket.chat/docs/developer-guides/rest-api/
We've included an [API client][node-rest] to make it super simple for bots and
apps consuming the SDK to call the [Rocket.Chat REST API][rest-api] endpoints.
By default, it will attempt to login with the same defaults or env config as
the driver, but the `.login` method could be used manually prior to requests to
use different credentials.
If a request is made to an endpoint requiring authentication, before login is
called, it will attempt to login first and keep the response token for later.
Bots and apps should manually call the API `.logout` method on shutdown if they
have used the API.
### `api.loggedIn()`
Returns boolean status of existing login
### `api.post(endpoint, data[, auth, ignore])
Make a POST request to the REST API
- `endpoint` - The API resource ID, e.g. `channels.info`
- `data` - Request payload object to send, e.g. { roomName: 'general' }
- `auth` - If authorisation is required (defaults to true)
- Returns promise
### `api.get(endpoint, data[, auth, ignore])
Make a GET request to the REST API
- `endpoint` - The API endpoint resource ID, e.g. `users.list`
- `data` - Params (converted to query string), e.g. { fields: { 'username': 1 } }
- `auth` - If authorisation is required (defaults to true)
- Returns promise
### `api.login([user])`
Perform login with default or given credentials
- `user` object with `.username` and `.password` properties.
- Returns promise, resolves with login result
### `api.logout()`
Logout the current user. Returns promise
### `api.currentLogin`
Exported property with details of the current API session
- `.result` - The login request result
- `.username` - The logged in user's username
- `.userId` - The logged in user's ID
- `.authToken` - The current auth token
---
## Development
A local instance of Rocket.Chat is required for unit tests to confirm connection
and subscription methods are functional. And it helps to manually run your SDK
......@@ -410,8 +479,6 @@ rocketchat.driver.connect({ host: 'localhost:3000' }, function (err, asteroid) {
})
```
## Develop & Test
### Settings
| Env var | Description |
......@@ -439,10 +506,9 @@ rocketchat.driver.connect({ host: 'localhost:3000' }, function (err, asteroid) {
These are only required in test and development, assuming in production they
will be passed from the adapter implementing this package.
`ROCKETCHAT_ROOM` should be set to empty (with `ROCKETCHAT_ROOM=''`) when using
`LISTEN_ON_ALL_PUBLIC`. This option also allows the bot to listen and respond to
messages _from all newly created private groups_ where the bot's user has been
added as a member.
`ROCKETCHAT_ROOM` is ignored when using `LISTEN_ON_ALL_PUBLIC`. This option also
allows the bot to listen and respond to messages _from all private groups_ where
the bot's user has been added as a member.
### Installing Rocket.Chat
......@@ -484,9 +550,8 @@ but won't change coverage to avoid making any working copy changes after commit.
The node scripts in `utils` are used to prepare for and clean up after test
interactions. They use the Rocket.Chat API to create a bot user and a mock human
user (benny) for the bot to interact with. They *should* restore the pre-test
state but it is always advised to only run tests with a connection to a clean
local or fresh re-usable container instance of Rocket.Chat.
user for the bot to interact with. It is always advised to only run tests with
a connection to a clean local or re-usable container instance of Rocket.Chat.
### Debugging
......
TN:
SF:/Volumes/x/code/rocketchat/Rocket.Chat.js.SDK/src/lib/api.ts
FN:24,loggedIn
FN:47,getQueryString
FN:49,(anonymous_8)
FN:62,setAuth
FN:68,getHeaders
FN:81,clearHeaders
FN:87,success
FN:109,post
FN:119,(anonymous_15)
FN:120,(anonymous_16)
FN:124,(anonymous_17)
FN:141,get
FN:152,(anonymous_20)
FN:153,(anonymous_21)
FN:157,(anonymous_22)
FN:170,login
FN:197,logout
FN:203,(anonymous_26)
FNF:18
FNH:16
FNDA:31,loggedIn
FNDA:22,getQueryString
FNDA:14,(anonymous_8)
FNDA:8,setAuth
FNDA:43,getHeaders
FNDA:10,clearHeaders
FNDA:45,success
FNDA:21,post
FNDA:21,(anonymous_15)
FNDA:21,(anonymous_16)
FNDA:0,(anonymous_17)
FNDA:19,get
FNDA:19,(anonymous_20)
FNDA:19,(anonymous_21)
FNDA:0,(anonymous_22)
FNDA:20,login
FNDA:20,logout
FNDA:7,(anonymous_26)
DA:1,1
DA:2,1
DA:3,1
DA:16,1
DA:24,1
DA:25,31
DA:29,1
DA:30,1
DA:33,1
DA:42,1
DA:47,1
DA:48,22
DA:49,13
DA:50,14
DA:53,14
DA:58,1
DA:59,1
DA:62,1
DA:63,8
DA:64,8
DA:68,1
DA:69,43
DA:70,33
DA:75,1
DA:77,32
DA:81,1
DA:82,10
DA:83,10
DA:87,1
DA:88,45
DA:109,1
DA:115,21
DA:116,21
DA:117,21
DA:118,21
DA:119,21
DA:120,21
DA:121,21
DA:122,21
DA:123,21
DA:124,0
DA:126,21
DA:127,21
DA:129,0
DA:130,0
DA:141,1
DA:147,19
DA:148,19
DA:149,19
DA:150,19
DA:151,19
DA:152,19
DA:153,19
DA:154,19
DA:155,19
DA:156,19
DA:157,0
DA:159,19
DA:160,19
DA:162,0
DA:170,1
DA:171,20
DA:172,20
DA:173,13
DA:174,13
DA:175,12
DA:177,1
DA:180,8
DA:181,8
DA:182,8
DA:188,8
DA:189,8
DA:190,8
DA:192,0
DA:197,1
DA:198,20
DA:199,13
DA:200,13
DA:202,7
DA:203,7
DA:204,7
DA:205,7
LF:82
LH:76
BRDA:30,0,0,1
BRDA:30,0,1,0
BRDA:34,1,0,1
BRDA:34,1,1,0
BRDA:35,2,0,1
BRDA:35,2,1,0
BRDA:43,3,0,1
BRDA:43,3,1,0
BRDA:48,4,0,9
BRDA:48,4,1,13
BRDA:48,5,0,22
BRDA:48,5,1,15
BRDA:48,5,2,15
BRDA:51,6,0,2
BRDA:51,6,1,12
BRDA:68,7,0,1
BRDA:69,8,0,10
BRDA:69,8,1,33
BRDA:70,9,0,1
BRDA:70,9,1,32
BRDA:71,10,0,33
BRDA:71,10,1,32
BRDA:71,10,2,32
BRDA:71,10,3,32
BRDA:97,11,0,43
BRDA:97,11,1,2
BRDA:90,12,0,45
BRDA:90,12,1,45
BRDA:90,12,2,28
BRDA:90,12,3,44
BRDA:90,12,4,17
BRDA:90,12,5,28
BRDA:90,12,6,26
BRDA:90,12,7,2
BRDA:90,12,8,0
BRDA:90,12,9,0
BRDA:112,13,0,0
BRDA:117,14,0,0
BRDA:117,14,1,21
BRDA:117,15,0,21
BRDA:117,15,1,13
BRDA:121,16,0,0
BRDA:121,16,1,21
BRDA:122,17,0,0
BRDA:122,17,1,21
BRDA:144,18,0,0
BRDA:149,19,0,1
BRDA:149,19,1,18
BRDA:149,20,0,19
BRDA:149,20,1,18
BRDA:154,21,0,0
BRDA:154,21,1,19
BRDA:155,22,0,0
BRDA:155,22,1,19
BRDA:170,23,0,6
BRDA:172,24,0,13
BRDA:172,24,1,7
BRDA:174,25,0,12
BRDA:174,25,1,1
BRDA:181,26,0,8
BRDA:181,26,1,0
BRDA:181,27,0,8
BRDA:181,27,1,8
BRDA:198,28,0,13
BRDA:198,28,1,7
BRF:65
BRH:51
end_of_record
TN:
SF:/Volumes/x/code/rocketchat/Rocket.Chat.js.SDK/src/lib/driver.ts
FN:36,connectDefaults
FN:47,respondDefaults
......@@ -16,88 +208,88 @@ FN:184,setupMethodCache
FN:205,asyncCall
FN:209,(anonymous_22)
FN:213,(anonymous_23)
FN:226,callMethod
FN:237,cacheCall
FN:239,(anonymous_26)
FN:243,(anonymous_27)
FN:255,login
FN:272,(anonymous_29)
FN:276,(anonymous_30)
FN:283,logout
FN:284,(anonymous_32)
FN:295,subscribe
FN:296,(anonymous_34)
FN:300,(anonymous_35)
FN:322,unsubscribe
FN:332,unsubscribeAll
FN:333,(anonymous_38)
FN:340,subscribeToMessages
FN:342,(anonymous_40)
FN:373,reactToMessages
FN:376,(anonymous_42)
FN:401,respondToMessages
FN:413,(anonymous_44)
FN:419,(anonymous_45)
FN:419,(anonymous_46)
FN:492,getRoomId
FN:497,getRoomName
FN:506,getDirectMessageRoomId
FN:507,(anonymous_50)
FN:511,joinRoom
FN:523,leaveRoom
FN:535,joinRooms
FN:536,(anonymous_56)
FN:543,prepareMessage
FN:553,sendMessage
FN:562,sendToRoomId
FN:566,(anonymous_60)
FN:577,sendToRoom
FN:578,(anonymous_62)
FN:586,sendDirectToUser
FN:587,(anonymous_64)
FN:228,callMethod
FN:239,cacheCall
FN:241,(anonymous_26)
FN:245,(anonymous_27)
FN:257,login
FN:274,(anonymous_29)
FN:278,(anonymous_30)
FN:285,logout
FN:286,(anonymous_32)
FN:297,subscribe
FN:298,(anonymous_34)
FN:302,(anonymous_35)
FN:324,unsubscribe
FN:334,unsubscribeAll
FN:335,(anonymous_38)
FN:342,subscribeToMessages
FN:344,(anonymous_40)
FN:375,reactToMessages
FN:378,(anonymous_42)
FN:403,respondToMessages
FN:415,(anonymous_44)
FN:421,(anonymous_45)
FN:421,(anonymous_46)
FN:500,getRoomId
FN:505,getRoomName
FN:514,getDirectMessageRoomId
FN:515,(anonymous_50)
FN:519,joinRoom
FN:531,leaveRoom
FN:543,joinRooms
FN:544,(anonymous_56)
FN:551,prepareMessage
FN:561,sendMessage
FN:570,sendToRoomId
FN:574,(anonymous_60)
FN:585,sendToRoom
FN:586,(anonymous_62)
FN:594,sendDirectToUser
FN:595,(anonymous_64)
FNF:55
FNH:40
FNH:41
FNDA:36,connectDefaults
FNDA:12,respondDefaults
FNDA:21,(anonymous_10)
FNDA:10,respondDefaults
FNDA:3,(anonymous_10)
FNDA:0,useLog
FNDA:31,connect
FNDA:31,(anonymous_13)
FNDA:27,(anonymous_14)
FNDA:30,connect
FNDA:30,(anonymous_13)
FNDA:26,(anonymous_14)
FNDA:0,(anonymous_15)
FNDA:4,(anonymous_16)
FNDA:27,(anonymous_17)
FNDA:26,(anonymous_17)
FNDA:0,disconnect
FNDA:0,(anonymous_19)
FNDA:31,setupMethodCache
FNDA:14,asyncCall
FNDA:30,setupMethodCache
FNDA:15,asyncCall
FNDA:0,(anonymous_22)
FNDA:14,(anonymous_23)
FNDA:0,callMethod
FNDA:13,cacheCall
FNDA:15,(anonymous_23)
FNDA:1,callMethod
FNDA:10,cacheCall
FNDA:0,(anonymous_26)
FNDA:13,(anonymous_27)
FNDA:22,login
FNDA:22,(anonymous_29)
FNDA:10,(anonymous_27)
FNDA:24,login
FNDA:24,(anonymous_29)
FNDA:0,(anonymous_30)
FNDA:0,logout
FNDA:0,(anonymous_32)
FNDA:18,subscribe
FNDA:18,(anonymous_34)
FNDA:18,(anonymous_35)
FNDA:16,subscribe
FNDA:16,(anonymous_34)
FNDA:16,(anonymous_35)
FNDA:0,unsubscribe
FNDA:0,unsubscribeAll
FNDA:0,(anonymous_38)
FNDA:18,subscribeToMessages
FNDA:18,(anonymous_40)
FNDA:11,reactToMessages
FNDA:93,(anonymous_42)
FNDA:9,respondToMessages
FNDA:16,subscribeToMessages
FNDA:16,(anonymous_40)
FNDA:9,reactToMessages
FNDA:72,(anonymous_42)
FNDA:7,respondToMessages
FNDA:0,(anonymous_44)
FNDA:15,(anonymous_45)
FNDA:15,(anonymous_46)
FNDA:13,(anonymous_45)
FNDA:13,(anonymous_46)
FNDA:6,getRoomId
FNDA:5,getRoomName
FNDA:2,getRoomName
FNDA:2,getDirectMessageRoomId
FNDA:2,(anonymous_50)
FNDA:4,joinRoom
......@@ -122,8 +314,8 @@ DA:19,1
DA:36,1
DA:37,36
DA:47,1
DA:48,12
DA:50,21
DA:48,10
DA:50,3
DA:67,1
DA:76,1
DA:88,1
......@@ -131,280 +323,279 @@ DA:98,1
DA:108,1
DA:109,0
DA:129,1
DA:130,31
DA:131,31
DA:132,31
DA:133,31
DA:134,31
DA:142,31
DA:143,31
DA:144,31
DA:145,31
DA:146,31
DA:130,30
DA:131,30
DA:132,30
DA:133,30
DA:134,30
DA:142,30
DA:143,30
DA:144,30
DA:145,30
DA:146,30
DA:147,4
DA:148,4
DA:149,4
DA:150,4
DA:151,4
DA:156,31
DA:157,31
DA:158,27
DA:160,27
DA:161,27
DA:162,27
DA:156,30
DA:157,30
DA:158,26
DA:160,26
DA:161,26
DA:162,26
DA:171,1
DA:172,0
DA:173,0
DA:174,0
DA:185,31
DA:186,31
DA:194,31
DA:185,30
DA:186,30
DA:194,30
DA:205,1
DA:206,14
DA:207,14
DA:208,14
DA:206,15
DA:207,15
DA:208,15