{"id":24776793,"url":"https://github.com/seated/apus","last_synced_at":"2025-10-25T12:34:23.708Z","repository":{"id":38358733,"uuid":"131128641","full_name":"seated/apus","owner":"seated","description":"Apus is a testable and adapter based Elixir SMS library","archived":false,"fork":false,"pushed_at":"2025-01-27T19:56:59.000Z","size":203,"stargazers_count":7,"open_issues_count":15,"forks_count":5,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-01-27T20:41:13.872Z","etag":null,"topics":["elixir","sms","twilio"],"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/seated.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-26T08:59:30.000Z","updated_at":"2024-11-28T11:04:14.000Z","dependencies_parsed_at":"2024-08-28T14:56:15.016Z","dependency_job_id":"a8b06150-8489-491b-9ea1-f60066a57699","html_url":"https://github.com/seated/apus","commit_stats":{"total_commits":119,"total_committers":10,"mean_commits":11.9,"dds":0.73109243697479,"last_synced_commit":"b706391a62388828f5078da7bbd70adc81fabc8c"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seated%2Fapus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seated%2Fapus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seated%2Fapus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seated%2Fapus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seated","download_url":"https://codeload.github.com/seated/apus/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236144191,"owners_count":19101937,"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":["elixir","sms","twilio"],"created_at":"2025-01-29T07:22:15.580Z","updated_at":"2025-10-09T14:46:48.032Z","avatar_url":"https://github.com/seated.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Apus\n\nApus is an Elixir library enabling a flexible and testable approach to sending SMS messages.\n\n## Installation\n\nYou can install apus by adding it to your list of dependencies in `mix.exs` and running `mix deps.get`.\n\n```elixir\ndef deps do\n  [\n    {:apus, \"~\u003e 0.15.0\"}\n  ]\nend\n```\n\n## Getting Started\n\nTo get started using apus you must first setup a module that will handle sending sms messages.\n\n```elixir\ndefmodule MyApp.SmsSender do\n  use Apus.SmsSender, otp_app: :my_app\nend\n```\n\nOnce the `SmsSender` module has been created it can be configured to use an adapter in your `config/config.exs` file.\n\n```elixir\nconfig :my_app, MyApp.SmsSender,\n  adapter: Apus.TwilioAdapter,\n  account_sid: \"\u003ctwilio account sid\u003e\",\n  auth_token: \"\u003ctwilio auth token\u003e\"\n```\n\nNow we can send sms messages like so.\n\n```elixir\nmessage = %Apus.Message{\n  to: \"+15551234567\",\n  from: \"+15557654321\",\n  body: \"Hello there!\"\n}\n\n# to deliver a message synchronously\nMyApp.SmsSender.deliver_now(message)\n\n# to deliver in the background\nMyApp.SmsSender.deliver_later(message)\n```\n\n## Working in development mode\n\nWhen working in development we don't always want to send real SMS messages but we do want\nto see that they have been correctly sent through apus. To solve this, apus offers an in-memory\nadapter that can be configured in your `config/dev.exs` file.\n\n```elixir\nconfig :my_app, MyApp.SmsSender, adapter: Apus.LocalAdapter\n```\n\nYou will now see the sent messages being printed to the current terminal session as they are delivered.\n\n## Sent messages viewer\n\nApus comes with a built-in web interface for viewing sent messages via a `plug`. This interface works\ndirectly with the `Apus.LocalAdapter` which must be configured before using the sent messages viewer.\n\nUsing with Plug\n\n```elixir\ndefmodule MyApp.Router do\n  use Plug.Router\n\n  if Mix.env == :dev do\n    forward(\"/sent_messages\", to: Apus.SentMessagesViewerPlug)\n  end\nend\n```\n\nUsing with Phoenix\n\n```elixir\ndefmodule MyApp.Router do\n  use Phoenix.Router\n\n  if Mix.env == :dev do\n    forward(\"/sent_messages\", Apus.SentMessagesViewerPlug)\n  end\nend\n```\n\n## Testing\n\nApus comes with an `Apus.TestAdapter` and some handy macros to make testing SMS delivery straightforward.\n\nSetup the test adapter in the `config/test.exs` file.\n\n```elixir\nconfig :my_app, MyApp.SmsSender, adapter: Apus.TestAdapter\n```\n\nNow you can test SMS delivery using the `assert_delivered_message` macro.\n\n### Assertions\n\nFor full match use the following example:\n\n```elixir\ndefmodule MyApp.RegistrationTest do\n  use ExUnit.Case\n\n  import Apus.Test\n  alias Apus.Message\n\n  test \"the user gets a message after registration\" do\n    new_user = user\n\n    Users.register(new_user)\n\n    assert_delivered_message %Message{\n      to: new_user.phone_number,\n      body: \"Welcome there!\"\n    }\n  end\nend\n```\n\nIf you only care that any message was delivered, you can use following assertion:\n\n```elixir\ntest \"message gets delivered\" do\n  new_user = user\n\n  Users.register(new_user)\n\n  message = assert_delivered_message()\n  # do something with the delivered message...\nend\n```\n\nLastly anonymous function matcher is also provided for more flexible assertions:\n\n```elixir\ntest \"some delivered message attrs match\" do\n  new_user = user\n\n  Users.register(new_user)\n\n  assert_delivered_message_matches(fn message -\u003e\n    assert message.to == new_user.phone_number\n    assert message.body =~ \"partial match...\"\n  end)\nend\n```\n\n### Refute\n\nThere is also a `refute_delivered_message/1` macro for testing that a specific message was not delivered.\n\n```elixir\n  test \"specific message doesn't get delivered\" do\n    # Do something...\n\n    # assert that following message wasn't sent out\n    message = %Apus.Message(to: 123, body: \"message\")\n    refute_delivered_message(message)\n  end\n```\n\nSimilarly you can also use `refute_delivered_message/0` to ensure no messages were delivered.\n\n```elixir\n  test \"no messages delivered\" do\n    # Do something....\n\n    # assert no messages were sent out\n    refute_delivered_message()\n  end\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseated%2Fapus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseated%2Fapus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseated%2Fapus/lists"}