- APIボット用の軽量クライアント。
- メッセージパーサーを使用した更新コントローラーの基本クラス。 ActionDispatchのAbstractControllerに基づいており、コールバック、セッション、メッセージのコンテキストの保存などを提供します。
- 更新フックを受け入れるプロダクション用のラックミドルウェアと、便利な開発のために更新されたコードを自動的にロードするポーラー。
- すくいタスク、鉄道ルートとテストのヘルパー。
面白い? インストールするには、
Gemfile
telegram-bot
を追加し、詳細をカットします。
ボットAPIのクライアント
クライアントの作成は簡単です:
Telegram::Bot::Client.new(token, username)
。
username
値はオプションであり、呼び出し(
/cmd@BotName
)およびKey-Valueストアのセッションキープレフィックス内のコマンドを解析するために使用されます。
基本的なクライアントメソッドは
request(path_suffix, body)
。ドキュメントのすべてのチームには、Rubyスタイルのショートカットがあります-アンダースコア(
.send_message(body)
、
answer_inline_query(body)
)。 これらのメソッドはすべて、目的のURLに渡されたパラメーターを使用してPOSTを実行するだけです。
body
ファイルは
multipart/form-data
で自動的に転送され、添付のハッシュはドキュメントで必要とされるようにjsonでエンコードされます。
bot.request(:getMe) or bot.get_me bot.request(:getupdates, offset: 1) or bot.get_updates(offset: 1) bot.send_message chat_id: chat_id, text: 'Test' bot.send_photo chat_id: chat_id, photo: File.open(photo_filename)
すぐに使用できるように、クライアントは各リクエストに対して通常の分散jsonを返します。 telegram-
telegram-bot-types
を使用して、出力でvirtus-modelsを取得できます。
# Gemfile: gem 'telegram-bot-types', '~> xxx' # typecasting : Telegram::Bot::Client.typed_response! # : bot.extend Telegram::Bot::Client::TypedResponse bot.get_me.class # => Telegram::Bot::Types::User
カスタマイズ
gemは、アプリケーションに共通のクライアントをセットアップしてアクセスするためのメソッドを
Telegram
モジュールに追加します(これらはスレッドセーフであり、複数のスレッドで問題はありません)。
# Telegram.bots_config = { # default: 'bot_token', # username chat: { token: 'other_token', username } } # : Telegram.bots[:chat].send_message(params) Telegram.bots[:default].send_message(params) # :default (, ): Telegram.bot.get_me
Railsアプリケーションの場合、
bots_config
を手動で設定せずに実行できます。設定は
bots_config
から読み取られ
secrets.yml
。
development: telegram: bots: chat: TOKEN_1 default: token: TOKEN_2 username: ChatBot # bots.default bot: token: TOKEN username: SomeBot
コントローラー
更新を処理するために、gemにはベースコントローラークラスがあります。
ActionController
と同様に、すべてのパブリックメソッドはコマンドを処理するためのアクションメソッドとして使用されます。 つまり、メッセージ
/cmd arg 1 2
が到着すると、
cmd('arg', '1', '2')
メソッド
cmd('arg', '1', '2')
が呼び出されます(定義されていてパブリックの場合)。 ActionControllerとは異なり、サポートされていないコマンドが到着した場合、ActionMissingエラーなしで単に無視されます。
コントローラーは参照付きのコマンドを処理できます。 これが発生すると、コマンドの名前
username
ボットの
username
と比較され
username
。 一致する場合、コマンドが実行されます。一致しない場合、メッセージはプレーンテキストとして処理されます。
他の更新(メッセージではない)を処理するには、更新タイプの名前からpublicメソッドを定義する必要もあります(現在、3つのオプションが利用可能です: `message、inline_query、selected_inline_result ')。 これらのメソッドは、更新から対応するオブジェクトを引数として受け取ります。
通知に応答するために、受信した更新から受信者およびその他のフィールドを公開する
reply_with(type, params)
および
answer_inline_query(results, params)
ヘルパーがあります。
class TelegramWebhookController < Telegram::Bot::UpdatesController def message(message) reply_with text: "Echo: #{message['text']}" end def start(*) # chat from: reply_with text: "Hello #{from['username']}!" if from # payload: log { "Started at: #{payload['date']}" } end # splat- # -, # , . def help(cmd = nil, *) message = if cmd help_for_cmd?(cmd) ? t(".cmd.#{cmd}") : t('.no_help') else t('.help') end reply_with text: message end end
ほとんどの場合、ボットはメッセージ間のチャットの状態を記憶する必要があります。 これを行うには、コントローラーでセッションを使用できます。 このインターフェースはActionControllerのセッションインターフェースに似ていますが、違いは保存方法です。 任意のActiveSupport ::キャッシュ互換ストレージ(
redis-activesupport
など)をアダプターとして使用できます。
デフォルトでは、この値はセッションIDとして使用されます(メソッドをオーバーライドすることで変更できます)。
def session_key "#{bot.username}:#{from ? "from:#{from['id']}" : "chat:#{chat['id']}"}" end
セッションを使用して、メッセージコンテキストを実装できます-複数のメッセージで送信されるコマンドのサポート:ユーザーは引数なしでコマンドを送信し、ボットは期待する引数を指定し、ユーザーは次のメッセージでそれらを送信します(たとえば、BotFatherが行うように)。 このような機能は、
Telegram::Bot::UpdatesController::MessageContext
利用でき
Telegram::Bot::UpdatesController::MessageContext
:
class TelegramWebhookController < Telegram::Bot::UpdatesController include Telegram::Bot::UpdatesController::MessageContext def rename(*) # : save_context :rename reply_with :message, text: 'What name do you like?' end # : context_handler :rename do |message| update_name message[:text] reply_with :message, text: 'Renamed!' end # -. rename, # . def rename(name = nil, *) if name update_name name reply_with :message, text: 'Renamed!' else # , : save_context :rename reply_with :message, text: 'What name do you like?' end end # , . # , , # '/rename %text%' context_handler :rename # , : context_to_action! # . end
アプリケーション統合
コントローラーはいくつかの方法で使用できます。
# : ControllerClass.dispatch(bot, update) # , . controller = ControllerClass.new(bot, from: telegram_user, chat: telegram_chat) controller.process(:help, *args)
フックを処理するためのラックエンドポイントがあります。 Railsアプリケーションにはルートヘルパーがあります。ボットトークンがパスサフィックスとして使用されます。 アプリケーションで単一のボットを使用する場合は、次を追加します。
# routes.rb telegram_webhooks Telegram::WebhookController
このヘルパーを使用すると、タスクを使用して結果のURLを使用して、ボットの
setWebhook
を設定できます。
rake telegram:bot:set_webhook RAILS_ENV=production
テスト中
gemには、テストでAPIクライアントを置き換える
Telegram::Bot::ClientStub
があります。 クエリを実行する代わりに、
#requests
ハッシュに保存します。 作成されたすべてのクライアントをストールさせ、テスト実行中にTelegramにリクエストを送信しないようにするには、次のように記述できます。
RSpec.configure do |config| # ... Telegram.reset_bots Telegram::Bot::ClientStub.stub_all! config.after { Telegram.bot.reset } # ... end
ActionControllerと同じ方法でコントローラーをテストするためのヘルパーがあります。
require 'telegram/bot/updates_controller/rspec_helpers' RSpec.describe TelegramWebhookController do include_context 'telegram/bot/updates_controller' describe '#rename' do subject { -> { dispatch_message "/rename #{new_name}" } } let(:new_name) { 'new_name' } it { should change { resource.reload.name }.to(new_name) } end end
開発とデバッグ
ローカルデバッグの場合、更新ポーラーを実行できます。 これを行うには、おそらく別のボットを作成する必要があります。
rake telegram:bot:poller
は
rake telegram:bot:poller
を起動します。 更新の処理時にコードの更新が自動的にダウンロードされるため、プロセスを再起動する必要はありません。
ソースコードと詳細な説明はgithubで入手できます。
素晴らしい開発を!