3 releases
0.1.2 | Apr 7, 2021 |
---|---|
0.1.1 | Feb 5, 2021 |
0.1.0 | Feb 5, 2021 |
#2161 in Web programming
15KB
92 lines
Urbit Chatbot Framework
A framework that allows anyone to create an Urbit Chatbot with only a few lines of code.
The Urbit Chatbot Framework takes care of all the complexities of connecting to a ship, subscribing to a chat, parsing messages, and sending messages automatically for you. All you have to do is simply write the message handling/response logic and everything else will just work.
This crate is available on crates.io.
Basic Design
At its core, the framework revolves around the Chatbot
struct. It is defined as:
/// This struct represents a chatbot that is connected to a given `ship`,
/// is watching/posting to a specific `chat_ship`/`chat_name`
/// and is using the function `respond_to_message` to process any messages
/// which are posted in said chat.
pub struct Chatbot {
/// `respond_to_message` is a function defined by the user of this framework.
/// This function receives any messages that get posted to the connected chat,
/// and if the function returns `Some(message)`, then `message` is posted to the
/// chat as a response. If it returns `None`, then no message is posted.
respond_to_message: fn(AuthoredMessage) -> Option<Message>,
ship: ShipInterface,
chat_ship: String,
chat_name: String,
}
To create a chatbot, one simply must instantiate a Chatbot
struct with:
- A
ShipInterface
to connect to to interact with the Urbit network - The
chat_ship
that the chat is running on - The
chat_name
- A function (optionally named respond_to_message) which takes an
AuthoredMessage
as input, and returns anOption<Message>
as output
Creating A Chatbot
A Chatbot
is most easily created using the new_with_local_config
method:
/// Create a new `Chatbot` with a `ShipInterface` derived automatically
/// from a local config file. If the config file does not exist, the
/// `Chatbot` will create the config file, exit, and prompt the user to
/// fill it out.
pub fn new_with_local_config(
respond_to_message: fn(AuthoredMessage) -> Option<Message>,
chat_ship: &str,
chat_name: &str,
) -> Self {
This automatically deals with creating a local ship config file for the user to edit if none available, and then on rerun, reading said config to connect to a ship.
In order to use this method, we need to define a respond_to_message
function which we can supply as an argument. Here is an example of one of the simplest possible implementations:
fn respond_to_message(authored_message: AuthoredMessage) -> Option<Message> {
// Any time a message is posted in the chat, respond in chat with a static message.
Some(Message::new().add_text("Calm Computing ~"))
}
Do note, that if this function returns None
, then the Chatbot
will not reply to the message, and simply continue forward processing the next one.
With this function defined, you can now easily call Chatbot::new_with_local_config()
and acquire an instantiated Chatbot
.
Running The Chatbot
Once the Chatbot
struct is defined, all one needs to do is:
chat_bot.run();
This will automatically perform all messaging, parsing, and interfacing with the connected Urbit ship without any further code required.
And just like that you have an Urbit chatbot ready to go.
Example Projects
The projects linked below are example Urbit Chatbot projects. They link directly to the main.rs
so you can immediately see the implementation of said chatbot.
You can also easily run any of these examples by:
- Cloning this repo.
- Changing directory into the example project folder in your terminal.
- Editing
main.rs
with thechat_ship
andchat_name
which you wish to run the bot in. - Running
cargo run
the first time to create the ship config file. - Editing the
ship_config.yaml
with your ship information (Moons or comets typically work best. Do not use your daily-driver ship because messages from the ship the chatbot is connected to are all ignored.) - Running
cargo run
to run the chatbot with the ship config info provided.
Simple Chatbot
The Simple Chatbot is the simplest chatbot possible which replies to all messages in a chat with a static message. Approximately 4 lines of real code, showing off how simple it is to create a chatbot.
The point of this project is to display the bare minimum requirements for setting up a chatbot.
Anti Comet Chatbot
The Anti Comet Chatbot is a slightly more advanced chatbot which takes a look at the ship that authored the latest message. If the ship has a name long enough to be classified a comet, then it responds with a message. Otherwise, it returns None
, meaning no message is sent by the chatbot to the chat in reply (if they aren't a comet).
Crypto Prices Chatbot
The Crypto Prices Chatbot is a real world example of a useful chatbot that implements a command for everyone in a chat to use.
In effect, if anyone types:
|price {crypto_name_here}
such as
|price bitcoin
Then the bot will fetch the bitcoin price via coingecko API, and return it:
USD $37167
This is the first chatbot implemented via the Urbit Chatbot Framework which has real utility, and is a great example of how to go about building chatbots for use cases which need to reply based off of commands and make calls to external APIs.
Bible Chatbot
The Bible Chatbot is another real world example of a useful chatbot that implements a command for everyone in a chat to use.
This chatbot allows anyone to use the !bible
command and request one or more verses from the bible (KJV):
!bible John 1:1-5
Poll Chatbot
The Poll Chatbot is the most complex chatbot example enabling anyone to run votes/polls inside of their chats. Every poll is saved into a .json
file and ensured that every ship only gets a single vote.
To start a poll with any given amount of options:
!poll [option1] [option2] ...
or
!poll -t [title] [option1] [option2] ...
The title of a poll acts as its ID, so don't use the same one multiple times yet.
Once a poll is running any ship can vote (precisely once):
!vote [pollid] [option]
Results of a poll can be accessed via:
!results [pollid]
or
!results all
to view all active polls.
The creator of a poll can end the poll via:
!endpoll [pollid]
Polls without titles have a numerical ID generated at creation and are stored in a json file in the directory that the bot is run from.
(Credits to ~hodzod-walrus for creating the Poll Chatbot)
Dependencies
~10–27MB
~367K SLoC