pechkin 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2166aaacd30bc05dfd296593e02d22cc097d5106dd7dad58572650d4580b6342
4
- data.tar.gz: fcc1bd8cb27ad1d4d7758574b1ee33706aac3d76c033fb7b3558b9a46fc3ff0d
3
+ metadata.gz: c09b7bf36267e573df915d23e6151a6ea001ce2a807fb4859d07b09f051d6c09
4
+ data.tar.gz: 6a7740e99df749f0a049162eaeff88f9d1e91f6cf6656df6559f51c9994dcbf9
5
5
  SHA512:
6
- metadata.gz: 63f33140ef49b37016263d006ef0ae7b0dd7773b5d865584a8eb9f784b498e1998b0218120105be6337db739f9e1daaf44b333d0a490f33b153591dba2168421
7
- data.tar.gz: 7c80b47d54c900718b9defb2533b45d35597ba2db15bc66f944f96ca7f8a09a57573761628171505846f7dfc4ded42483fffd993e7bda587f7925ebe6974f9d3
6
+ metadata.gz: 5d04a31b930b50e3667cd566ab8bd42fe3be462a98432d375ae851f121adbd321fbd0198acbd6edeb6e1694dca1918d1e7c1d31683e8fecfe287bc23775037ec
7
+ data.tar.gz: 64dc0d47c19686d613f652366024b55a495e4a124cdd46a6f72c1e543a5f0739682e00147496dd972e3f772517b3b76458bd27a406b35d8b8731f565bcdca860
@@ -2,6 +2,9 @@ require 'rack'
2
2
  require 'logger'
3
3
 
4
4
  require_relative 'pechkin/cli'
5
+ require_relative 'pechkin/message'
6
+ require_relative 'pechkin/connector'
7
+ require_relative 'pechkin/channel'
5
8
  require_relative 'pechkin/api'
6
9
  require_relative 'pechkin/config'
7
10
 
@@ -1,5 +1,4 @@
1
1
  require 'grape'
2
- require_relative 'telegram'
3
2
  require 'json'
4
3
 
5
4
  module Pechkin # :nodoc:
@@ -10,29 +9,43 @@ module Pechkin # :nodoc:
10
9
  resource base_path do
11
10
  create_chanels(config['chanels'], config['bots'])
12
11
  end
12
+
13
13
  self
14
14
  end
15
15
 
16
16
  def create_chanels(chanels, bots)
17
17
  chanels.each do |chanel_name, chanel_desc|
18
- bot_token = bots[chanel_desc['bot']]
18
+ bot = bots[chanel_desc['bot']]
19
+ connector = create_connector(bot, chanel_name)
20
+
19
21
  chat_ids = chanel_desc['chat_ids']
20
- bot = Telegram::Chanel.new(bot_token, chat_ids)
21
- bot.logger = logger
22
+ channel = Chanel.new(connector, chat_ids)
23
+ channel.logger = logger
22
24
  resource chanel_name do
23
- create_chanel(bot, chanel_desc)
25
+ create_chanel(channel, chanel_desc)
24
26
  end
25
27
  end
26
28
  end
27
29
 
28
- def create_chanel(bot, chanel_desc)
30
+ def create_connector(bot, channel_name)
31
+ case bot['connector']
32
+ when 'tg', 'telegram'
33
+ TelegramConnector.new(bot['token'])
34
+ when 'slack'
35
+ SlackConnector.new(bot['token'])
36
+ else
37
+ raise 'Unknown connector ' + bot['connector'] + ' for ' + channel_name
38
+ end
39
+ end
40
+
41
+ def create_chanel(channel, chanel_desc)
29
42
  chanel_desc['messages'].each do |message_name, message_desc|
30
- generate_endpoint(bot, message_name, message_desc)
43
+ generate_endpoint(channel, message_name, message_desc)
31
44
  end
32
45
  end
33
46
 
34
47
  # rubocop:disable Metrics/AbcSize
35
- def generate_endpoint(bot, message_name, message_desc)
48
+ def generate_endpoint(channel, message_name, message_desc)
36
49
  params do
