Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/alice-bot/alice
A Slack bot framework for Elixir; down the rabbit hole!
https://github.com/alice-bot/alice
Last synced: 3 months ago
JSON representation
A Slack bot framework for Elixir; down the rabbit hole!
- Host: GitHub
- URL: https://github.com/alice-bot/alice
- Owner: alice-bot
- License: other
- Created: 2016-02-05T03:06:44.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2021-09-15T00:03:11.000Z (over 3 years ago)
- Last Synced: 2024-09-16T08:25:29.301Z (4 months ago)
- Language: Elixir
- Homepage: https://hexdocs.pm/alice
- Size: 8.66 MB
- Stars: 111
- Watchers: 9
- Forks: 19
- Open Issues: 22
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- freaking_awesome_elixir - Elixir - A Slack bot framework for Elixir. (Chatting)
- fucking-awesome-elixir - alice - A Slack bot framework for Elixir. (Chatting)
- awesome-elixir - alice - A Slack bot framework for Elixir. (Chatting)
README
# Alice [![Hex Version](https://img.shields.io/hexpm/v/alice.svg)](https://hex.pm/packages/alice) [![Hex Downloads](https://img.shields.io/hexpm/dt/alice.svg)](https://hex.pm/packages/alice) [![License: MIT](https://img.shields.io/hexpm/l/alice.svg)](https://hex.pm/packages/alice) [![Coverage Status](https://coveralls.io/repos/github/alice-bot/alice/badge.svg?branch=master)](https://coveralls.io/github/alice-bot/alice?branch=master)
#### A Lita-inspired Slack bot written in Elixir.
_The Caterpillar and Alice looked at each other for some time in silence: at
last the Caterpillar took the hookah out of its mouth, and addressed her in a
languid, sleepy voice.__"Who are YOU?" said the Caterpillar. This was not an encouraging opening for
conversation. Alice replied, rather shyly, "I—I hardly know, sir, just at
present—at least I know who I WAS when I got up this morning, but I think I must
have been changed several times since then."_For an example bot, see the [Active Alice] bot. For an example handler, see
[Google Images Handler].You'll need a Slack API token which can be retrieved from the [Web API page] or
by creating a new [bot integration].[Active Alice]: https://github.com/adamzaninovich/active-alice
[Google Images Handler]: https://github.com/alice-bot/alice_google_images
[Web API page]: https://api.slack.com/web
[bot integration]: https://my.slack.com/services/new/bot## Handler Plugins
Alice has a plug in system that allows you to customize the functionality of
your bot instance. See [the docs] for more information about creating your own
handlers.[the docs]: https://github.com/alice-bot/alice#creating-a-route-handler-plugin
### Known Handlers
* Alice Against Humanity: [hex](https://hex.pm/packages/alice_against_humanity), [code](https://github.com/alice-bot/alice_against_humanity)
* Alice Google Images: [hex](https://hex.pm/packages/alice_google_images), [code](https://github.com/alice-bot/alice_google_images)
* Alice Karma: [hex](https://hex.pm/packages/alice_karma), [code](https://github.com/alice-bot/alice_karma)
* Alice Reddit: [hex](https://hex.pm/packages/alice_reddit), [code](https://github.com/alice-bot/alice_reddit)
* Alice Shizzle: [hex](https://hex.pm/packages/alice_shizzle), [code](https://github.com/notdevinclark/alice_shizzle)
* Alice XKCD: [hex](https://hex.pm/packages/alice_xkcd), [code](https://github.com/notdevinclark/alice_xkcd)
* Alice Doge [hex](https://hex.pm/packages/alice_doge_me), [code](https://github.com/alice-bot/alice_doge_me/)If you write your own handler, please submit a pull request and update this
list!## Creating Your Own Bot With Alice
### Create the Project
Create a new mix project.
```sh
mix new my_bot
cd my_bot
rm lib/my_bot.ex test/my_bot_test.exs
```### Configure the Application
In `mix.exs`, bring in alice and any other handlers you want. You also need to
include the `websocket_client` dependency because it's not a [hex] package.[hex]: http://hex.pm
```elixir
defp deps do
[
{:alice, "~> 0.4.2"},
{:alice_against_humanity, "~> 0.1.0"},
{:alice_google_images, "~> 0.1.0"}
]
end
```In the same file, also configure the app:
```elixir
def application do
[ applications: [:alice],
mod: {Alice, %{}}
]
end
```In `config/config.exs` add any configuration that your bot needs. This includes registering any handlers you want. You can
add handlers through dependencies, or you can write them directly in your bot
instance. (See [Writing Route Handlers] for information on how to write a
handler. We recommend putting them in `lib/alice/handlers/`.)[Writing Route Handlers]: https://github.com/alice-bot/alice#writing-route-handlers
```elixir
use Mix.Configconfig :alice,
api_key: System.get_env("SLACK_API_TOKEN"),
state_backend: :redis,
redis: System.get_env("REDIS_URL"),
handlers: [
Alice.Handlers.Random,
Alice.Handlers.AgainstHumanity,
Alice.Handlers.GoogleImages
]config :alice_google_images,
cse_id: System.get_env("GOOGLE_CSE_ID"),
cse_token: System.get_env("GOOGLE_CSE_TOKEN"),
safe_search_level: :medium
```With that, you're done! Run your bot with `iex -S mix` or `mix run --no-halt`.
### Deploying to Heroku
Create a new heroku app running Elixir.
```sh
heroku create --buildpack "https://github.com/HashNuke/heroku-buildpack-elixir.git"
```Create a file called `elixir_buildpack.config` at the root of your project.
```sh
erlang_version=22.0.3
elixir_version=1.8.2
always_rebuild=false
```Create a `Procfile` at the root of your project. If you don't create the proc
as a `worker`, Heroku will assume it's a web process and will terminate it for
not binding to port 80.
```ruby
worker: mix run --no-halt
```You may also need to reconfigure Heroku to run the worker.
```sh
heroku ps:scale web=0 worker=1
```Add your slack token and any other environment variables to Heroku
```sh
heroku config:set SLACK_API_TOKEN=xoxb-23486423876-HjgF354JHG7k567K4j56Gk3o
```Push to Heroku
```sh
git add -A
git commit -m "initial commit"
git push heroku master
```Your bot should be good to go. :metal:
## Creating a Route Handler Plugin
### First Steps
```sh
mix new alice_google_images
cd alice_google_images
rm lib/alice_google_images.ex test/alice_google_images_test.exs
mkdir -p lib/alice/handlers
mkdir -p test/alice/handlers
touch lib/alice/handlers/google_images.ex test/alice/handlers/google_images_test.exs
```### Configuring the App
In `mix.exs`, update `application` and `deps` to look like the following:
```elixir
def application do
[applications: []]
enddefp deps do
[
{:alice, "~> 0.4.2"}
]
end
```### Writing Route Handlers
In `lib/alice/handlers/google_images.ex`:
```elixir
defmodule Alice.Handlers.GoogleImages do
use Alice.Routercommand ~r/(image|img)\s+me (?.+)/i, :fetch
route ~r/(image|img)\s+me (?.+)/i, :fetch@doc "`img me alice in wonderland` - gets a random image from Google Images"
def fetch(conn) do
conn
|> Alice.Conn.last_capture
|> get_images
|> select_image
|> reply(conn)
end#...
end
```### The Elixir Formatter and Alice
If you want the Elixir formatter to omit the parens on `command/2` and
`route/2`, simply [import] the alice config in your `.formatter.exs`:[import]: https://hexdocs.pm/mix/master/Mix.Tasks.Format.html#module-importing-dependencies-configuration
```elixir
# my_handler/.formatter.exs
[
# ...import_deps: [:alice]
]
```### Testing Handlers
Alice provides several helpers to make it easy to test your handlers. First
you'll need to invoke to add `use Alice.HandlerCase, handlers: [YourHandler]`
passing it the handler you're trying to test. Then you can use
`message_received()` within your test, which will simulate a message coming in
from the chat backend and route it through to the handlers appropriately. If
you're wanting to invoke a command, you'll need to make sure your message
includes `<@alice>` within the string. From there you can use either
`first_reply()` to get the first reply sent out or `all_replies()` which will
return a List of replies that have been received during your test. You can use
either to use normal assertions on to ensure your handler behaves in the manner
you expect.In `test/alice/handlers/google_images_test.exs`:
```elixir
defmodule Alice.Handlers.GoogleImagesTest do
use Alice.HandlerCase, handlers: Alice.Handlers.GoogleImagestest "it fetches an image when asked" do
send_message("img me example image")assert first_reply() == "http://example.com/image_from_google.jpg"
end
end
```### Registering Handlers
In the `config.exs` file of your bot, add your handler to the list of handlers to
register on start```elixir
use Mix.Configconfig :alice,
handlers: [
Alice.Handlers.GoogleImages,
...
]
```