解決策はハンマーのように簡単です。 サービスからのフックを受け入れ、必要な形式でSlackを処理およびスローします。
リスト内の統合とともに、 ハンモックが発見されました。これはPHPで記述され、特定のプラグインのセットを備えていますが、このソリューションは特に好まれませんでした。 既成の統合はありますが、残念ながら、それらは必要ありません。また、コードを読み取り、「ディレクトリ内の何かを修正する」レベルでPHPに精通しているため、独自のコードを作成する必要はありません。
したがって、私は自分のサービスを書くことにしました。 コアと、「入力」と「出力」用の個別のモジュールという、モジュールベースで完全に構築することにしました。 Rubyを言語として使用しましたが、その動的な性質はこの計画の実装に大いに役立ちました。
会いましょう
フックラー!
通知を受信してさらに送信するための最小限のコードでサービスを収集できます。 設定するには、独自のDSLを使用します。
require 'hooksler/slack' require 'hooksler/newrelic' require 'hooksler/trello' require 'dotenv' Dotenv.load Hooksler::Router.config do secret_code 'very_secret_code' host_name 'http://example.com' endpoints do input 'simple', type: :simple input 'newrelic', type: :newrelic input 'trello', type: :trello, create: false, public_key: ENV['TRELLO_KEY'], member_token: ENV['TRELLO_TOKEN'], board_id: ENV['TRELLO_ID1'] output 'black_hole', type: :dummy output 'slack_out', type: :slack, url: ENV['SLACK_WEBHOOK_URL'], channel: '#test' end route 'simple' => 'slack_out' route 'trello' => ['black_hole', 'slack_out'] route 'newrelic' => ['black_hole', 'slack_out'] end
初めに、入力入力ポイントが宣言され、それぞれが独自の名前とタイプを持ち、初期化のための追加のパラメーターを含むこともあります。 ルートは次のとおりです。 別の形式で指定できます。1対1、1対多、またはその逆です。
また、各ルートにフィルターを配置できます。フィルターは、メッセージの変更とフィルターの両方を行うことができます。 したがって、ポイントAからポイントBにメッセージをルーティングするための十分に柔軟なカーネルを取得します。
内部のメッセージは内部表現で送信されますが、受信されたサービス(タイプ)+元のメッセージは既知です。 受信すると、一般的なフィールドが入力されます:ユーザー、テキスト、タイトル、リンク、レベル。 将来的には、それらを使用して通知を生成できます。
現時点では、カーネルは完全に実装、テストされ、テストでカバーされています。 いくつかの統合も実装されています:trello、newrelic、slack。 統合の作成は非常に簡単です。
ちょっとした練習
メッセージを受信する
たとえば、POSTリクエストの本文をメッセージフィールドに配置できるモジュールを作成します。
class DummyInput extend Hooksler::Channel::Input register :dummy def initialize(params) @params = params end def load(request) build_message({}) do |msg| msg.message = request.body.read end end end
クラスを宣言し、適切なモジュールで拡張します。 次に、彼の名前を登録します。 すべて、その後、着信データを受信して処理する準備が整いました。 要求処理は、 Rack :: Requestクラスのオブジェクトという1つのパラメーターのみをとるloadメソッドで実行されます。 複雑な処理は必要ありませんので、すぐにメッセージを作成してフィールドに入力してください。 その後、構成で説明されているルートに沿ってさらに進みます。 送信のために、複数のメッセージを一度に作成できます。 loadメソッドは配列を返します。 将来、各オブジェクトは個別に処理されます。
メッセージを送信する
送信用のモジュールを作成するのも簡単です。これにより、受信したメッセージをコンソールで確認できます。
class DummyOutput extend Hooksler::Channel::Output register :dummy def initialize(params) @params = params end def dump(message) puts "-- #{message.title} : #{message.level} --" puts message.user puts message.message puts message.url end end
着信アクションと同じアクションを実行し、適切な拡張モジュールのみを選択します。 この場合、コンソールへの出力の送信は、 dumpメソッドで実行されます。 メソッド名は議論の余地がありますが、sendはすでに使用されているため、再定義したくありませんでした。
それでは、すべてを収集してルートを説明しましょう。
Hooksler::Router.config do secret_code 'very_secret_code' host_name 'http://example.com' endpoints do input 'in', type: :dummy output 'out', type: :dummy end route 'in' => 'out' end
パスを生成するために使用されるコードと、サービスがハングするホストを示します。 開始し、準備ができました。 最終パスはアドレスhttp://example.com/_endpoints_で確認できます。応答はJSONです。 より詳細な例は、DEMOアプリケーションで見ることができます: github.com/hooksler/hooksler-demo
したがって、多くの労力をかけずに、異なるポイントに同時にメッセージを送信するように設定できます。Trelloからの変更の受信、Slackへの変更の送信、または電話へのプッシュを介した重要な変更(キーワードやタグなど)の送信。 たくさんのスキームを思いつくことができ、その利点は柔軟です。
より実用的な例。
先日、ユーザーをSlackに招待するプロセスを自動化するタスクがありました。 それぞれを手動で追加するのは長くて面倒ですが、すぐにオープン登録を行うことはできません。 インターネット上のnodejsには既製のフォームがあります。 しかし、以来 私はすでにそれでやろうと決めた作業フックラーを持っています。 まず、なんらかの方法で正しいメールを取得する必要があります。これは、Webhookで受信メッセージをラップするMandrillの機能を利用しました(医師が注文したものだけです)。 次に、受信トレイを作成し、Webhookを構成して、レシーバーを記述します。
require 'hashie' module Hooksler module Mandrill class Input extend Hooksler::Channel::Input register :mandrill def initialize(params) @params = Hashie::Mash.new(params) end def load(request) return unless request.content_type == 'application/x-www-form-urlencoded' action, payload = request.POST.first return unless action == 'mandrill_events' payload = MultiJson.load(payload) payload.map do |event| build_message(event) do |msg| begin method_name = "for_#{event['event']}" self.send method_name, msg, event if respond_to? method_name rescue end end end end def for_inbound(msg, event) msg.message = event['msg']['text'] || event['msg']['html'] msg.title = event['msg']['subject'] msg.user = event['msg']['headers']['From'] end end end end
イベントを受け入れ、メッセージとヘルメットをさらに包み込みます。 次に、ユーザーの招待を実行するコードが必要です。
class SlackInviteOutbound extend Hooksler::Channel::Output register :slack_invite def initialize(params) @params = params end def dump(message) return unless message.source == :mandrill email = message.raw['msg']['from_email'] url = "https://#{@params[:team]}.slack.com/api/users.admin.invite" HTTParty.post url, body: { email: email, token: @params[:token], set_active: true } end end
メッセージを受け入れ、マンドリルからのものであることを確認し、メール、リクエストを受け取り、ユーザーを招待します。 同時に、ボックスが有効であると確信しています。
最後の仕上げとして、ルーティングのセットアップ:
endpoints do input 'slack_invite', type: :mandrill output 'slack_invite', type: :slack_invite, team: 'myteam', token: 'mysupersecrettoken' end route 'slack_invite' => 'slack_invite'
プロセスを開始し、楽しんでいます。
結論として
問題が発生するまで、すべてを安定して実行するまで、私はこのソリューションをしばらく使用しています。 唯一のことは、trelloの場合、すべてのケースが処理されているわけではなく、すでに多くの異なるタイプの通知があることです。 また、Slackの場合、独自のフォーマットモジュールが作成されました 。興味のある方はこちらの例をご覧ください 。
将来的には、メッセージの受信と送信の両方でアダプターの数を増やす計画です。 このソリューションが他の誰かに役立つことを願っています。
批判と提案は歓迎です。PMのテキストにエラーメッセージがあります。
Hooksler自体とアダプターはGithubで入手できます: github.com/hooksler