37
50
  # TODO: Can't extract this code to method because this block is
38
51
  # evaluated in separate scope
@@ -44,7 +57,7 @@ module Pechkin # :nodoc:
44
57
  end
45
58
  post message_name do
46
59
  template = message_desc['template']
47
- opts = { markup: 'HTML' }.update(message_desc['options'] || {})
60
+ opts = message_desc['options'] || {}
48
61
  # Some services will send json, but without correct content-type, then
49
62
  # params will be parsed weirdely. So we try parse request body as json
50
63
  params = ensure_json(request.body.read, params)
@@ -54,7 +67,7 @@ module Pechkin # :nodoc:
54
67
  # received parameters.
55
68
  params = (message_desc['variables'] || {}).merge(params)
56
69
 
57
- bot.send_message(template, params, opts)
70
+ channel.send_message(template, params, opts)
58
71
  end
59
72
  # rubocop:enable Metrics/AbcSize
60
73
  end
@@ -68,7 +81,7 @@ module Pechkin # :nodoc:
68
81
  JSON.parse(body) # Try parse body as json. If it possible will return as
69
82
  # params
70
83
  end
71
- rescue JSON::JSONError => _error
84
+ rescue JSON::JSONError => _e
72
85
  params
73
86
  end
74
87
 
@@ -0,0 +1,34 @@
1
+ module Pechkin
2
+ # Creates object which can send messages to assigned chanels
3
+ class Chanel
4
+ attr_accessor :logger
5
+
6
+ def initialize(connector, channel_list)
7
+ @connector = connector
8
+ @channel_list = channel_list
9
+ @channel_list = [channel_list] unless channel_list.is_a?(Array)
10
+ @logger = ::Logger.new(STDOUT)
11
+ end
12
+
13
+ def send_message(message, data, options)
14
+ text = Message.new(data).render(message)
15
+ logger.warn 'Resulting text is empty' if text.empty?
16
+ results = @channel_list.map { |id| @connector.send_message(id, text, options) }
17
+ process_results(message, results)
18
+ end
19
+
20
+ private
21
+
22
+ def process_results(message, results)
23
+ success, error = results.partition { |_chat, code, _body| code < 400 }
24
+ error.each do |chat, code, body|
25
+ logger.error "#{message} => #{chat}[HTTP #{code}]: #{body}"
26
+ end
27
+
28
+ {
29
+ successful: success.map(&:first),
30
+ errors: error
31
+ }
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,57 @@
1
+ require 'open-uri'
2
+ require 'net/http'
3
+ require 'uri'
4
+ require 'json'
5
+
6
+ module Pechkin
7
+ # Base connector
8
+ class Connector
9
+ def send_message(chat, message, options); end
10
+
11
+ def post_data(url, data, headers: {})
12
+ uri = URI.parse(url)
13
+ headers = { 'Content-Type' => 'application/json' }.merge(headers)
14
+ http = Net::HTTP.new(uri.host, uri.port)
15
+ http.use_ssl = url.start_with?('https://')
16
+
17
+ request = Net::HTTP::Post.new(uri.request_uri, headers)
18
+ request.body = data.to_json
19
+
20
+ http.request(request)
21
+ end
22
+ end
23
+
24
+ class TelegramConnector < Connector #:nodoc:
25
+ def initialize(bot_token)
26
+ @bot_token = bot_token
27
+ end
28
+
29
+ def send_message(chat_id, message, options = {})
30
+ options = { markup: 'HTML' }.update(options)
31
+ params = options.update(chat_id: chat_id, text: message)
32
+
33
+ response = post_data(method_url('sendMessage'), params)
34
+ [chat_id, response.code.to_i, response.body]
35
+ end
36
+
37
+ private
38
+
39
+ def method_url(method)
40
+ "https://api.telegram.org/bot#{@bot_token}/#{method}"
41
+ end
42
+ end
43
+
44
+ class SlackConnector < Connector # :nodoc:
45
+ def initialize(bot_token)
46
+ @headers = { 'Authorization' => "Bearer #{bot_token}" }
47
+ end
48
+
49
+ def send_message(chat, message, options)
50
+ params = options.update(channel: chat, text: message)
51
+ url = 'https://slack.com/api/chat.postMessage'
52
+ response = post_data(url, params, headers: @headers)
53
+
54
+ [chat, response.code.to_i, response.body]
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,8 @@
1
+ module Pechkin
2
+ # Easy way to render erb template
3
+ class Message < OpenStruct
4
+ def render(template_file)
5
+ ERB.new(IO.read(template_file)).result(binding)
6
+ end
7
+ end
8
+ end
@@ -1,7 +1,7 @@
1
1
  module Pechkin
