diff --git a/CHANGELOG.md b/CHANGELOG.md index adf4b7c..17757c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased +- Read config from secrets when credentials don't provide it in rails >= 5.2. - Remove botan.io support. It's already shut down, so it should not be a braking change. https://github.com/botanio/sdk#this-service-will-be-shut-down-on-25th-may-2018 diff --git a/README.md b/README.md index 18660e6..e880ada 100644 --- a/README.md +++ b/README.md @@ -55,9 +55,28 @@ require 'telegram/bot' ## Usage +### Configuration + +While clients can be instantiated explicitly, there is `Telegram.bots_config=` method +to configure app-wide clients, which are accessible via `Telegram.bots`. +It accepts hash of `{bot_id: bot_config}`, and there is special id `:default` +which is used for `Telegram.bot`. + +```ruby +Telegram.bots_config = { + default: DEFAULT_BOT_TOKEN, + chat: {token: CHAT_BOT_TOKEN, username: 'chatbot'}, +} + +Telegram.bot.get_updates +Telegram.bot == Telegram.bots[:default] # true +Telegram.bots[:chat].send_message(...) +``` + ### Configuration in Rails app -For Rails < 5.2 add `telegram` section into `secrets.yml`: +In Rails app `Telegram.bots_config` is read from `secrets.yml` automatically +from `telegram` section: ```yml development: @@ -79,7 +98,14 @@ development: username: ChatBot ``` -For Rails > 5.2 edit credentials `EDITOR=nano rails credentials:edit` +For Rails >= 5.2 `Telegram::Bot` searches for config first in credentials and then in secrets. +To use credentials as config store, add telegram section to credentials instead of secrets using +`rails credentials:edit`. In this case be aware of that [Rails may not load +credentials in dev environment by default](https://github.com/telegram-bot-rb/telegram-bot/issues/74#issuecomment-384205609). + +I suggest not using Rails 5.2 credentials because it can lead to leakage of sesitive data +and it's more difficult to use in multiple environments. See +[secure_credentials](https://github.com/printercu/secure_credentials) gem for better option. From now clients will be accessible with `Telegram.bots[:chat]` or `Telegram.bots[:auction]`. Single bot can be accessed with `Telegram.bot` or `Telegram.bots[:default]`. diff --git a/lib/telegram/bot/config_methods.rb b/lib/telegram/bot/config_methods.rb index 8b4c275..154371c 100644 --- a/lib/telegram/bot/config_methods.rb +++ b/lib/telegram/bot/config_methods.rb @@ -48,10 +48,12 @@ module Telegram @bots_config ||= if defined?(Rails.application) app = Rails.application - store = app.respond_to?(:credentials) ? app.credentials : app.secrets - secrets = store.fetch(:telegram, {}).with_indifferent_access - secrets.fetch(:bots, {}).symbolize_keys.tap do |config| - default = secrets[:bot] + store = app.credentials[:telegram] if app.respond_to?(:credentials) + store ||= app.secrets[:telegram] if app.respond_to?(:secrets) + store ||= {} + store = store.with_indifferent_access + store.fetch(:bots, {}).symbolize_keys.tap do |config| + default = store[:bot] config[:default] = default if default end else diff --git a/spec/telegram/bot/config_methods_spec.rb b/spec/telegram/bot/config_methods_spec.rb index 3f2dbec..e8acd96 100644 --- a/spec/telegram/bot/config_methods_spec.rb +++ b/spec/telegram/bot/config_methods_spec.rb @@ -61,13 +61,14 @@ RSpec.describe Telegram::Bot::ConfigMethods do it { should eq({}) } context 'in rails environment' do - before { stub_const('Rails', double(application: double(secrets: secrets))) } + before { stub_const('Rails', double(application: double(app_stub))) } + let(:app_stub) { {secrets: secrets} } let(:secrets) { {} } it { should eq({}) } context 'when there is telegram section in secrets' do - let(:secrets) { {telegram: config.stringify_keys} } - let(:config) do + let(:secrets) { {telegram: secrets_config} } + let(:secrets_config) do { bot: double(:bot_config), bots: { @@ -76,13 +77,21 @@ RSpec.describe Telegram::Bot::ConfigMethods do }, } end - it { should include default: config[:bot] } - it { should include config[:bots] } + it { should include default: secrets_config[:bot] } + it { should include secrets_config[:bots] } context 'on rails >5.1 (deep symbolized keys)' do - let(:secrets) { {telegram: config.deep_symbolize_keys} } - it { should include default: config[:bot] } - it { should include config[:bots] } + let(:secrets) { super().deep_symbolize_keys } + it { should include default: secrets_config[:bot] } + it { should include secrets_config[:bots] } + end + + context 'and credentials (>= 5.2)' do + let(:app_stub) { super().merge(credentials: credentials) } + let(:credentials) { {telegram: credentials_config} } + let(:credentials_config) { {bot: double(:credentials_bot_config)} } + it { should include default: credentials_config[:bot] } + it { should_not include secrets[:bots] } end end end