Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

README.md

keybase-bot

npm Travis CI

Script Keybase functionality in Node.js.

This module is a side-project/work in progress and may change or have crashes, but feel free to play with it. As long as you have a Keybase account, you can use this module to script basic Keybase commands.

Installation

  1. Install Node.js 8 or above. You can do this directly from the Node.js website or via your favorite package manager.
  2. Make sure that you have Keybase installed and running.
  3. Install keybase-bot. You can do this using either npm or Yarn.
    npm install keybase-bot
    # or
    yarn add keybase-bot

You're ready to make your first Keybase bot!

Hello world via your Keybase bot

Let's make a bot that says hello to the Keybase user kbot.

We recommend either creating a dedicated Keybase account for the bot, or if you decide to reuse your own account at the very least create a dedicated paperkey so you can revoke it later if needed.

const Bot = require('keybase-bot')

const bot = new Bot()
const username = 'your username'
const paperkey = 'your paperkey'
bot
  .init(username, paperkey, {verbose: false})
  .then(() => {
    console.log(`Your bot is initialized. It is logged in as ${bot.myInfo().username}`)

    const channel = {name: 'kbot,' + bot.myInfo().username, public: false, topicType: 'chat'}
    const message = {
      body: `Hello kbot! This is ${bot.myInfo().username} saying hello from my device ${
        bot.myInfo().devicename
      }`,
    }

    bot.chat
      .send(channel, message)
      .then(() => {
        console.log('Message sent!')
        bot.deinit()
      })
      .catch(error => {
        console.error(error)
        bot.deinit()
      })
  })
  .catch(error => {
    console.error(error)
    bot.deinit()
  })

To run the above bot, you want to save that code into a file and run it with node:

node <my-awesome-file-name>.js

This code is also in demos/hello-world.js, if you want to take a look in there. There are also some other cool bots in the demos directory, including a bot that tells you how many unread messages you have and a bot that does math for you and your friends. You can write a bot in any language that can compile to JavaScript and run on Node.js. We have some ES7+ (with async/await) demos in demos/ES7 and even a bot in Iced CoffeeScript! (in demos/iced)

API

Table of Contents

Bot

A Keybase bot.

init

Initialize your bot by starting an instance of the Keybase service and logging in using oneshot mode.

Parameters
  • username string The username of your bot's Keybase account.
  • paperkey string The paperkey of your bot's Keybase account.
  • options InitOptions The initialization options for your bot.
Examples
bot.init('username', 'paperkey')

Returns Promise<void>

initFromRunningService

Initialize your bot by using an existing running service with a logged in user.

Parameters
  • homeDir string The home directory of this currently running service. Leave blank to use the default homeDir for your system.
  • options InitOptions The initialization options for your bot.
Examples
bot.initFromRunningService()

Returns Promise<void>

myInfo

Get info about your bot!

Examples
const info = bot.myInfo()

Returns BotInfo? – Useful information like the username, device, and home directory of your bot. If your bot isn't initialized, you'll get null.

deinit

Deinitializes the bot by logging out, stopping the keybase service, and removing any leftover login files made by the bot. This should be run before your bot ends.

Examples
bot.deinit()

Returns Promise<void>

Bot Types

A collection of types used by the bot.

InitOptions

Options for initializing the bot.

Type: {verbose: boolean?, botLite: boolean?, disableTyping: boolean?}

Properties

BotInfo

Useful information like the username, device, home directory of your bot and configuration options.

Type: {username: string, devicename: string, homeDir: string?, botLite: boolean?, disableTyping: boolean?}

Properties

Chat

Extends ClientBase

The chat module of your Keybase bot. For more info about the API this module uses, you may want to check out keybase chat api.

joinChannel

Joins a team conversation.

Parameters
Examples
bot.chat.listConvsOnName('team_name').then(async teamConversations => {
  for (const conversation of teamConversations) {
    if (conversation.memberStatus !== 'active') {
      await bot.chat.join(conversation.channel)
      console.log('Joined team channel', conversation.channel)
    }
  }
})

Returns Promise<void>

leaveChannel

Leaves a team conversation.

Parameters
Examples
bot.chat.listConvsOnName('team_name').then(async teamConversations => {
  for (const conversation of teamConversations) {
    if (conversation.memberStatus === 'active') {
      await bot.chat.leave(conversation.channel)
      console.log('Left team channel', conversation.channel)
    }
  }
})

Returns Promise<void>

list

Lists your chats, with info on which ones have unread messages.

Parameters
  • options ChatListOptions An object of options that can be passed to the method.
Examples
bot.chat.list({unreadOnly: true}).then(chatConversations => console.log(chatConversations))

