A general-purpose bot library inspired by Hubot but written in Go. :robot:

Overview

Joe Bot πŸ€–

A general-purpose bot library inspired by Hubot but written in Go.


Joe is a library used to write chat bots in the Go programming language. It is very much inspired by the awesome Hubot framework developed by the folks at Github and brings its power to people who want to implement chat bots using Go.

Getting Started

Joe is a software library that is packaged as Go module. You can get it via:

go get github.com/go-joe/joe

Example usage

You can find all code examples, more explanation and complete recipes at https://joe-bot.net

Each bot consists of a chat Adapter (e.g. to integrate with Slack), a Memory implementation to remember key-value data (e.g. using Redis) and a Brain which routes new messages or custom events (e.g. receiving an HTTP call) to the corresponding registered handler functions.

By default joe.New(…) uses the CLI adapter which makes the bot read messages from stdin and respond on stdout. Additionally the bot will store key value data in-memory which means it will forget anything you told it when it is restarted. This default setup is useful for local development without any dependencies but you will quickly want to add other Modules to extend the bots capabilities.

The following example connects the Bot with a Slack workspace and stores key-value data in Redis. To allow the message handlers to access the memory we define them as functions on a custom ExampleBottype which embeds the joe.Bot.

package main

import (
	"fmt"

	"github.com/go-joe/joe"
	"github.com/go-joe/redis-memory"
	"github.com/go-joe/slack-adapter/v2"
)

type ExampleBot struct {
	*joe.Bot
}

func main() {
	b := &ExampleBot{
		Bot: joe.New("example",
			redis.Memory("localhost:6379"),
			slack.Adapter("xoxb-1452345…"),
		),
	}

	b.Respond("remember (.+) is (.+)", b.Remember)
	b.Respond("what is (.+)", b.WhatIs)

	err := b.Run()
	if err != nil {
		b.Logger.Fatal(err.Error())
	}
}

func (b *ExampleBot) Remember(msg joe.Message) error {
	key, value := msg.Matches[0], msg.Matches[1]
	msg.Respond("OK, I'll remember %s is %s", key, value)
	return b.Store.Set(key, value)
}

func (b *ExampleBot) WhatIs(msg joe.Message) error {
	key := msg.Matches[0]
	var value string
	ok, err := b.Store.Get(key, &value)
	if err != nil {
		return fmt.Errorf("failed to retrieve key %q from brain: %w", key, err)
	}

	if ok {
		msg.Respond("%s is %s", key, value)
	} else {
		msg.Respond("I do not remember %q", key)
	}

	return nil
}

Available modules

Joe ships with no third-party modules such as Redis integration to avoid pulling in more dependencies than you actually require. There are however already some modules that you can use directly to extend the functionality of your bot without writing too much code yourself.

If you have written a module and want to share it, please add it to this list and open a pull request.

Chat Adapters

Memory Modules

Other Modules

Built With

  • zap - Blazing fast, structured, leveled logging in Go
  • multierr - Package multierr allows combining one or more errors together
  • testify - A simple unit test library

Contributing

Please read CONTRIBUTING.md for details on our code of conduct and on the process for submitting pull requests to this repository.

Versioning

THIS SOFTWARE IS STILL IN ALPHA AND THERE ARE NO GUARANTEES REGARDING API STABILITY YET.

All significant (e.g. breaking) changes are documented in the CHANGELOG.md.

After the v1.0 release we plan to use SemVer for versioning. For the versions available, see the tags on this repository.

Authors

  • Friedrich Große - Initial work - fgrosse

See also the list of contributors who participated in this project.

License

This project is licensed under the BSD-3-Clause License - see the LICENSE file for details.

Acknowledgments

  • Hubot and its great community for the inspiration
  • embedmd for a cool tool to embed source code in markdown files