2
2
  # Keeps actual version
3
3
  module Version
4
- VERSION = [0, 0, 5].freeze
4
+ VERSION = [0, 1, 0].freeze
5
5
  class << self
6
6
  def version_string
7
7
  VERSION.join('.')
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pechkin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ilya Arkhanhelsky
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-03 00:00:00.000000000 Z
11
+ date: 2019-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grape
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: 1.1.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: 1.1.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rack
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -48,9 +48,11 @@ files:
48
48
  - bin/pechkin
49
49
  - lib/pechkin.rb
50
50
  - lib/pechkin/api.rb
51
+ - lib/pechkin/channel.rb
51
52
  - lib/pechkin/cli.rb
52
53
  - lib/pechkin/config.rb
53
- - lib/pechkin/telegram.rb
54
+ - lib/pechkin/connector.rb
55
+ - lib/pechkin/message.rb
54
56
  - lib/pechkin/version.rb
55
57
  homepage: https://github.com/iarkhanhelsky/pechkin
56
58
  licenses:
@@ -71,8 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
73
  - !ruby/object:Gem::Version
72
74
  version: '0'
73
75
  requirements: []
74
- rubyforge_project:
75
- rubygems_version: 2.7.6
76
+ rubygems_version: 3.0.3
76
77
  signing_key:
77
78
  specification_version: 4
78
79
  summary: Web service to proxy webhooks to Telegram Bot API
@@ -1,61 +0,0 @@
1
- require 'erb'
2
- require 'open-uri'
3
- require 'net/http'
4
-
5
- module Pechkin
6
- module Telegram
7
- # Easy way to render erb template
8
- class Message < OpenStruct
9
- def render(template_file)
10
- ERB.new(IO.read(template_file)).result(binding)
11
- end
12
- end
13
- # Creates object which can send messages to assigned chanels
14
- class Chanel
15
- attr_accessor :logger
16
-
17
- def initialize(bot_token, chat_ids)
18
- @bot_token = bot_token
19
- @chat_ids = chat_ids
20
- @chat_ids = [chat_ids] unless chat_ids.is_a?(Array)
21
- @logger = ::Logger.new(STDOUT)
22
- end
23
-
24
- def send_message(message, data, options)
25
- text = Message.new(data).render(message)
26
- logger.warn 'Resulting text is empty' if text.empty?
27
- results = @chat_ids.map { |id| send_message_to_id(id, text, options) }
28
- process_results(message, results)
29
- end
30
-
31
- private
32
-
33
- def send_message_to_id(chat_id, text, options)
34
- params = options.update(text: text, chat_id: chat_id)
35
- response = send_data('sendMessage', params)
36
- [chat_id, response.code.to_i, response.body]
37
- end
38
-
39
- def send_data(method, data = {})
40
- url = URI.parse(method_url(method))
41
- Net::HTTP.post_form(url, data)
42
- end
43
-
44
- def process_results(message, results)
45
- success, error = results.partition { |_chat, code, _body| code < 400 }
46
- error.each do |chat, code, body|
47
- logger.error "#{message} => #{chat}[HTTP #{code}]: #{body}"
48
- end
49
-
50
- {
51
- successful: success.map(&:first),
52
- errors: error
53
- }
54
- end
55
-
56
- def method_url(method)
57
- "https://api.telegram.org/bot#{@bot_token}/#{method}"
58
- end
59
- end
60
- end
61
- end