Returns Promise<Array<ChatConversation>> An array of chat conversations. If there are no conversations, the array is empty.

listChannels

Lists conversation channels in a team

Parameters
Examples
bot.chat.listChannels('team_name').then(chatConversations => console.log(chatConversations))

Returns Promise<Array<ChatConversation>> An array of chat conversations. If there are no conversations, the array is empty.

read

Reads the messages in a channel. You can read with or without marking as read.

Parameters
  • channel ChatChannel The chat channel to read messages in.
  • options ChatReadOptions An object of options that can be passed to the method.
Examples
alice.chat.read(channel).then(messages => console.log(messages))

Returns Promise<ReadResult> A summary of data about a message, including who send it, when, the content of the message, etc. If there are no messages in your channel, then an error is thrown.

send

Send a message to a certain channel.

Parameters
  • channel ChatChannel The chat channel to send the message in.
  • message ChatMessage The chat message to send.
  • options ChatSendOptions An object of options that can be passed to the method.
Examples
const channel = {name: 'kbot,' + bot.myInfo().username, public: false, topicType: 'chat'}
const message = {body: 'Hello kbot!'}
bot.chat.send(channel, message).then(() => console.log('message sent!'))

Returns Promise<SendResult>

createChannel

Creates a new blank conversation.

Parameters
Examples
bot.chat.createChannel(channel).then(() => console.log('conversation created'))

Returns Promise<void>

attach

Send a file to a channel.

Parameters
  • channel ChatChannel The chat channel to send the message in.
  • filename string The absolute path of the file to send.
  • options ChatAttachOptions An object of options that can be passed to the method.
Examples
bot.chat.attach(channel, '/Users/nathan/my_picture.png').then(() => console.log('Sent a picture!'))

Returns Promise<SendResult>

download

Download a file send via Keybase chat.

Parameters
  • channel ChatChannel The chat channel that the desired attacment to download is in.
  • messageId number The message id of the attached file.
  • output string The absolute path of where the file should be downloaded to.
  • options ChatDownloadOptions An object of options that can be passed to the method
Examples
bot.chat.download(channel, 325, '/Users/nathan/Downloads/file.png')

react

Reacts to a given message in a channel. Messages have messageId's associated with them, which you can learn in bot.chat.read.

Parameters
  • channel ChatChannel The chat channel to send the message in.
  • messageId number The id of the message to react to.
  • reaction string The reaction emoji, in colon form.
  • options ChatReactOptions An object of options that can be passed to the method.
Examples
bot.chat.react(channel, 314, ':+1:').then(() => console.log('Thumbs up!'))

Returns Promise<SendResult>

delete

Deletes a message in a channel. Messages have messageId's associated with them, which you can learn in bot.chat.read. Known bug: the GUI has a cache, and deleting from the CLI may not become apparent immediately.

Parameters
  • channel ChatChannel The chat channel to send the message in.
  • messageId number The id of the message to delete.
  • options ChatDeleteOptions An object of options that can be passed to the method.
Examples
bot.chat.delete(channel, 314).then(() => console.log('message deleted!'))

Returns Promise<void>

watchChannelForNewMessages

Listens for new chat messages on a specified channel. The onMessage function is called for every message your bot receives. This is pretty similar to watchAllChannelsForNewMessages, except it specifically checks one channel. Note that it receives messages your own bot posts, but from other devices. You can filter out your own messages by looking at a message's sender object. Hides exploding messages by default.

Parameters
  • channel ChatChannel The chat channel to watch.
  • onMessage OnMessage A callback that is triggered on every message your bot receives.
  • onError OnError A callback that is triggered on any error that occurs while the method is executing.
  • options ListenOptions Options for the listen method.
Examples
// Reply to all messages between you and `kbot` with 'thanks!'
const channel = {name: 'kbot,' + bot.myInfo().username, public: false, topicType: 'chat'}
const onMessage = message => {
  const channel = message.channel
  bot.chat.send(channel, {body: 'thanks!!!'})
}
bot.chat.watchChannelForNewMessages(channel, onMessage)

Returns Promise<void>

watchAllChannelsForNewMessages

This function will put your bot into full-read mode, where it reads everything it can and every new message it finds it will pass to you, so you can do what you want with it. For example, if you want to write a Keybase bot that talks shit at anyone who dares approach it, this is the function to use. Note that it receives messages your own bot posts, but from other devices. You can filter out your own messages by looking at a message's sender object. Hides exploding messages by default.

Parameters
  • onMessage OnMessage A callback that is triggered on every message your bot receives.
  • onError OnError A callback that is triggered on any error that occurs while the method is executing.
  • options ListenOptions Options for the listen method.