Issues
  • Add Reactions to Messages

    Add Reactions to Messages

    Summary

    Many chat services (e.g. Slack, Rocket.Chat, Mattermost, etc.) offer the ability to "react" to messages with emoji. It would be nice to be able to make use of that capability.

    Basic example

    func DoWork(msg joe.Message) error {
      msg.React(":+1:")
      time.Sleep(1 * time.Second)
      msg.Respond("Job is done")
    }
    

    Motivation

    Using reactions is an easy way to acknowledge that a command has been received without cluttering up the chat with intermediate results. Simple commands could even skip output entirely and just use reactions.

    Potential Issues

    Not all Adapters will be able to support reactions (e.g. CLI Adapter). A decision would be necessary for how to handle reactions in this case. My thought would be to fail silently (optionally with a logger warning) and to document that reactions are optional for adapters. An alternative would be to error if not available and to offer a capability to test if reactions are available ReactionsEnabled or perhaps msg.ReactIfEnabled.

    Edit 1

    Perhaps a pragmatic way to handle the absence of reactions would be a ReactOrRespond function that would add a reaction if able, respond if not.

    func DoWork(msg joe.Message) error {
      msg.ReactOrRespond(":+1:", "Job started")
      time.Sleep(1 * time.Second)
      msg.Respond("Job is done")
    }
    
    opened by dwmunster 10
  • Implement an API to allow chat adapters to implement emoji reactions

    Implement an API to allow chat adapters to implement emoji reactions

    Fixes #21

    The slack implementation is pretty much done but not yet really tested. Reviews and feedback welcome, otherwise I will probably merge this mid or end of next week :)

    opened by fgrosse 4
  • Slack interactive messages

    Slack interactive messages

    opened by d-kononov 4
  • Telegram integration

    Telegram integration

    Is there any example with Telegram? Would be cool to see a small example :)

    opened by talentlessguy 4
  • Registering a default response when no match

    Registering a default response when no match

    Fixes #25

    • improve documentation about how multiple matching event handlers are executed
    • add a way for handlers to prevent execution of later event handlers
    • use this in Bot.Respond(…) so only the first matching handler is executed
    • unit test it all
    opened by fgrosse 3
  • How to change default log level

    How to change default log level

    Hi, i'm just digging around how i can adjust the log level of the bot.

    Maybe you can add a simple example how the log-level can be adjusted?

    Thanks

    opened by eloo 3
  • Add VK adapter

    Add VK adapter

    VK Adapter: https://github.com/tdakkota/joe-vk-adapter

    This PR adds a link the repository in the README.

    opened by SevereCloud 2
  • Add link to Telegram adapter

    Add link to Telegram adapter

    I wrote an adapter for Telegram over the weekend...

    I also have a memory implementation using bolt

    Both still need a README with some documentation but I wanted to open these anyway in case anybody else is interested in this...

    opened by robertgzr 2
  • Storage

    Storage

    TODO: write changelog

    opened by fgrosse 2
  • Auth continued

    Auth continued

    • Make Auth.Grant(…) idempotent and do not unnecessarily add smaller scopes
    • Support extending permissions via Auth.Grant(…)
    • Add boolean return value to Auth.Grant(…) to indicate if a new permission was granted
    • Add Auth.Revoke(…) to remove permissions
    • Fix flaky unit test TestBrain_Memory
    • Fix flaky TestCLIAdapter_Register test
    opened by fgrosse 2
  • List support in Memory

    List support in Memory

    I'd really like to have support for lists in Memory implementations, without having to build it up from KV considering that some of the Memory implementations have first class support (Redis). Would you want to add this concept to joe?

    I'd also like to have Sets since my ultimate goal is actually a list of unique objects, and if we have List, and Set I can compose them into UniqList anyway.

    opened by mmlb 0
  • Allow for specifying whether message is DM in `ReceiveMessageEvent`

    Allow for specifying whether message is DM in `ReceiveMessageEvent`

    Currently, the standard joe.ReceiveMessageEvent sent by all documented adapters does not specify whether the message is "private" (a one-on-one chat in Slack, a /msg in IRC, etc).

    This can be useful in having handlers process commands differently (e.g. allow admin-level commands in direct chats) depending on the communication mode, without having to either parse the Channel or Data fields (which assumes the handler knows which adapter is being used) or having to use custom events, which assume adapter support.

    opened by deuill 0
  • Possible to send a message without having Message struct?

    Possible to send a message without having Message struct?

    Thanks for putting together this library, I'm just starting to explore it. I was wondering if there is a recommended method to send an arbitrary message to a channel without needing to "Respond" to a message that has come in.

    My [first] use case is that I want to send a message to a channel after receiving a webhook via the http-server.

    I suppose one way that I might be able to achieve this is to have the webhook handler publish a joe.ReceiveMessageEvent event with the desired channel that I want to send a message to, then listen for this 'silent' event emitted and respond to it. This will likely work, but it seems like quite a workaround to achieve my goal.

    Any insight you can provide would be appreciated.

    Thanks

    opened by neufeldtech 4
  • Prefix Scans for Storage Keys

    Prefix Scans for Storage Keys

    Closes #31.

    opened by dwmunster 0
  • Prefix Scans for Storage Keys

    Prefix Scans for Storage Keys

    Summary

    Since many uses of the Storage interface may have hierarchical keys, e.g. the permissions, it would be beneficial to have a way to iterate over keys matching a given prefix.

    Basic example

    for _, key := range a.store.KeysWithPrefix("joe.permissions.mymodule.") {
      ...
    }
    

    Motivation

    From #28

    Since we are iterating over all keys the bot knows we should expect that also non-permission keys are among them.

    I suggest you update your unit test to check this is also handled correctly.

    Rather than push this onto any developer who needs to interact with the permissions, we could require the Storage interface to support prefix scans. Some storage engines may have a higher performance way of doing prefix scans and we could take advantage of that. If the storage engine does not offer it, the bot could handle the naive looping over keys itself. This removes the burden from developers to implement/test this independently.

    Potential Issues

    • If the prefix scan isn't optional for the Storage interface, a new release would break any third party implementations. As described above, this would not be an issue.
    opened by dwmunster 3
