## Classes
object
* [.getCabalSettings(key)](#Client+getCabalSettings) ⇒ object
* [.writeCabalSettings(key, settings)](#Client+writeCabalSettings)
* [.resolveName(name, [cb])](#Client+resolveName)
* [.createCabal()](#Client+createCabal) ⇒ Promise
* [.addCabal(key, opts, cb)](#Client+addCabal) ⇒ Promise
* [.focusCabal(key)](#Client+focusCabal)
* [.removeCabal(key, cb)](#Client+removeCabal)
* [.getDetails()](#Client+getDetails) ⇒ [CabalDetails](#CabalDetails)
* [.getCabalKeys()](#Client+getCabalKeys) ⇒ Array.<string>
* [.getCurrentCabal()](#Client+getCurrentCabal) ⇒ [CabalDetails](#CabalDetails)
* [.addCommand([name], [cmd])](#Client+addCommand)
* [.removeCommand([name])](#Client+removeCommand)
* [.getCommands()](#Client+getCommands)
* [.addAlias([longCmd], [shortCmd])](#Client+addAlias)
* [.cabalToDetails([cabal])](#Client+cabalToDetails) ⇒ [CabalDetails](#CabalDetails)
* [.addStatusMessage(message, channel, [cabal])](#Client+addStatusMessage)
* [.clearStatusMessages(channel, [cabal])](#Client+clearStatusMessages)
* [.getUsers([cabal])](#Client+getUsers) ⇒ Array.<Object>
* [.getJoinedChannels([cabal])](#Client+getJoinedChannels) ⇒ Array.<Object>
* [.getChannels([cabal])](#Client+getChannels) ⇒ Array.<Object>
* [.subscribe(listener, [cabal])](#Client+subscribe)
* [.unsubscribe(listener, [cabal])](#Client+unsubscribe)
* [.getMessages([opts], [cb], [cabal])](#Client+getMessages)
* [.searchMessages([searchString], [opts], [cabal])](#Client+searchMessages) ⇒ Promise
* [.getNumberUnreadMessages(channel, [cabal])](#Client+getNumberUnreadMessages) ⇒ number
* [.getNumberMentions([channel], [cabal])](#Client+getNumberMentions)
* [.getMentions([channel], [cabal])](#Client+getMentions)
* [.focusChannel([channel], [keepUnread], [cabal])](#Client+focusChannel)
* [.unfocusChannel([channel], [newChannel], [cabal])](#Client+unfocusChannel)
* [.getCurrentChannel()](#Client+getCurrentChannel) ⇒ string
* [.markChannelRead(channel, [cabal])](#Client+markChannelRead)
* _static_
* [.getDatabaseVersion()](#Client.getDatabaseVersion) ⇒ string
* [.generateKey()](#Client.generateKey) ⇒ string
* [.scrubKey(key)](#Client.scrubKey) ⇒ string
* [.getCabalDirectory()](#Client.getCabalDirectory) ⇒ string
* [.getCabalSettingsFile()](#Client.getCabalSettingsFile) ⇒ string
* * *
### new Client([opts])
Create a client instance from which to manage multiple
[`cabal-core`](https://github.com/cabal-club/cabal-core/) instances.
**Params**
- *opts* object
- aliases object - key/value pairs of `alias` -> `command name`
- commands object - key/value pairs of `command name` -> `command object`, which has the following properties:
- call function - command function with the following signature `command.call(cabal, res, arg)`
- help function - return the help string for this command
- category Array.<string> - a list of categories this commands belongs to
- alias Array.<string> - a list of command aliases
- config object
- temp boolean - if `temp` is true no data is persisted to disk.
- *dbdir* string - the directory to store the cabal data
- *preferredPort* string - the port cabal will listen on for traffic
- *maxFeeds* number = 1000 - max amount of feeds to sync
- *persistentCache* object - specify a `read` and `write` to create a persistent DNS cache
- read function - async cache lookup function
- write function - async cache write function
* * *
### client.readCabalSettingsFile() ⇒ object
Read and parse the contents of the settings.yml file.
If the file doesn't exist, return {}.
**Returns**: object - the contents of the settings file
* * *
### client.getCabalSettings(key) ⇒ object
Get the settings for a given cabal from the settings.yml file.
If the file doesn't exist or the given cabal has no settings, return the default settings.
**Returns**: object - the cabal settings
**Params**
- key string - the cabal
* * *
### client.writeCabalSettings(key, settings)
Reads the settings from the settings.yml file, updates the settings for the given cabal, then
writes the revised settings to the settings.yml file.
**Params**
- key string - the cabal
- settings object - the cabal settings
* * *
### client.resolveName(name, [cb])
Resolve the DNS shortname `name`. If `name` is already a cabal key, it will
be returned and the DNS lookup is aborted.
If `name` is a whisper:// key, a DHT lookup for the passed-in key will occur.
Once a match is found, it is assumed to be a cabal key, which is returned.
Returns the cabal key in `cb`. If `cb` is null a Promise is returned.
**Params**
- name string - the DNS shortname, or whisper:// shortname
- *cb* function - The callback to be called when lookup succeeds
* * *
### client.createCabal() ⇒ Promise
Create a new cabal.
**Returns**: Promise - a promise that resolves into a `CabalDetails` instance.
* * *
### client.addCabal(key, opts, cb) ⇒ Promise
Add/load the cabal at `key`.
**Returns**: Promise - a promise that resolves into a `CabalDetails` instance.
**Params**
- key string
- opts object
- cb function - a function to be called when the cabal has been initialized.
* * *
### client.focusCabal(key)
Focus the cabal at `key`, used when you want to switch from one open cabal to another.
**Params**
- key string
* * *
### client.removeCabal(key, cb)
Remove the cabal `key`. Destroys everything related to it
(the data is however still persisted to disk, fret not!).
**Params**
- key string
- cb function
* * *
### client.getDetails() ⇒ [CabalDetails](#CabalDetails)
Returns the details of a cabal for the given key.
* * *
### client.getCabalKeys() ⇒ Array.<string>
Returns a list of cabal keys, one for each open cabal.
* * *
### client.getCurrentCabal() ⇒ [CabalDetails](#CabalDetails)
Get the current cabal.
* * *
### client.addCommand([name], [cmd])
Add a command to the set of supported commands.
**Params**
- *name* string - the long-form command name
- *cmd* object - the command object
- *help* function - function returning help text
- *alias* array - array of string aliases
- *call* function - implementation of the command receiving (cabal, res, arg) arguments
* * *
### client.removeCommand([name])
Remove a command.
**Params**
- *name* string - the command name
* * *
### client.getCommands()
Get an object mapping command names to command objects.
* * *
### client.addAlias([longCmd], [shortCmd])
Add an alias `shortCmd` for `longCmd`
**Params**
- *longCmd* string - command to be aliased
- *shortCmd* string - alias
* * *
### client.cabalToDetails([cabal]) ⇒ [CabalDetails](#CabalDetails)
Returns a `CabalDetails` instance for the passed in `cabal-core` instance.
**Params**
- *cabal* Cabal = this.currentCabal
* * *
### client.addStatusMessage(message, channel, [cabal])
Add a status message, displayed client-side only, to the specified channel and cabal.
If no cabal is specified, the currently focused cabal is used.
**Params**
- message object
- channel string
- *cabal* Cabal = this.currentCabal
* * *
### client.clearStatusMessages(channel, [cabal])
Clear status messages for the specified channel.
**Params**
- channel string
- *cabal* Cabal = this.currentCabal
* * *
### client.getUsers([cabal]) ⇒ Array.<Object>
Returns a list of all the users for the specified cabal.
If no cabal is specified, the currently focused cabal is used.
**Returns**: Array.<Object> - the list of users
**Params**
- *cabal* Cabal = this.currentCabal
* * *
### client.getJoinedChannels([cabal]) ⇒ Array.<Object>
Returns a list of channels the user has joined for the specified cabal.
If no cabal is specified, the currently focused cabal is used.
**Returns**: Array.<Object> - the list of Channels
**Params**
- *cabal* Cabal = this.currentCabal
* * *
### client.getChannels([cabal]) ⇒ Array.<Object>
Returns a list of all channels for the specified cabal.
If no cabal is specified, the currently focused cabal is used.
**Returns**: Array.<Object> - the list of Channels
**Params**
- *cabal* Cabal = this.currentCabal
* * *
### client.subscribe(listener, [cabal])
Add a new listener for the `update` event.
**Params**
- listener function
- *cabal* Cabal = this.currentCabal
* * *
### client.unsubscribe(listener, [cabal])
Remove a previously added listener.
**Params**
- listener function
- *cabal* Cabal = this.currentCabal
* * *
### client.getMessages([opts], [cb], [cabal])
Returns a list of messages according to `opts`. If `cb` is null, a Promise is returned.
**Params**
- *opts* Object
- *olderThan* number - timestamp in epoch time. we want to get messages that are *older* than this ts
- *newerThan* number - timestamp in epoch time. we want to get messages that are *newer* than this ts
- *amount* number - amount of messages to get
- *channel* string - channel to get messages from. defaults to currently focused channel
- *cb* function - the callback to be called when messages are retreived
- *cabal* Cabal = this.currentCabal
* * *
### client.searchMessages([searchString], [opts], [cabal]) ⇒ Promise
Searches for messages that include the search string according to `opts`.
Each returned match contains a message string and a matchedIndexes array containing the indexes at which the search string was found in the message
**Returns**: Promise - a promise that resolves into a list of matches.
**Params**
- *searchString* string - string to match messages against
- *opts* Object
- *olderThan* number - timestamp in epoch time. we want to search through messages that are *older* than this ts
- *newerThan* number - timestamp in epoch time. we want to search through messages that are *newer* than this ts
- *amount* number - amount of messages to be search through
- *channel* string - channel to get messages from. defaults to currently focused channel
- *cabal* Cabal = this.currentCabal
* * *
### client.getNumberUnreadMessages(channel, [cabal]) ⇒ number
Returns the number of unread messages for `channel`.
**Params**
- channel string
- *cabal* Cabal = this.currentCabal
* * *
### client.getNumberMentions([channel], [cabal])
Returns the number of mentions in `channel`.
**Params**
- *channel* string = "this.getCurrentChannel()"
- *cabal* Cabal = this.currentCabal
* * *
### client.getMentions([channel], [cabal])
Returns a list of messages that triggered a mention in channel.
**Params**
- *channel* string = "this.getCurrentChannel()"
- *cabal* Cabal = this.currentCabal
* * *
### client.focusChannel([channel], [keepUnread], [cabal])
View `channel`, closing the previously focused channel.
**Params**
- *channel* \* = this.getCurrentChannel()
- *keepUnread* boolean = false
- *cabal* Cabal = this.currentCabal
* * *
### client.unfocusChannel([channel], [newChannel], [cabal])
Close `channel`.
**Params**
- *channel* string = "this.getCurrentChannel()"
- *newChannel* string = null
- *cabal* Cabal = this.currentCabal
* * *
### client.getCurrentChannel() ⇒ string
Returns the currently focused channel name.
* * *
### client.markChannelRead(channel, [cabal])
Mark the channel as read.
**Params**
- channel string
- *cabal* Cabal = this.currentCabal
* * *
### Client.getDatabaseVersion() ⇒ string
Get the current database version.
* * *
### Client.generateKey() ⇒ string
Returns a 64 character hex string i.e. a newly generated cabal key.
Useful if you want to programmatically create a new cabal as part of a shell pipeline.
* * *
### Client.scrubKey(key) ⇒ string
Removes URI scheme, URI search params (if present), and returns the cabal key as a 64 character hex string
**Returns**: string - the scrubbed key
**Params**
- key string - the key to scrub
**Example**
```js
Client.scrubKey('cabal://12345678...?admin=7331b4b..')
// => '12345678...'
```
* * *
### Client.getCabalDirectory() ⇒ string
Returns a string path of where all of the cabals are stored on the hard drive.
**Returns**: string - the cabal directory
* * *
### Client.getCabalSettingsFile() ⇒ string
Returns a string path of where the cabal settings are stored on the hard drive.
**Returns**: string - the cabal settings file path
* * *
## CabalDetails
**Emits**: [update](#CabalDetails+event_update), [init](#CabalDetails+event_init), [info](#CabalDetails+event_info), [user-updated](#CabalDetails+event_user-updated), [new-channel](#CabalDetails+event_new-channel), [new-message](#CabalDetails+event_new-message), [private-message](#CabalDetails+event_private-message), [publish-message](#CabalDetails+event_publish-message), [publish-private-message](#CabalDetails+event_publish-private-message), [publish-nick](#CabalDetails+event_publish-nick), [status-message](#CabalDetails+event_status-message), [topic](#CabalDetails+event_topic), [channel-focus](#CabalDetails+event_channel-focus), [channel-join](#CabalDetails+event_channel-join), [channel-leave](#CabalDetails+event_channel-leave), [cabal-focus](#CabalDetails+event_cabal-focus), [started-peering](#CabalDetails+event_started-peering), [stopped-peering](#CabalDetails+event_stopped-peering)
* [CabalDetails](#CabalDetails)
* [new CabalDetails({, done)](#new_CabalDetails_new)
* [.processLine([line], [cb])](#CabalDetails+processLine)
* [.publishMessage(msg, [opts], [cb])](#CabalDetails+publishMessage)
* [.publishNick(nick, [cb])](#CabalDetails+publishNick)
* [.publishChannelTopic([channel], topic, cb)](#CabalDetails+publishChannelTopic)
* [.getTopic([channel])](#CabalDetails+getTopic) ⇒ string
* [.getChannelMembers([channel])](#CabalDetails+getChannelMembers) ⇒ Array.<object>
* [.addStatusMessage(message, [channel])](#CabalDetails+addStatusMessage)
* [.getChannels([opts])](#CabalDetails+getChannels) ⇒ Array.<string>
* [.getCurrentChannel()](#CabalDetails+getCurrentChannel) ⇒ string
* [.getCurrentChannelDetails()](#CabalDetails+getCurrentChannelDetails) ⇒ ChannelDetails
* [.clearVirtualMessages([channel])](#CabalDetails+clearVirtualMessages)
* [.getPrivateMessageList()](#CabalDetails+getPrivateMessageList)
* [.isChannelPrivate()](#CabalDetails+isChannelPrivate)
* [.joinPrivateMessage(channel)](#CabalDetails+joinPrivateMessage)
* [.leavePrivateMessage(channel)](#CabalDetails+leavePrivateMessage)
* [.publishPrivateMessage(msg, recipientKey, [cb])](#CabalDetails+publishPrivateMessage)
* [.getJoinedChannels()](#CabalDetails+getJoinedChannels) ⇒ Array.<string>
* [.getLocalUser()](#CabalDetails+getLocalUser) ⇒ user
* [.getLocalName()](#CabalDetails+getLocalName) ⇒ string
* [.joinChannel(channel)](#CabalDetails+joinChannel)
* [.leaveChannel(channel)](#CabalDetails+leaveChannel)
* [.archiveChannel(channel, [reason], cb(err))](#CabalDetails+archiveChannel)
* [.unarchiveChannel(channel, [reason], cb(err))](#CabalDetails+unarchiveChannel)
* [.getUsers()](#CabalDetails+getUsers) ⇒ object
* [._destroy()](#CabalDetails+_destroy)
* ["update"](#CabalDetails+event_update)
* ["init"](#CabalDetails+event_init)
* ["user-updated"](#CabalDetails+event_user-updated)
* ["new-channel"](#CabalDetails+event_new-channel)
* ["new-message"](#CabalDetails+event_new-message)
* ["private-message"](#CabalDetails+event_private-message)
* ["publish-message"](#CabalDetails+event_publish-message)
* ["publish-private-message"](#CabalDetails+event_publish-private-message)
* ["publish-nick"](#CabalDetails+event_publish-nick)
* ["status-message"](#CabalDetails+event_status-message)
* ["topic"](#CabalDetails+event_topic)
* ["channel-focus"](#CabalDetails+event_channel-focus)
* ["channel-join"](#CabalDetails+event_channel-join)
* ["channel-leave"](#CabalDetails+event_channel-leave)
* ["cabal-focus"](#CabalDetails+event_cabal-focus)
* ["started-peering"](#CabalDetails+event_started-peering)
* ["stopped-peering"](#CabalDetails+event_stopped-peering)
* ["update"](#CabalDetails+event_update)
* ["info"](#CabalDetails+event_info)
* * *
### new CabalDetails({, done)
**Params**
- { object - cabal , commands, aliases }
- done function - the function to be called after the cabal is initialized
* * *
### cabalDetails.processLine([line], [cb])
Interpret a line of input from the user.
This may involve running a command or publishing a message to the current
channel.
**Params**
- *line* string - input from the user
- *cb* function - callback called when the input is processed
* * *
### cabalDetails.publishMessage(msg, [opts], [cb])
Publish a message up to consumer. See
[`cabal-core`](https://github.com/cabal-club/cabal-core/)
for the full list of options.
**Params**
- msg object - the full message object
- *opts* object - options passed down to cabal.publish
- *cb* function - callback function called when message is published
**Example**
```js
cabalDetails.publishMessage({
type: 'chat/text',
content: {
text: 'hello world',
channel: 'cabal-dev'
}
})
```
* * *
### cabalDetails.publishNick(nick, [cb])
Announce a new nickname.
**Params**
- nick string
- *cb* function - will be called after the nick is published
* * *
### cabalDetails.publishChannelTopic([channel], topic, cb)
Publish a new channel topic to `channel`.
**Params**
- *channel* string = "this.chname"
- topic string
- cb function - will be called when publishing has finished.
* * *
### cabalDetails.getTopic([channel]) ⇒ string
**Returns**: string - The current topic of `channel` as a string
**Params**
- *channel* string = "this.chname"
* * *
### cabalDetails.getChannelMembers([channel]) ⇒ Array.<object>
Return the list of users that have joined `channel`.
Note: this can be a subset of all of the users in a cabal.
**Params**
- *channel* string = "this.chname"
* * *
### cabalDetails.addStatusMessage(message, [channel])
Add a status message, visible locally only.
**Params**
- message object
- *channel* string = "this.chname"
* * *
### cabalDetails.getChannels([opts]) ⇒ Array.<string>
**Returns**: Array.<string> - a list of all the channels in this cabal. Does not return channels with 0 members.
**Params**
- *opts* object
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| includeArchived | boolean | Determines whether to include archived channels or not. Defaults to false. |
| includePM | boolean | Determines whether to include private message channels or not. Defaults to false. |
| onlyJoined | boolean | Determines whether to limit returned channels to only those that are joined or not. Defaults to false. |
* * *
### cabalDetails.getCurrentChannel() ⇒ string
**Returns**: string - The name of the current channel
* * *
### cabalDetails.getCurrentChannelDetails() ⇒ ChannelDetails
**Returns**: ChannelDetails - A ChannelDetails object for the current chanel
* * *
### cabalDetails.clearVirtualMessages([channel])
Remove all of the virtual (i.e. status) messages associated with this channel.
Virtual messages are local only.
**Params**
- *channel* string = "this.chname"
* * *
### cabalDetails.getPrivateMessageList()
Get the list of currently opened private message channels.
**Returns{string[]}**: A list of all public keys you have an open PM with (hidden users are removed from list).
* * *
### cabalDetails.isChannelPrivate()
Query if the passed in channel name is private or not
**Returns{boolean}**: true if channel is private, false if not (or if it doesn't exist)
* * *
### cabalDetails.joinPrivateMessage(channel)
Join a private message channel if it is not already joined.
**Params**
- channel string - the key of the PM to join
* * *
### cabalDetails.leavePrivateMessage(channel)
Leave a private message channel if it has not already been left.
**Params**
- channel string - the key of the PM to leave
* * *
### cabalDetails.publishPrivateMessage(msg, recipientKey, [cb])
Send a private message to a recipient. Open and focus a new private message channel if one doesn't exist already.
**Params**
- msg string - a message object conforming to any type of chat message (e.g. `chat/text` or `chat/emote`),
see CabalDetails.publishMessage for more information
- recipientKey string - the public key of the recipient
- *cb* function - optional callback triggered after trying to publish (returns err if failed)
* * *
### cabalDetails.getJoinedChannels() ⇒ Array.<string>
**Returns**: Array.<string> - A list of all of the channel names the user has joined. Excludes private message channels.
* * *
### cabalDetails.getLocalUser() ⇒ user
**Returns**: user - The local user for this cabal.
* * *
### cabalDetails.getLocalName() ⇒ string
**Returns**: string - The local user's username (or their truncated public key, if their
username is not set)
* * *
### cabalDetails.joinChannel(channel)
Join a channel. This is distinct from focusing a channel, as this actually tracks changes
and publishes a message announcing that you have joined the channel
**Params**
- channel string
* * *
### cabalDetails.leaveChannel(channel)
Leave a joined channel. This publishes a message announcing
that you have left the channel.
**Params**
- channel string
* * *
### cabalDetails.archiveChannel(channel, [reason], cb(err))
Archive a channel. Publishes a message announcing
that you have archived the channel, applying it to the views of others who have you as a moderator/admin.
**Params**
- channel string
- *reason* string
- cb(err) function - callback invoked when the operation has finished, with error as its only parameter
* * *
### cabalDetails.unarchiveChannel(channel, [reason], cb(err))
Unarchive a channel. Publishes a message announcing
that you have unarchived the channel.
**Params**
- channel string
- *reason* string
- cb(err) function - callback invoked when the operation has finished, with error as its only parameter
* * *
### cabalDetails.getUsers() ⇒ object
**Returns**: object - all of the users in this cabal. Each key is the public key of its
corresponding user.
* * *
### cabalDetails.\_destroy()
Destroy all of the listeners associated with this `details` instance
* * *
### "update"
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| local | boolean | |
| online | boolean | |
| name | string | The user's username |
| key | string | The user's public key |
| flags | Map.<string, string> | The user's array of flags per channel ("@" means cabal-wide"). Possible flags include {"admin", "mod", "normal", "hide", "mute", "block"}. |
* * *
### "init"
Fires when the cabal has finished initialization
**Kind**: event emitted by [CabalDetails](#CabalDetails)
* * *
### "user-updated"
Fires when a user has updated their nickname
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| key | string | Public key of the updated user |
| user | object | Object containing user information |
| user.name | string | Current nickname of the updated user |
* * *
### "new-channel"
Fires when a new channel has been created
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| channel | string | Name of the created channel |
* * *
### "new-message"
Fires when a new message has been posted
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| channel | string | Name of the channel the message was posted to |
| author | object | Object containing the user that posted the message |
| author.name | string | Nickname of the user |
| author.key | string | Public key of the user |
| author.local | boolean | True if user is the local user (i.e. at the keyboard and not someone else in the cabal) |
| author.online | boolean | True if the user is currently online |
| message | object | The message that was posted. See `cabal-core` for more complete message documentation. |
| message.key | string | Public key of the user posting the message (again, it's a quirk) |
| message.seq | number | Sequence number of the message in the user's append-only log |
| message.value | object | Message content, see `cabal-core` documentation for more information. |
* * *
### "private-message"
Fires when a new private message has been posted
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| channel | string | The public key corresponding to the private message channel |
| author | object | Object containing the user that posted the message |
| author.name | string | Nickname of the user |
| author.key | string | Public key of the user |
| author.local | boolean | True if user is the local user (i.e. at the keyboard and not someone else in the cabal) |
| author.online | boolean | True if the user is currently online |
| message | object | The message that was posted. See `cabal-core` for more complete message documentation. |
| message.key | string | Public key of the user posting the message (again, it's a quirk) |
| message.seq | number | Sequence number of the message in the user's append-only log |
| message.value | object | Message content, see `cabal-core` documentation for more information. |
* * *
### "publish-message"
Fires when the local user has published a new message
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| message | object | The message that was posted. See `cabal-core` for more complete message documentation. |
| message.type | string | Message type that was posted, e.g. `chat/text` or `chat/emote` |
| message.content | string | Message contents, e.g. channel and text if `chat/text` |
| message.timestamp | number | The time the message was published |
* * *
### "publish-private-message"
Fires when the local user has published a new private message
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| message | object | The message that was posted. See `cabal-core` for more complete message documentation. |
| message.type | string | Message type that was posted, e.g. `chat/text` or `chat/emote` |
| message.content | string | Message contents, e.g. channel and text if `chat/text` |
| message.timestamp | number | The time the message was published |
* * *
### "publish-nick"
Fires when the local user has published a new nickname
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| name | string | The nickname that was published |
* * *
### "status-message"
Fires when a status message has been created. These are only visible by the local user.
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| channel | string | Name of the channel the message was published to |
| message | object | |
| message.timestamp | number | Publish timestamp |
| message.text | string | The published status message contents |
* * *
### "topic"
Fires when a new channel topic has been set
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| channel | string | Name of the channel with the new topic |
| topic | string | Name of the channel with the new topic |
* * *
### "channel-focus"
Fires when the user has focused (i.e. switched to) a new channel
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| channel | string | Name of the focused channel |
* * *
### "channel-join"
Fires when a user has joined a channel
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| channel | string | Name of the joined channel |
| key | string | Public key of the user joining the channel |
| isLocal | boolean | True if it was the local user joining a new channel |
* * *
### "channel-leave"
Fires when a user has leaveed a channel
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| channel | string | Name of the leaved channel |
| key | string | Public key of the user leaving the channel |
| isLocal | boolean | True if it was the local user leaving a new channel |
* * *
### "cabal-focus"
Fires when another cabal has been focused
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| key | string | Key of the focused cabal |
* * *
### "started-peering"
Fires when the local user has connected directly with another peer
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| key | string | Public key of the other peer |
| name- | string | Name of the other peer |
* * *
### "stopped-peering"
Fires when the local user has disconnected with another peer
**Kind**: event emitted by [CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| key | string | Public key of the other peer |
| name- | string | Name of the other peer |
* * *
### "update"
Fires when any kind of change has happened to the cabal.
**Kind**: event emitted by [CabalDetails](#CabalDetails)
* * *
### "info"
Fires when a valid slash-command (/CabalDetails](#CabalDetails)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| command | string | The command that triggered the event & has emitted output |
* * *