Examples
// Reply to incoming traffic on all channels with 'thanks!'
const onMessage = message => {
  const channel = message.channel
  bot.chat.send(channel, {body: 'thanks!!!'})
}
bot.chat.watchAllChannelsForNewMessages(onMessage)

Returns Promise<void>

Chat Types

A collection of types used by the Chat module.

ChatChannel

A Keybase chat channel. This can be a channel in a team, or just an informal channel between two users. name: the name of the team or comma-separated list of participants

Type: {name: string, public: boolean, membersType: MembersType, topicType: TopicType?, topicName: string?}

Properties

ChatMessage

A chat message. The content goes in the body property!

Type: {body: string}

Properties

ChatConversation

A chat conversation. This is essentially a chat channel plus some additional metadata.

Type: {id: string, channel: ChatChannel, unread: boolean, activeAt: number, activeAtMs: number, memberStatus: string}

Properties

ChatListOptions

Options for the list method of the chat module.

Type: {failOffline: boolean?, showErrors: boolean?, topicType: TopicType?, unreadOnly: boolean?}

Properties

ChatListChannelsOptions

Options for the listChannels method of the chat module.

Type: {topicType: TopicType?, membersType: MembersType?}

Properties
  • topicType TopicType?
  • membersType MembersType?

ChatReadOptions

Options for the read method of the chat module.

Type: {conversationId: string?, failOffline: boolean?, pagination: Pagination?, peek: boolean?, unreadOnly: boolean?}

Properties

ChatSendOptions

Options for the send method of the chat module.

Type: {conversationId: string?, nonblock: boolean?, membersType: MembersType, confirmLumenSend: boolean?}

Properties

ChatReactOptions

Options for the react method of the chat module.

Type: {conversationId: string?}

Properties

ChatAttachOptions

Options for the attach method of the chat module.

Type: {conversationId: string?, title: string?, preview: string?}

Properties

ChatDownloadOptions

Options for the download method of the chat module.

Type: {conversationId: string?, preview: string?, noStream: boolean?}

Properties

ChatDeleteOptions

Options for the delete method of the chat module.

Type: {conversationId: string?}

Properties

OnMessage

A function to call when a message is received.

Type: function (message: MessageSummary): (void | Promise<void>)

OnError

A function to call when an error occurs.

Type: function (error: Error): (void | Promise<void>)

Wallet

Extends ClientBase

The wallet module of your Keybase bot. For more info about the API this module uses, you may want to check out keybase wallet api.

balances

Provides a list of all accounts owned by the current Keybase user.

Examples
bot.wallet.balances().then(accounts => console.log(accounts))

Returns Promise<Array<Account>> An array of accounts. If there are no accounts, the array is empty.

history

Provides a list of all transactions in a single account.

Parameters
  • accountId string The id of an account owned by a Keybase user.
Examples
bot.wallet
  .history('GDUKZH6Q3U5WQD4PDGZXYLJE3P76BDRDWPSALN4OUFEESI2QL5UZHCK')
  .then(transactions => console.log(transactions))

Returns Promise<Array<Transaction>> An array of transactions related to the account.

details

Get details about a particular transaction

Parameters
  • transactionId string The id of the transaction you would like details about.
Examples
bot.wallet
  .details('e5334601b9dc2a24e031ffeec2fce37bb6a8b4b51fc711d16dec04d3e64976c4')
  .then(details => console.log(details))

Returns Promise<Transaction> An object of details about the transaction specified.

lookup

Lookup the primary Stellar account ID of a Keybase user.

Parameters
  • name string The name of the user you want to lookup. This can be either a Keybase username or a username of another account that is supported by Keybase if it is followed by an '@'.
Examples
const lookup1 = bot.wallet.lookup('patrick')
// 'patrick' on Keybase is 'patrickxb' on twitter
const lookup2 = bot.wallet.lookup('patrcikxb@twitter')
// Using Lodash's `isEqual` since objects with same values aren't equal in JavaScript
_.isEqual(lookup1, lookup2) // => true

Returns Promise<{accountID: string, username: string}> An object containing the account ID and Keybase username of the found user.

send

Send lumens (XLM) via Keybase with your bot!

Parameters
  • recipient string Who you're sending your money to. This can be a Keybase user, stellar address, or a username of another account that is supported by Keybase if it is followed by an '@'.
  • amount string The amount of XLM to send.
  • currency string Adds a currency value to the amount specified. For example, adding 'USD' would send
  • message string The message for your payment
