{"id":13507534,"url":"https://github.com/alice-bot/alice","last_synced_at":"2026-01-14T22:42:28.078Z","repository":{"id":47068216,"uuid":"51122695","full_name":"alice-bot/alice","owner":"alice-bot","description":"A Slack bot framework for Elixir; down the rabbit hole!","archived":false,"fork":false,"pushed_at":"2021-09-15T00:03:11.000Z","size":9078,"stargazers_count":112,"open_issues_count":22,"forks_count":19,"subscribers_count":8,"default_branch":"master","last_synced_at":"2026-01-14T07:34:25.285Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://hexdocs.pm/alice","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alice-bot.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-02-05T03:06:44.000Z","updated_at":"2025-08-19T06:52:38.000Z","dependencies_parsed_at":"2022-08-04T10:30:42.853Z","dependency_job_id":null,"html_url":"https://github.com/alice-bot/alice","commit_stats":null,"previous_names":["adamzaninovich/alice"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/alice-bot/alice","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alice-bot%2Falice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alice-bot%2Falice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alice-bot%2Falice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alice-bot%2Falice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alice-bot","download_url":"https://codeload.github.com/alice-bot/alice/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alice-bot%2Falice/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28436721,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T22:37:52.437Z","status":"ssl_error","status_checked_at":"2026-01-14T22:37:31.496Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T02:00:35.841Z","updated_at":"2026-01-14T22:42:28.059Z","avatar_url":"https://github.com/alice-bot.png","language":"Elixir","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)\n\n#### A Lita-inspired Slack bot written in Elixir.\n\n\u003cimg height=\"135\" src=\"http://i.imgur.com/UndMkm3.png\" align=\"left\" /\u003e\n\n_The Caterpillar and Alice looked at each other for some time in silence: at\nlast the Caterpillar took the hookah out of its mouth, and addressed her in a\nlanguid, sleepy voice._\n\n_\"Who are YOU?\" said the Caterpillar. This was not an encouraging opening for\nconversation. Alice replied, rather shyly, \"I—I hardly know, sir, just at\npresent—at least I know who I WAS when I got up this morning, but I think I must\nhave been changed several times since then.\"_\n\nFor an example bot, see the [Active Alice] bot. For an example handler, see\n[Google Images Handler].\n\nYou'll need a Slack API token which can be retrieved from the [Web API page] or\nby creating a new [bot integration].\n\n[Active Alice]: https://github.com/adamzaninovich/active-alice\n[Google Images Handler]: https://github.com/alice-bot/alice_google_images\n[Web API page]: https://api.slack.com/web\n[bot integration]: https://my.slack.com/services/new/bot\n\n## Handler Plugins\n\nAlice has a plug in system that allows you to customize the functionality of\nyour bot instance. See [the docs] for more information about creating your own\nhandlers.\n\n[the docs]: https://github.com/alice-bot/alice#creating-a-route-handler-plugin\n\n### Known Handlers\n\n* Alice Against Humanity: [hex](https://hex.pm/packages/alice_against_humanity), [code](https://github.com/alice-bot/alice_against_humanity)\n* Alice Google Images: [hex](https://hex.pm/packages/alice_google_images), [code](https://github.com/alice-bot/alice_google_images)\n* Alice Karma: [hex](https://hex.pm/packages/alice_karma), [code](https://github.com/alice-bot/alice_karma)\n* Alice Reddit: [hex](https://hex.pm/packages/alice_reddit), [code](https://github.com/alice-bot/alice_reddit)\n* Alice Shizzle: [hex](https://hex.pm/packages/alice_shizzle), [code](https://github.com/notdevinclark/alice_shizzle)\n* Alice XKCD: [hex](https://hex.pm/packages/alice_xkcd), [code](https://github.com/notdevinclark/alice_xkcd)\n* Alice Doge [hex](https://hex.pm/packages/alice_doge_me), [code](https://github.com/alice-bot/alice_doge_me/)\n\nIf you write your own handler, please submit a pull request and update this\nlist!\n\n## Creating Your Own Bot With Alice\n\n### Create the Project\n\nCreate a new mix project.\n```sh\nmix new my_bot\ncd my_bot\nrm lib/my_bot.ex test/my_bot_test.exs\n```\n\n### Configure the Application\n\nIn `mix.exs`, bring in alice and any other handlers you want. You also need to\ninclude the `websocket_client` dependency because it's not a [hex] package.\n\n[hex]: http://hex.pm\n\n```elixir\ndefp deps do\n  [\n    {:alice, \"~\u003e 0.4.2\"},\n    {:alice_against_humanity, \"~\u003e 0.1.0\"},\n    {:alice_google_images, \"~\u003e 0.1.0\"}\n  ]\nend\n```\n\nIn the same file, also configure the app:\n\n```elixir\ndef application do\n  [ applications: [:alice],\n    mod: {Alice, %{}}\n  ]\nend\n```\n\nIn `config/config.exs` add any configuration that your bot needs. This includes registering any handlers you want. You can\nadd handlers through dependencies, or you can write them directly in your bot\ninstance. (See [Writing Route Handlers] for information on how to write a\nhandler. We recommend putting them in `lib/alice/handlers/`.)\n\n[Writing Route Handlers]: https://github.com/alice-bot/alice#writing-route-handlers\n\n```elixir\nuse Mix.Config\n\nconfig :alice,\n  api_key: System.get_env(\"SLACK_API_TOKEN\"),\n  state_backend: :redis,\n  redis: System.get_env(\"REDIS_URL\"),\n  handlers: [\n    Alice.Handlers.Random,\n    Alice.Handlers.AgainstHumanity,\n    Alice.Handlers.GoogleImages\n  ]\n\nconfig :alice_google_images,\n  cse_id: System.get_env(\"GOOGLE_CSE_ID\"),\n  cse_token: System.get_env(\"GOOGLE_CSE_TOKEN\"),\n  safe_search_level: :medium\n```\n\nWith that, you're done! Run your bot with `iex -S mix` or `mix run --no-halt`.\n\n### Deploying to Heroku\n\nCreate a new heroku app running Elixir.\n```sh\nheroku create --buildpack \"https://github.com/HashNuke/heroku-buildpack-elixir.git\"\n```\n\nCreate a file called `elixir_buildpack.config` at the root of your project.\n```sh\nerlang_version=22.0.3\nelixir_version=1.8.2\nalways_rebuild=false\n```\n\nCreate a `Procfile` at the root of your project. If you don't create the proc\nas a `worker`, Heroku will assume it's a web process and will terminate it for\nnot binding to port 80.\n```ruby\nworker: mix run --no-halt\n```\n\nYou may also need to reconfigure Heroku to run the worker.\n```sh\nheroku ps:scale web=0 worker=1\n```\n\nAdd your slack token and any other environment variables to Heroku\n```sh\nheroku config:set SLACK_API_TOKEN=xoxb-23486423876-HjgF354JHG7k567K4j56Gk3o\n```\n\nPush to Heroku\n```sh\ngit add -A\ngit commit -m \"initial commit\"\ngit push heroku master\n```\n\nYour bot should be good to go. :metal:\n\n## Creating a Route Handler Plugin\n\n### First Steps\n\n```sh\nmix new alice_google_images\ncd alice_google_images\nrm lib/alice_google_images.ex test/alice_google_images_test.exs\nmkdir -p lib/alice/handlers\nmkdir -p test/alice/handlers\ntouch lib/alice/handlers/google_images.ex test/alice/handlers/google_images_test.exs\n```\n\n### Configuring the App\n\nIn `mix.exs`, update `application` and `deps` to look like the following:\n\n```elixir\ndef application do\n  [applications: []]\nend\n\ndefp deps do\n  [\n    {:alice, \"~\u003e 0.4.2\"}\n  ]\nend\n```\n\n### Writing Route Handlers\n\nIn `lib/alice/handlers/google_images.ex`:\n\n```elixir\ndefmodule Alice.Handlers.GoogleImages do\n  use Alice.Router\n\n  command ~r/(image|img)\\s+me (?\u003cterm\u003e.+)/i, :fetch\n  route ~r/(image|img)\\s+me (?\u003cterm\u003e.+)/i, :fetch\n\n  @doc \"`img me alice in wonderland` - gets a random image from Google Images\"\n  def fetch(conn) do\n    conn\n    |\u003e Alice.Conn.last_capture\n    |\u003e get_images\n    |\u003e select_image\n    |\u003e reply(conn)\n  end\n\n  #...\nend\n```\n\n### The Elixir Formatter and Alice\n\nIf you want the Elixir formatter to omit the parens on `command/2` and\n`route/2`, simply [import] the alice config in your `.formatter.exs`:\n\n[import]: https://hexdocs.pm/mix/master/Mix.Tasks.Format.html#module-importing-dependencies-configuration\n\n```elixir\n# my_handler/.formatter.exs\n[\n  # ...\n\n  import_deps: [:alice]\n]\n```\n\n### Testing Handlers\n\nAlice provides several helpers to make it easy to test your handlers.  First\nyou'll need to invoke to add `use Alice.HandlerCase, handlers: [YourHandler]`\npassing it the handler you're trying to test. Then you can use\n`message_received()` within your test, which will simulate a message coming in\nfrom the chat backend and route it through to the handlers appropriately.  If\nyou're wanting to invoke a command, you'll need to make sure your message\nincludes `\u003c@alice\u003e` within the string. From there you can use either\n`first_reply()` to get the first reply sent out or `all_replies()` which will\nreturn a List of replies that have been received during your test. You can use\neither to use normal assertions on to ensure your handler behaves in the manner\nyou expect.\n\nIn `test/alice/handlers/google_images_test.exs`:\n\n```elixir\ndefmodule Alice.Handlers.GoogleImagesTest do\n  use Alice.HandlerCase, handlers: Alice.Handlers.GoogleImages\n\n  test \"it fetches an image when asked\" do\n    send_message(\"img me example image\")\n\n    assert first_reply() == \"http://example.com/image_from_google.jpg\"\n  end\nend\n```\n\n### Registering Handlers\n\nIn the `config.exs` file of your bot, add your handler to the list of handlers to\nregister on start\n\n```elixir\nuse Mix.Config\n\nconfig :alice,\n  handlers: [\n    Alice.Handlers.GoogleImages,\n    ...\n  ]\n```\n","funding_links":[],"categories":["Chatting"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falice-bot%2Falice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falice-bot%2Falice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falice-bot%2Falice/lists"}