Slack Bot Framework

slacker Built on top of the Slack API github.com/slack-go/slack with the idea to simplify the Real-Time Messaging feature to easily create Slack Bots,

Raed Shomali 536 Jul 23, 2021
Telegram Bot Framework for Go

Margelet Telegram Bot Framework for Go is based on telegram-bot-api It uses Redis to store it's states, configs and so on. Any low-level interactions

Gleb Sinyavskiy 62 Jul 15, 2021
A general-purpose bot library inspired by Hubot but written in Go. :robot:

Joe Bot ?? A general-purpose bot library inspired by Hubot but written in Go. Joe is a library used to write chat bots in the Go programming language.

Joe Bot 425 Jul 16, 2021
easy-peasy wg tg bot

wireguard-telegram-bot Simple-Dimple Telegram Bot for Wireguard VPN config generation Functionality /menu β€” list available commands /newkeys β€” create

Sergey Skaredov 12 Jun 7, 2021
Flexible message router add-on for go-telegram-bot-api library.

telemux Flexible message router add-on for go-telegram-bot-api library. Table of contents Motivation Features Minimal example Documentation Changelog

Andrew Dunai 12 Jul 20, 2021
Chatto is a minimal chatbot framework in Go.

chatto Simple chatbot framework written in Go, with configurations in YAML. The aim of this project is to create very simple text-based chatbots using

Jaime Tenorio 88 Jul 12, 2021
Golang bindings for the Telegram Bot API

Golang bindings for the Telegram Bot API All methods are fairly self explanatory, and reading the godoc page should explain everything. If something i

null 3k Jul 23, 2021
Kelp is a free and open-source trading bot for the Stellar DEX and 100+ centralized exchanges

Kelp Kelp is a free and open-source trading bot for the Stellar universal marketplace and for centralized exchanges such as Binance, Kraken, CoinbaseP

Stellar 714 Jul 25, 2021
A golang implementation of a console-based trading bot for cryptocurrency exchanges

Golang Crypto Trading Bot A golang implementation of a console-based trading bot for cryptocurrency exchanges. Usage Download a release or directly bu

Alessandro Sanino 574 Jul 22, 2021
Bot that polls activity API for Github organisation and pushes updates to Telegram.

git-telegram-bot Telegram bot for notifying org events Requirements (for building) Go version 1.16.x Setup If you don't have a telegram bot token yet,

Skycoin 3 May 13, 2021
Telebot is a Telegram bot framework in Go.

Telebot "I never knew creating Telegram bots could be so sexy!" go get -u gopkg.in/tucnak/telebot.v2 Overview Getting Started Poller Commands Files Se

Ian P Badtrousers 2k Jul 22, 2021
Simple yet customizable bot framework written in Go.

Introduction Sarah is a general-purpose bot framework named after the author's firstborn daughter. This comes with a unique feature called "stateful c

Go Hagiwara 196 Jul 7, 2021
A Telegram Repo For Bots Under Maintenance Which Gives Faster Response To Users

Maintenance Bot A Telegram Repo For Bots Under Maintenance Which Gives Faster Response To Users Requests Β» Report a Bug | Request Feature Table of Con

HEIMAN PICTURES 6 Jul 4, 2021
The modern cryptocurrency trading bot written in Go.

bbgo A trading bot framework written in Go. The name bbgo comes from the BB8 bot in the Star Wars movie. aka Buy BitCoin Go! Current Status Features E

Yo-An Lin 331 Jul 24, 2021