Examples
bot.wallet.send('nathunsmitty', '3.50') // Send 3.50 XLM to Keybase user `nathunsmitty`
bot.wallet.send('nathunsmitty@github', '3.50') // Send 3.50 XLM to GitHub user `nathunsmitty`
bot.wallet.send('nathunsmitty', '3.50', 'USD') // Send $3.50 worth of lumens to Keybase user `nathunsmitty`
bot.wallet.send('nathunsmitty', '3.50', 'USD', 'Shut up and take my money!') // Send $3.50 worth of lumens to Keybase user `nathunsmitty` with a memo

Returns Promise<Transaction> The trasaction object of the transaction.

batch

Send lumens (XLM) via Keybase to more than one user at once. As opposed to the normal bot.wallet.send command, this can get multiple transactions into the same 5-second Stellar ledger.

Parameters
  • batchId string example, if sending a bunch of batches for an airdrop, you could pass them all airdrop2025.
  • payments Array<PaymentBatchItem> an array of objects containing recipients and XLM of the form {"recipient": "someusername", "amount": "1.234", "message", "hi there"}
Examples
bot.wallet.batch("airdrop2040",[{"recipient":"a1","amount": "1.414", "message": "hi a1, yes 1"},{"recipient": "a2", "amount": "3.14159", "message": "hi a2, yes 2"},}])

Returns Promise<BatchResult> an object

cancel

If you send XLM to a Keybase user who has not established a wallet, you can cancel the payment before the recipient claims it and the XLM will be returned to your account.

Parameters
  • transactionId string The id of the transaction to cancel.
Examples
bot.wallet
  .cancel('e5334601b9dc2a24e031ffeec2fce37bb6a8b4b51fc711d16dec04d3e64976c4')
  .then(() => console.log('Transaction successfully canceled!'))

Returns Promise<void>

Wallet Types

A collection of types used by the Wallet module.

Asset

An asset.

Type: {type: string, code: string, issuer: string, verifiedDomain: string, issuerName: string}

Properties

ExchangeRate

An exchange rate, which specifies a currency and the rate of exchange between an asset and that currency.

Type: {currency: string, rate: string}

Properties

Balance

A balance.

Type: {asset: Asset, amount: string, limit: string}

Properties

Account

An account, with money inside!

Type: {accountId: string, name: string, isPrimary: boolean, balance: (null | Array<Balance>), exchangeRate: ExchangeRate}

Properties

Transaction

A transaction, where a user sends money to another user.

Type: {txId: string, time: number, status: PaymentStatus, statusDetail: string, amount: string, asset: Asset, displayAmount: string, displayCurrency: string, fromStellar: string, toStellar: string, fromUsername: string, toUsername: string, note: string, noteErr: string, unread: boolean}

Properties

PaymentStatus

The status of a payment.

Type: ("none" | "pending" | "claimable" | "completed" | "error" | "unknown" | "canceled")

BatchResult

A batch send result

Type: {payments: Array<BatchItemResult>, startTime: number, preparedTime: number, allSubmittedTime: number, endTime: number, overallDurationMs: number, prepareDurationMs: number, submitDurationMs: number, waitDurationMs: number, countSuccess: number, countError: number, countPending: number, avgDurationMs: number, avgSuccessDurationMs: number, avgErrorDurationMs: number}

Properties

PaymentBatchItem

In batch sends, one individual send

Type: {recipient: string, amount: string, message: string?}

Properties

Contributions

Make sure that you have Node, Yarn, and the Keybase application installed. We also use developer tools such as EditorConfig, ESLint, Flow, and Prettier so you'll probably want to make sure that your development is configured to use those tools somewhere in your code writing process.

Setting up the source code

  1. Clone this repo.
  2. Install dependencies with yarn.
  3. Build the bot in watch mode with yarn dev.
  4. Build the bot for production with yarn build.
  5. Build the docs for the bot with yarn docs.

That's it. We accept changes via Pull Requests; please make sure that any changes you make build successfully and pass Flow, Prettier, and ESLint checks. We'd also really appreciate it if your PR could follow the Conventional Commit specification. If you're adding a new feature, please add/update tests, demos, documentation, and whatever else makes sense to go with it. If you have any questions about contributing, please feel free to ask a maintainer!

Release

We automatically generate a CHANGELOG and version (using Semantic Versioning) keybase-bot with standard-version. To cut a new release:

  1. Make sure all commits that are to be included in the release are squash-merged into master branch.
  2. On your local copy of the bot, checkout master and ensure it's up to date with origin/master.
  3. Run standard-version with the command yarn release.
  4. Push the new git tags to origin. (git push --follow-tags origin master)
  5. Publish to npm with yarn publish.

License

BSD-3-Clause