{"id":13436033,"url":"https://github.com/hedwig-im/hedwig","last_synced_at":"2025-05-15T16:04:56.874Z","repository":{"id":15546564,"uuid":"18281521","full_name":"hedwig-im/hedwig","owner":"hedwig-im","description":"An Adapter-based Bot Framework for Elixir Applications","archived":false,"fork":false,"pushed_at":"2022-09-03T12:33:29.000Z","size":378,"stargazers_count":654,"open_issues_count":15,"forks_count":73,"subscribers_count":23,"default_branch":"master","last_synced_at":"2025-03-31T20:08:20.820Z","etag":null,"topics":["bot","elixir","otp","slack","xmpp"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hedwig-im.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":"2014-03-31T04:16:17.000Z","updated_at":"2025-03-15T16:07:55.000Z","dependencies_parsed_at":"2022-09-16T23:52:59.460Z","dependency_job_id":null,"html_url":"https://github.com/hedwig-im/hedwig","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hedwig-im%2Fhedwig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hedwig-im%2Fhedwig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hedwig-im%2Fhedwig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hedwig-im%2Fhedwig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hedwig-im","download_url":"https://codeload.github.com/hedwig-im/hedwig/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247730069,"owners_count":20986404,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["bot","elixir","otp","slack","xmpp"],"created_at":"2024-07-31T03:00:42.597Z","updated_at":"2025-04-07T21:13:27.597Z","avatar_url":"https://github.com/hedwig-im.png","language":"Elixir","funding_links":[],"categories":["Elixir","Free Time Projects","Chatting"],"sub_categories":[],"readme":"# Hedwig\n\n\u003e An Adapter-based Bot Framework for Elixir Applications\n\n[![Build Status](https://travis-ci.org/hedwig-im/hedwig.svg?branch=master)](https://travis-ci.org/hedwig-im/hedwig)\n[![Coverage Status](https://coveralls.io/repos/hedwig-im/hedwig/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/hedwig-im/hedwig?branch=master)\n\n![Hedwig](https://raw.githubusercontent.com/hedwig-im/hedwig/master/hedwig.png)\n\nHedwig is a chat bot, highly inspired by GitHub's [Hubot](https://hubot.github.com/).\n\nSee the [online documentation](https://hexdocs.pm/hedwig) for more information.\n\nHedwig was designed for 2 use-cases:\n\n  1. A single, stand-alone OTP application.\n  2. Included as a dependency of other OTP applications (or an umbrella).\n\nYou can spawn multiple bots at run-time with different configurations.\n\n## Adapters\n\n- [XMPP](https://github.com/hedwig-im/hedwig_xmpp) (Official)\n- [Slack](https://github.com/hedwig-im/hedwig_slack) (Official)\n- [Flowdock](https://github.com/supernullset/hedwig_flowdock)\n\nCheck out [enilsen16/awesome-hedwig](https://github.com/enilsen16/awesome-hedwig) for a curated list of adapters, responders, and other resources.\n\n## Getting started\n\nHedwig ships with a console adapter to get you up and running quickly. It's\ngreat for testing how your bot will respond to the messages it receives.\n\nTo add Hedwig to an existing Elixir application, add `:hedwig` to your list of\ndependencies in your `mix.exs` file:\n\n```elixir\ndefp deps do\n  [{:hedwig, \"~\u003e 1.0\"}]\nend\n```\n\nUpdate your applications list to include `:hedwig`. This will ensure that the\nHedwig application, along with it's supervision tree is started when you start\nyour application.\n\n```elixir\ndef applications do\n  [applications: [:hedwig]]\nend\n```\n\nFetch the dependencies:\n\n```\n$ mix deps.get\n```\n\n## Create a robot module\n\nHedwig provides a convenient mix task to help you generate a basic robot module.\n\nRun the following and follow the prompts:\n\n```\n$ mix hedwig.gen.robot\n\nWelcome to the Hedwig Robot Generator!\n\nLet's get started.\n\nWhat would you like to name your bot?: alfred\n\nAvailable adapters\n\n1. Hedwig.Adapters.Console\n\nPlease select an adapter: 1\n\n* creating lib/alfred\n* creating lib/alfred/robot.ex\n* updating config/config.exs\n\nDon't forget to add your new robot to your supervision tree\n(typically in lib/alfred.ex):\n\n    worker(Alfred.Robot, [])\n```\n\n```elixir\ndefmodule Alfred.Robot do\n  use Hedwig.Robot, otp_app: :alfred\n\n  ...\nend\n```\n\n## Configuration\n\nThe generator will automatically generate a default configuration in\n`config/config.exs`. You will need to customize it further depending on the\nadapter you will use.\n\nThis is mainly to setup the module to be compiled along with the adapter. An\nadapter can inject functionality into your module if needed.\n\n```elixir\n# config/config.exs\n\nconfig :alfred, Alfred.Robot,\n  adapter: Hedwig.Adapters.Console,\n  name: \"alfred\",\n  aka: \"/\",\n  responders: [\n    {Hedwig.Responders.Help, []},\n    {Hedwig.Responders.Ping, []}\n  ]\n```\n\n### Start a bot.\n\nYou can start your bot as part of your application's supervision tree or by\nusing the supervision tree provided by Hedwig.\n\n### Starting as part of your supervision tree:\n\n```elixir\n# add this to the list of your supervisor's children\nworker(Alfred.Robot, [])\n```\n\n### Trying out the console adapter:\n\n```\nmix run --no-halt\n\nHedwig Console - press Ctrl+C to exit.\n\nThe console adapter is useful for quickly verifying how your\nbot will respond based on the current installed responders.\n\nscrogson\u003e alfred help\nalfred\u003e alfred help \u003cquery\u003e - Displays all help commands that match \u003cquery\u003e.\nalfred help - Displays all of the help commands that alfred knows about.\nalfred: ping - Responds with 'pong'\nscrogson\u003e\n```\n\n### Starting bots manually:\n\n```elixir\n# Start the bot via the module. The configuration options will be read in from\n# config.exs\n{:ok, pid} = Hedwig.start_robot(Alfred.Robot)\n\n# You can also pass in a list of options that will override the configuration\n# provided in config.exs (except for the adapter as that is compiled into the\n# module).\n{:ok, pid} = Hedwig.start_robot(Alfred.Robot, [name: \"jeeves\"])\n```\n\n### Registering your robot process\n\nIf you want to start, stop, and send messages to your bot without keeping track\nof its `pid`, you can register your robot in the `handle_connect/1` callback in\nyour robot module like so:\n\n```elixir\ndefmodule Alfred.Robot do\n  use Hedwig.Robot, otp_app: :alfred\n\n  def handle_connect(%{name: name} = state) do\n    if :undefined == :global.whereis_name(name) do\n      :yes = :global.register_name(name, self())\n    end\n    {:ok, state}\n  end\nend\n```\n\nProcess registration via `Process.register/2` is simple. However, since the name\ncan only be an atom it may not work for all use-cases. If you are using the same\nmodule for many robots, you'll need to reach for something more flexible like:\n\n* [global](http://erlang.org/doc/man/global.html)\n* [gproc](https://github.com/uwiger/gproc)\n* [swarm](https://github.com/bitwalker/swarm)\n\n#### Finding your robot\n\n```elixir\n# Start the robot\nHedwig.start_robot(Alfred.Robot)\n# Get the pid of the robot by name\npid = :global.whereis_name(\"alfred\")\n\n# Start a new robot with a different name\nHedwig.start_robot(Alfred.Robot, [name: \"jeeves\"])\n# Get the pid\npid = :global.whereis_name(\"jeeves\")\n# Stop the robot\nHedwig.stop_robot(pid)\n```\n\n## Sending Messages\n\n```elixir\n# Get the pid of the robot\npid = :global.whereis_name(\"alfred\")\n\n# Create a Hedwig message\nmsg = %Hedwig.Message{\n  type: \"groupchat\",\n  room: \"my_room@example.com\",\n  text: \"hello world\"\n}\n\n# Send the message\nHedwig.Robot.send(pid, msg)\n```\n\n## Building Responders\n\nResponders are processes that will handle incoming messages.\n\nAll that's needed is to `use Hedwig.Responder` and use the `hear/2`, or\n`respond/2` macros to define a pattern to listen for and how to respond in\nthe block when a message matches.\n\nHere is an example:\n\n```elixir\ndefmodule MyApp.Responders.GreatSuccess do\n  @moduledoc \"\"\"\n  Borat, Great Success!\n\n  Replies with a random link to a Borat image when a message contains\n  'great success'.\n  \"\"\"\n\n  use Hedwig.Responder\n\n  @links [\n    \"http://mjanja.co.ke/wordpress/wp-content/uploads/2013/09/borat_great_success.jpg\",\n    \"http://s2.quickmeme.com/img/13/1324dfd733535e58dba70264e6d05c9b70346204d2cacef65abef9c702746d1c.jpg\",\n    \"https://www.youtube.com/watch?v=r13riaRKGo0\"\n  ]\n\n  @usage \"\"\"\n  \u003ctext\u003e (great success) - Replies with a random Borat image.\n  \"\"\"\n  hear ~r/great success(!)?/i, msg do\n    reply msg, random(@links)\n  end\nend\n```\n\n## Hear vs. Respond\n\nThe two responder macros are use for different reasons:\n\n* `hear` - matches messages containing the regular expression\n* `respond` - matches only when prefixed by your robot's configured `name` or `aka` value.\n\n## Testing responders:\n\nHedwig ships with a ExUnit-based module sepecifically made to test responders: `Hedwig.RobotCase`.\n\nIn order to test the above responder, you need to create an ExUnit test case:\n\n```elixir\n\n# test/my_app/responders/great_success_test.exs\n\ndefmodule MyApp.Responders.GreatSuccessTest do\n  use Hedwig.RobotCase\n\n  @tag start_robot: true, name: \"alfred\", responders: [{MyApp.Responders.GreatSuccess, []}]\n  test \"great success - responds with a borat url\", %{adapter: adapter, msg: msg} do\n    send adapter, {:message, %{msg | text: \"great success\"}}\n    assert_receive {:message, %{text: text}}\n    assert String.contains?(text, \"http\")\n  end\nend\n```\n\nTo run the tests, use `mix test`\n\n## @usage\n\nThe `@usage` module attribute works nicely with `Hedwig.Responders.Help`. If you\ninstall the help handler, your bot will listen for `\u003cyour-bots-nickname\u003e help`\nand respond with a message containing all of the installed handlers `@usage`\ntext.\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2015 Sonny Scroggin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhedwig-im%2Fhedwig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhedwig-im%2Fhedwig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhedwig-im%2Fhedwig/lists"}