{"id":13878540,"url":"https://github.com/slack-ruby/slack-ruby-bot-server","last_synced_at":"2025-05-14T18:04:25.094Z","repository":{"id":40685853,"uuid":"46002640","full_name":"slack-ruby/slack-ruby-bot-server","owner":"slack-ruby","description":"A library that enables you to write a complete Slack bot service with Slack button integration, in Ruby.","archived":false,"fork":false,"pushed_at":"2024-12-02T00:02:40.000Z","size":1973,"stargazers_count":268,"open_issues_count":22,"forks_count":76,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-05-14T18:04:24.427Z","etag":null,"topics":["ruby","slack","slackbot"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/slack-ruby.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":{"github":["dblock"]}},"created_at":"2015-11-11T18:54:07.000Z","updated_at":"2025-04-26T15:36:53.000Z","dependencies_parsed_at":"2024-01-03T04:56:19.913Z","dependency_job_id":"eba35ead-8de9-4fc8-b7ed-c60661c8cba5","html_url":"https://github.com/slack-ruby/slack-ruby-bot-server","commit_stats":{"total_commits":260,"total_committers":15,"mean_commits":"17.333333333333332","dds":"0.16538461538461535","last_synced_commit":"c2bc038a1e52dd68be582d5a92e4f8e7f2e11017"},"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slack-ruby%2Fslack-ruby-bot-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slack-ruby%2Fslack-ruby-bot-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slack-ruby%2Fslack-ruby-bot-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slack-ruby%2Fslack-ruby-bot-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/slack-ruby","download_url":"https://codeload.github.com/slack-ruby/slack-ruby-bot-server/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254198453,"owners_count":22030964,"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":["ruby","slack","slackbot"],"created_at":"2024-08-06T08:01:52.524Z","updated_at":"2025-05-14T18:04:25.018Z","avatar_url":"https://github.com/slack-ruby.png","language":"Ruby","readme":"Slack Ruby Bot Server\n=====================\n\n[![Gem Version](https://badge.fury.io/rb/slack-ruby-bot-server.svg)](https://badge.fury.io/rb/slack-ruby-bot-server)\n[![Code Climate](https://codeclimate.com/github/slack-ruby/slack-ruby-bot-server.svg)](https://codeclimate.com/github/slack-ruby/slack-ruby-bot-server)\n[![mongodb](https://github.com/slack-ruby/slack-ruby-bot-server/actions/workflows/test-mongodb.yml/badge.svg)](https://github.com/slack-ruby/slack-ruby-bot-server/actions/workflows/test-mongodb.yml)\n[![postgresql](https://github.com/slack-ruby/slack-ruby-bot-server/actions/workflows/test-postgresql.yml/badge.svg)](https://github.com/slack-ruby/slack-ruby-bot-server/actions/workflows/test-postgresql.yml)\n[![rubocop](https://github.com/slack-ruby/slack-ruby-bot-server/actions/workflows/rubocop.yml/badge.svg)](https://github.com/slack-ruby/slack-ruby-bot-server/actions/workflows/rubocop.yml)\n\nBuild a complete Slack bot service with Slack button integration, in Ruby.\n\n## Table of Contents\n\n- [What is this?](#what-is-this)\n- [Stable Release](#stable-release)\n- [Make Your Own](#make-your-own)\n- [Usage](#usage)\n  - [Storage](#storage)\n    - [MongoDB](#mongodb)\n    - [ActiveRecord](#activerecord)\n  - [OAuth Version and Scopes](#oauth-version-and-scopes)\n  - [Slack App](#slack-app)\n  - [API](#api)\n    - [App](#app)\n    - [Service Manager](#service-manager)\n      - [Lifecycle Callbacks](#lifecycle-callbacks)\n      - [Service Timers](#service-timers)\n      - [Extensions](#extensions)\n    - [Service Class](#service-class)\n  - [HTML Templates](#html-templates)\n  - [Access Tokens](#access-tokens)\n- [Sample Bots Using Slack Ruby Bot Server](#sample-bots-using-slack-ruby-bot-server)\n  - [Slack Bots with Granular Permissions](#slack-bots-with-granular-permissions)\n  - [Legacy Slack Bots](#legacy-slack-bots)\n- [Copyright \u0026 License](#copyright--license)\n\n## What is this?\n\nA library that contains a web server and a RESTful [Grape](http://github.com/ruby-grape/grape) API serving a Slack bot to multiple teams. Use in conjunction with [slack-ruby-bot-server-events](https://github.com/slack-ruby/slack-ruby-bot-server-events) to build a complete Slack bot service, or [slack-ruby-bot-server-rtm](https://github.com/slack-ruby/slack-ruby-bot-server-rtm) to build a (legacy) Classic RealTime Slack bot. Your customers can use a Slack button to install the bot.\n\n## Stable Release\n\nYou're reading the documentation for the **next** release of slack-ruby-bot-server. Please see the documentation for the [last stable release, v2.1.1](https://github.com/slack-ruby/slack-ruby-bot-server/blob/v2.1.1/README.md) unless you're integrating with HEAD. See [UPGRADING](UPGRADING.md) when upgrading from an older version. See [MIGRATING](MIGRATING.md) for help with migrating Legacy Slack Apps to Granular Scopes.\n\n## Make Your Own\n\nThis library alone will only register a new bot, but will not include any bot functionality. To make something useful, we recommend you get started from either [slack-ruby-bot-server-events-app-mentions-sample](https://github.com/slack-ruby/slack-ruby-bot-server-events-app-mentions-sample) (handles a single kind of event), or [slack-ruby-bot-server-events-sample](https://github.com/slack-ruby/slack-ruby-bot-server-events-sample) (handles all kinds of events) to bootstrap your project.\n\n## Usage\n\n### Storage\n\nA database is required to store teams.\n\n#### MongoDB\n\nUse MongoDB with [Mongoid](https://github.com/mongodb/mongoid) as ODM. Configure the database connection in `mongoid.yml`. Add the `mongoid` gem in your Gemfile.\n\n```\ngem 'mongoid'\ngem 'kaminari-mongoid'\ngem 'mongoid-scroll'\ngem 'slack-ruby-bot-server'\n```\n\n#### ActiveRecord\n\nUse ActiveRecord with, for example, PostgreSQL via [pg](https://github.com/ged/ruby-pg). Add the `activerecord`, `pg`, `otr-activerecord` and `pagy_cursor` gems to your Gemfile.\nCurrently supports ActiveRecord/Rails major versions 6.0, 6.1 and 7.0.\n\n```\ngem 'pg'\ngem 'activerecord', require: 'active_record'\ngem 'slack-ruby-bot-server'\ngem 'otr-activerecord'\ngem 'pagy_cursor'\n```\n\nConfigure the database connection in `config/postgresql.yml`. \n\n```yaml\ndefault: \u0026default\n  adapter: postgresql\n  pool: 10\n  timeout: 5000\n  encoding: unicode\n\ndevelopment:\n  \u003c\u003c: *default\n  database: bot_development\n\ntest:\n  \u003c\u003c: *default\n  database: bot_test\n\nproduction:\n  \u003c\u003c: *default\n  database: bot\n```\n\nEstablish a connection in your startup code.\n\n```ruby\nyml = ERB.new(File.read(File.expand_path('config/postgresql.yml', __dir__))).result\ndb_config = if Gem::Version.new(Psych::VERSION) \u003e= Gem::Version.new('3.1.0.pre1')\n              ::YAML.safe_load(yml, aliases: true)[ENV['RACK_ENV']]\n            else\n              ::YAML.safe_load(yml, [], [], true)[ENV['RACK_ENV']]\n            end\nActiveRecord::Base.establish_connection(db_config)\n```\n\n### OAuth Version and Scopes\n\nConfigure your app's [OAuth version](https://api.slack.com/authentication/oauth-v2) and [scopes](https://api.slack.com/legacy/oauth-scopes) as needed by your application.\n\n```ruby\nSlackRubyBotServer.configure do |config|\n  config.oauth_version = :v2\n  config.oauth_scope = ['channels:read', 'chat:write']\nend\n```\n\nThe \"Add to Slack\" button uses the standard OAuth code grant flow as described in the [Slack docs](https://api.slack.com/docs/oauth#flow). Once clicked, the user is taken through the authorization process at Slack's site. Upon successful completion, a callback containing a temporary code is sent to the redirect URL you specified. The endpoint at that URL contains code that persists the bot token each time a Slack client is instantiated for the specific team.\n\n### Slack App\n\nCreate a new Slack App [here](https://api.slack.com/applications/new).\n\n![](images/create-app.png)\n\nFollow Slack's instructions, note the app client ID and secret, give the bot a default name, etc.\n\nWithin your application, edit your `.env` file and add `SLACK_CLIENT_ID=...` and `SLACK_CLIENT_SECRET=...` in it.\n\nRun `bundle install` and `foreman start` to boot the app.\n\n```\n$ foreman start\n07:44:47 web.1  | started with pid 59258\n07:44:50 web.1  | * Listening on tcp://0.0.0.0:5000\n```\n\nSet the redirect URL in \"OAuth \u0026 Permissions\" be the location of your app. Since you cannot receive notifications on localhost from Slack use a public tunneling service such as [ngrok](https://ngrok.com/) to expose local port 9292 for testing.\n\n```\n$ ngrok http 5000\nForwarding https://ddfd97f80615.ngrok.io -\u003e http://localhost:5000\n```\n\nNavigate to either [localhost:9292](http://localhost:9292) or the ngrok URL above. You should see an \"Add to Slack\" button. Use it to install the app into your own Slack team.\n\n### API\n\nThis library implements an app, [SlackRubyBotServer::App](lib/slack-ruby-bot-server/app.rb) and a service manager, [SlackRubyBotServer::Service](lib/slack-ruby-bot-server/service.rb). It also provides [default HTML templates and JS scripts](public) for Slack integration.\n\n#### App\n\nThe app instance checks for a working database connection, ensures indexes, performs migrations, sets up bot aliases and log levels. You can introduce custom behavior into the app lifecycle by subclassing `SlackRubyBotServer::App` and creating an instance of the child class in `config.ru`.\n\n```ruby\nclass MyApp \u003c SlackRubyBotServer::App\n  def prepare!\n    super\n    deactivate_sleepy_teams!\n  end\n\n  private\n\n  def deactivate_sleepy_teams!\n    Team.active.each do |team|\n      next unless team.sleepy?\n      team.deactivate!\n    end\n  end\nend\n```\n\n```ruby\nMyApp.instance.prepare!\n```\n\n#### Service Manager\n\n##### Lifecycle Callbacks\n\nYou can introduce custom behavior into the service lifecycle via callbacks. This can be useful when new team has been registered via the API or a team has been deactivated from Slack.\n\n```ruby\ninstance = SlackRubyBotServer::Service.instance\n\ninstance.on :started, :stopped do |team|\n  # team has been started or stopped\nend\n\ninstance.on :created do |team, error, options|\n  # a new team has been registered\nend\n\ninstance.on :deactivated do |team, error, options|\n  # an existing team has been deactivated in Slack\nend\n\ninstance.on :error do |team, error, options|\n  # an error has occurred\nend\n```\n\nThe following callbacks are supported. All callbacks receive a `team`, except `error`, which receives a `StandardError` object.\n\n| callback       |  description                                                     |\n|:--------------:|:-----------------------------------------------------------------|\n| error          | an error has occurred                                            |\n| creating       | a new team is being registered                                   |\n| created        | a new team has been registered                                   |\n| booting        | the service is starting and is connecting a team to Slack        |\n| booted         | the service is starting and has connected a team to Slack        |\n| stopping       | the service is about to disconnect a team from Slack             |\n| stopped        | the service has disconnected a team from Slack                   |\n| starting       | the service is (re)connecting a team to Slack                    |\n| started        | the service has (re)connected a team to Slack                    |\n| deactivating   | a team is being deactivated                                      |\n| deactivated    | a team has been deactivated                                      |\n\nThe [Add to Slack button](https://api.slack.com/docs/slack-button) also allows for an optional `state` parameter that will be returned on completion of the request. The `creating` and `created` callbacks include an options hash where this value can be accessed (to check for forgery attacks for instance).\n```ruby\nauth = OpenSSL::HMAC.hexdigest(\"SHA256\", \"key\", \"data\")\n```\n```html\n\u003ca href=\"\u003c%= SlackRubyBotServer::Config.oauth_authorize_url %\u003e?scope=\u003c%= SlackRubyBotServer::Config.oauth_scope_s %\u003e\u0026client_id=\u003c%= ENV['SLACK_CLIENT_ID'] %\u003e\u0026state=#{auth)\"\u003e ... \u003c/a\u003e\n```\n```ruby\ninstance = SlackRubyBotServer::Service.instance\ninstance.on :creating do |team, error, options|\n  raise \"Unauthorized response\" unless options[:state] == auth\nend\n```\n\n##### Service Timers\n\nYou can introduce custom behavior into the service lifecycle on a timer. For example, check whether a team's trial has expired, or periodically clean-up data. Timers can run once on start (`once_and_every`) and start running after a certain period (`every`).\n\n```ruby\ninstance = SlackRubyBotServer::Service.instance\n\ninstance.every :hour do\n  Team.each do |team|\n    begin\n      # do something with every team once an hour\n    rescue StandardError\n    end\n  end\nend\n\ninstance.once_and_every :minute do\n  # called once on start, then every minute\nend\n\ninstance.every :minute do\n  # called every minute\nend\n\ninstance.every :second do\n  # called every second\nend\n\ninstance.every 30 do\n  # called every 30 seconds\nend\n```\n\nNote that, unlike callbacks, timers are global for the entire service. Timers are independent, and a failing timer will not terminate other timers.\n\n##### Extensions\n\nA number of extensions use service manager callbacks and service timers to implement useful functionality.\n\n* [slack-ruby-bot-server-events](https://github.com/slack-ruby/slack-ruby-bot-server-events): Easily handle Slack slash commands, interactive buttons and events.\n* [slack-ruby-bot-server-mailchimp](https://github.com/slack-ruby/slack-ruby-bot-server-mailchimp): Subscribes new bot users to a Mailchimp mailing list.\n* [slack-ruby-bot-server-stripe](https://github.com/slack-ruby/slack-ruby-bot-server-stripe): Enables paid bots with trial periods and commerce through Stripe.\n* [slack-ruby-bot-server-rtm](https://github.com/slack-ruby/slack-ruby-bot-server-rtm): Create RTM Slack bots.\n\n#### Service Class\n\nYou can override the service class to handle additional methods.\n\n```ruby\nclass MyService \u003c SlackRubyBotServer::Service\n  def url\n    'https://www.example.com'\n  end\nend\n\nSlackRubyBotServer.configure do |config|\n  config.service_class = MyService\nend\n\nSlackRubyBotServer::Service.instance # MyService\nSlackRubyBotServer::Service.instance.url # https://www.example.com\n```\n\n### HTML Templates\n\nThis library provides a [default HTML template and JS scripts](public) that implement the \"Add to Slack\" button workflow. Customize your pages by adding a `public` directory in your application and starting with a [index.html.erb](public/index.html.erb) template. The application's `views` and `public` folders are [loaded by default](lib/slack-ruby-bot-server/api/middleware.rb#L32).\n\nYou can add to or override template paths as follows.\n\n```ruby\nSlackRubyBotServer.configure do |config|\n  config.view_paths \u003c\u003c File.expand_path(File.join(__dir__, 'public'))\nend\n```\n\n### Access Tokens\n\nBy default the implementation of [Team](lib/slack-ruby-bot-server/models/team) stores the value of the token with all the requested OAuth scopes in both `token` and `activated_user_access_token` (for backwards compatibility), along with `oauth_version` and `oauth_scope`. If a legacy Slack bot integration `bot_access_token` is present, it is stored as `token`, and `activated_user_access_token` is the token that has all the requested OAuth scopes.\n\n## Sample Bots Using Slack Ruby Bot Server\n\n### Slack Bots with Granular Permissions\n\n* [slack-ruby-bot-server-events-sample](https://github.com/slack-ruby/slack-ruby-bot-server-events-sample), a generic sample\n* [slack-rails-bot-starter](https://github.com/CrazyOptimist/slack-rails-bot-starter), an all-in-one Rails starter kit\n\n### Legacy Slack Bots\n\n* [slack-ruby-bot-server-sample](https://github.com/slack-ruby/slack-ruby-bot-server-sample), a generic sample\n* [slack-sup](https://github.com/dblock/slack-sup), see [sup.playplay.io](https://sup.playplay.io)\n* [slack-gamebot](https://github.com/dblock/slack-gamebot), see [www.playplay.io](https://www.playplay.io)\n* [slack-market](https://github.com/dblock/slack-market), see [market.playplay.io](https://market.playplay.io)\n* [slack-shellbot](https://github.com/slack-ruby/slack-shellbot), see [shell.playplay.io](https://shell.playplay.io)\n* [slack-api-explorer](https://github.com/slack-ruby/slack-api-explorer), see [api-explorer.playplay.io](https://shell.playplay.io)\n* [slack-strava](https://github.com/dblock/slack-strava), see [slava.playplay.io](https://slava.playplay.io)\n* [slack-arena](https://github.com/dblock/slack-arena), see [arena.playplay.io](https://arena.playplay.io)\n\n## Copyright \u0026 License\n\nCopyright [Daniel Doubrovkine](http://code.dblock.org) and Contributors, 2015-2020\n\n[MIT License](LICENSE)\n","funding_links":["https://github.com/sponsors/dblock"],"categories":["Ruby",":hammer_and_wrench: \u0026nbsp; Libraries and SDKs"],"sub_categories":["Ruby"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslack-ruby%2Fslack-ruby-bot-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslack-ruby%2Fslack-ruby-bot-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslack-ruby%2Fslack-ruby-bot-server/lists"}