te_bot 0.1.0 → 0.2.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: 7d234f02d1972e727baf9fbc6576e7d9f2ef437c10ccdeb3cc208c3f2f3dd092
4
- data.tar.gz: b5f032d95cab54dec2387cd9e1ad662d05f846f73247c8c64aa233e837e92678
3
+ metadata.gz: 84afe807cfff02952abed21f9ad1e9cd4c4a337c2fc9d789960fe68de2e37b6c
4
+ data.tar.gz: 6b0616f98f5fca8cfe3583e97f59a5ce4149adaadfd2bb130f88a9f9449f436b
5
5
  SHA512:
6
- metadata.gz: e810fb8f9052cd7c8ee2727acfbed634422a503f918b2d0e02a3a382228696c7d6d8cc493861958a95188644b127f31d8739fcaceaa6e2e2cd41bbf5fe3bec70
7
- data.tar.gz: 9fb92b63eda3eda8b522e6455ee989fec4267809f6cf60819dfc082fbf02745e60a1e9378abe0f0ee8501dc083aeca65fe1e0ce06b8ea62216dbc1bf1a178519
6
+ metadata.gz: 1fe827e9835f85e930776fd4cb35964f20c3565d99ab2d2bb893cee9e0d61ab713858b3e218ef9157380d9e3af12b8f1c41ab511f559f36e0bd9f5f90392254d
7
+ data.tar.gz: 2cfbf9af5f37a95b1581cc2d44b883ecc8c49ffc1e639f693d53564115bbf705c315ad20ee5dbe9c23914621d40f8f06b89945a06987af5605c275c068c01b03
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- te_bot (0.1.0)
4
+ te_bot (0.2.0)
5
5
  faraday (~> 2.3)
6
6
  rack (~> 2.2)
7
7
 
@@ -57,6 +57,7 @@ GEM
57
57
  hashdiff (>= 0.4.0, < 2.0.0)
58
58
 
59
59
  PLATFORMS
60
+ x86_64-darwin-21
60
61
  x86_64-linux
61
62
 
62
63
  DEPENDENCIES
data/README.md CHANGED
@@ -1,21 +1,24 @@
1
1
  # ::TeBot
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/te_bot`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ [![Gem Version](https://badge.fury.io/rb/te_bot.svg)](https://badge.fury.io/rb/te_bot) ![Main Workflows](https://github.com/aaripurna/te_bot/actions/workflows/main.yml/badge.svg)
4
4
 
5
- This gem is used to handle telegram webhook and sending message with telegram bot
5
+ Welcome to yet another telegram bot webhook handler.
6
+
7
+ This gem is used to handle telegram webhook and sending message with telegram bot.
6
8
 
7
9
  ## Installation
8
10
 
9
11
  Install the gem and add to the application's Gemfile
10
12
 
11
- gem "te_bot", github: "aaripurna/te_bot"
13
+ gem 'te_bot', '~> 0.2.0'
14
+
12
15
  Then run
13
16
 
14
- $ bundle install
17
+ bundle install
15
18
 
16
19
  If bundler is not being used to manage dependencies, install the gem by executing:
17
20
 
18
- $ gem install te_bot -l https://github.com/aaripurna/te_bot.git
21
+ gem install te_bot
19
22
 
20
23
  ## Usage
21
24
 
@@ -25,23 +28,25 @@ This gem can be used as a standalone app since it implement rack interface. To u
25
28
  # app.rb
26
29
 
27
30
  require "te_bot"
31
+ require "te_bot/sender_options"
28
32
 
29
33
  class MyWebhookApp < TeBot::Court
30
- access_token ENV["YOUR_BOT_ACCESS_TOKEN"]
34
+ access_token ENV["YOUR_BOT_ACCESS_TOKEN"]
31
35
 
32
- command("/start") do |conn, params|
33
- reply(conn, "Welcome aboard my friend!")
34
- end
36
+ command("/start") do |conn|
37
+ conn.reply text: "Welcome aboard my friend!"
38
+ end
35
39
 
36
- command("/today") do |conn, params|
37
- reply(conn, Time.now.to_s)
38
- end
40
+ command("/today") do |conn|
41
+ conn.reply text: Time.now.to_s
42
+ end
39
43
  end
40
44
  ```
41
45
 
42
46
  To run this as a standalone app, you need to install `rack` and a webserver such as `puma`
43
47
 
44
- $ bundle add rack puma
48
+ bundle add rack puma
49
+
45
50
  create a file named `config.ru` as the rack entrypoint.
46
51
 
47
52
  ```rb
@@ -53,12 +58,12 @@ run MyWebhookApp.new
53
58
  ```
54
59
  To run the app we can use rackup
55
60
 
56
- $ bundle exec rackup
61
+ bundle exec rackup
57
62
 
58
63
  For more detailed information about rack please visit [Rack Repository](https://github.com/rack/rack).
59
64
 
60
65
  Now, our `MyWebhookApp` class is ready to handle some commands from telegram bot which are `/start` and `/today`.
61
- The command aslo support argument that will be passed to the `#command` block as `params`. To pass arguments, we can simply type `/today city:Jakarta limit:10`. The argument will be parsed as a Hash with string key => `{"city" => "Jakarta", "limit" => "10"}`. While the parameter `conn` is the message object which contains the full message including the chat_id to repy to.
66
+ The command aslo support argument that will be passed to the `#command` block as `conn.params`. To pass arguments, we can simply type `/today city:Jakarta limit:10`. The argument will be parsed as a Hash with string key => `{"city" => "Jakarta", "limit" => "10"}`. While the parameter `conn` is the message object which contains the full message including the chat_id to repy to.
62
67
 
63
68
  To add a default handler for non existing command we can use the `#default_command` macro.
64
69
 
@@ -66,9 +71,9 @@ To add a default handler for non existing command we can use the `#default_comma
66
71
  # app.rb
67
72
 
68
73
  class MyWebhookApp < TeBot::Court
69
- default_command do |conn, params|
70
- reply(conn, "Sorry, Comand not found. Try another command. or type /help")
71
- end
74
+ default_command do |conn|
75
+ conn.reply text: "Sorry, Comand not found. Try another command. or type /help"
76
+ end
72
77
  end
73
78
  ```
74
79
 
@@ -78,21 +83,21 @@ Other type of messages are also supported by using this macros `text` for regula
78
83
  # app.rb
79
84
 
80
85
  class MyWebhookApp < TeBot::Court
81
- text do |conn|
82
- message = do_some_fancy_stuff_here(conn)
83
- reply(conn, message)
84
- end
86
+ text do |conn|
87
+ message = do_some_fancy_stuff_here(conn)
88
+ conn.reply text: message
89
+ end
85
90
  end
86
91
  ```
87
- And also we can define a macro for defaul action `#default_action` if the request does not match with this [Documentation](https://core.telegram.org/bots/webhooks#testing-your-bot-with-updates), Or we have not create the handler for that specific message type. Just becarefull, the `conn.data` might returns nil if the message format doesnot match the documentation.
92
+ And also we can define a macro for defaul action `#default_action` if the request does not match with this [Documentation](https://core.telegram.org/bots/webhooks#testing-your-bot-with-updates), Or we have not create the handler for that specific message type.
88
93
 
89
94
  ```rb
90
95
  # app.rb
91
96
 
92
97
  class MyWebhookApp < TeBot::Court
93
- default_action do |conn|
94
- reply(conn, "No, I can't talk like people. use command instead") if conn.data&.chat_id
95
- end
98
+ default_action do |conn|
99
+ conn.reply text: "No, I can't talk like people. use command instead"
100
+ end
96
101
  end
97
102
  ```
98
103
  Since this app implements rack interface, and railr is also a rack based application. We can mount this app direcly inside rails app.
@@ -103,19 +108,44 @@ Since this app implements rack interface, and railr is also a rack based applica
103
108
  require "lib/to/your_webhook"
104
109
 
105
110
  Rails.application.routes.draw do
106
- mount MyAwessomWebhook.new => "telegram_webhook"
111
+ mount MyAwessomWebhook.new => "telegram_webhook"
107
112
  end
108
113
  ```
109
114
 
110
115
  ### Sending Message to Telegram
111
116
  To send message direcly to telegram, we can use this module `TeBot::Wire`
117
+ and need to require `"te_bot/sender_options"` to add default handler for different type of message.
118
+ Available message types are `:text`, `:markdown`, `:photo`, `:audio`, `:document`, `:video`, `:animation`, `:voice`
112
119
 
120
+ Some supported message by default:
113
121
  ```rb
114
122
  # app.rb
115
123
  sender = TeBot::Wire.new(ENV['YOUR_ACCESS_TOKEN_HERE'])
116
- sender.send_message(chat_id, message_string)
124
+ sender.send_message(chat_id, text: message_string)
125
+ sender.send_message(chat_id, markdown: markdown_string)
126
+
127
+ sender.send_message(chat_id, photo: { photo: url, caption: caption })
128
+ sender.send_message(chat_id, video: { video: url, caption: caption})
129
+ sender.send_message(chat_id, document: { document: url, caption: caption})
130
+ sender.send_message(chat_id, audio: { audio: url, caption: caption})
131
+ sender.send_message(chat_id, animation: { animation: url, caption: caption})
132
+
133
+ ```
134
+
135
+ For markdown telegram supports MArkdownV2 [refer to this](https://core.telegram.org/bots/api#markdownv2-style)
136
+ Please check the [documentation](https://core.telegram.org/bots/api#sendmessage) for more details.
137
+
138
+ Of course you add more handler by extending the `TeBot::Wire` class
139
+
140
+ ```ruby
141
+ # in/your/custom_handler.rb
142
+
143
+ TeBot::Wire.class_eval do
144
+ sender :json do |conn, chat_id, message|
145
+ conn.make_request("sendMessage", body: { chat_id: chat_id, json: message }.to_json)
146
+ end
147
+ end
117
148
  ```
118
- This gem only support [sendMessage](https://core.telegram.org/bots/api#sendmessage) API for this moment.
119
149
 
120
150
  ## Development
121
151
 
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TeBot
4
+ class Cable
5
+ attr_reader :message, :params
6
+ def initialize(wire, message, params = {})
7
+ @wire = wire
8
+ @message = message
9
+ @params = params
10
+ end
11
+
12
+ def chat_id
13
+ @message.data&.chat_id
14
+ end
15
+
16
+ def reply(**payload)
17
+ return if chat_id.nil?
18
+
19
+ @wire.send_message chat_id, **payload
20
+ end
21
+ end
22
+ end
data/lib/te_bot/court.rb CHANGED
@@ -20,14 +20,6 @@ module TeBot
20
20
  @default_action ||= block
21
21
  end
22
22
 
23
- def reply(conn, message)
24
- send_message(conn.data&.chat_id, message)
25
- end
26
-
27
- def send_message(chat_id, message)
28
- wire.send_message(chat_id, message)
29
- end
30
-
31
23
  def command(text, &block)
32
24
  @commands ||= {}
33
25
  @commands[text] = block
@@ -74,14 +66,15 @@ module TeBot
74
66
  def handle_request(body)
75
67
  message = ::TeBot::Message.new(body)
76
68
 
69
+ command, params = message.data&.content&.parse
70
+ conn = ::TeBot::Cable.new(self.class.wire, message, params || {})
71
+
77
72
  message.command do
78
- command, params = message.data.content.parse
79
73
  handler = self.class.commands[command]
80
-
81
74
  if handler.respond_to?(:call)
82
- handler.call(message, params)
75
+ handler.call(conn)
83
76
  elsif self.class.default_command.respond_to?(:call)
84
- self.class.default_command.call(message, params)
77
+ self.class.default_command.call(conn)
85
78
  end
86
79
  end
87
80
 
@@ -90,14 +83,14 @@ module TeBot
90
83
  handler = self.class.public_send(f)
91
84
 
92
85
  next unless handler.respond_to?(:call)
93
- handler.call(message)
86
+ handler.call(conn)
94
87
  end
95
88
  end
96
89
 
97
90
  if message.handler.respond_to?(:call)
98
91
  message.call
99
92
  elsif self.class.default_action.respond_to?(:call)
100
- self.class.default_action.call(message)
93
+ self.class.default_action.call(conn)
101
94
  end
102
95
  end
103
96
  end
@@ -0,0 +1,37 @@
1
+ require_relative "./wire"
2
+ require "json"
3
+
4
+ TeBot::Wire.class_eval do
5
+ sender :text do |conn, chat_id, message|
6
+ conn.make_request("sendMessage", body: {chat_id: chat_id, text: message}.to_json)
7
+ end
8
+
9
+ # this is using MarkdownV2 https://core.telegram.org/bots/api#markdownv2-style
10
+ sender :markdown do |conn, chat_id, message|
11
+ conn.make_request("sendMessage", body: {chat_id: chat_id, text: message, parse_mode: "MarkdownV2"}.to_json)
12
+ end
13
+
14
+ sender :photo do |conn, chat_id, message|
15
+ conn.make_request("sendPhoto", body: message.merge({chat_id: chat_id}).to_json)
16
+ end
17
+
18
+ sender :audio do |conn, chat_id, message|
19
+ conn.make_request("sendAudio", body: message.merge({chat_id: chat_id}).to_json)
20
+ end
21
+
22
+ sender :document do |conn, chat_id, message|
23
+ conn.make_request("sendDocument", body: message.merge({chat_id: chat_id}).to_json)
24
+ end
25
+
26
+ sender :video do |conn, chat_id, message|
27
+ conn.make_request("sendVideo", body: message.merge({chat_id: chat_id}).to_json)
28
+ end
29
+
30
+ sender :animation do |conn, chat_id, message|
31
+ conn.make_request("sendAnimation", body: message.merge({chat_id: chat_id}).to_json)
32
+ end
33
+
34
+ sender :voice do |conn, chat_id, message|
35
+ conn.make_request("sendVoice", body: message.merge({chat_id: chat_id}).to_json)
36
+ end
37
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TeBot
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/te_bot/wire.rb CHANGED
@@ -5,24 +5,47 @@ require "faraday/net_http"
5
5
 
6
6
  module TeBot
7
7
  class Wire
8
+ class << self
9
+ def sender(message_format, handler = nil, &block)
10
+ @senders ||= {}
11
+ @senders[message_format] = (block || handler)
12
+ end
13
+
14
+ def senders
15
+ @senders || {}
16
+ end
17
+ end
18
+
8
19
  CONN = Faraday.new(
9
20
  url: "https://api.telegram.org/",
10
21
  headers: {"Content-Type" => "application/json"}
11
22
  )
12
23
 
13
- def url(path)
14
- "/bot#{@access_token}/#{path}"
15
- end
16
-
17
24
  def initialize(access_token)
18
25
  @access_token = access_token
19
26
  end
20
27
 
21
- def send_message(chat_id, message)
22
- CONN.post(url("sendMessage")) do |req|
23
- req.params["chat_id"] = chat_id
24
- req.params["text"] = message
28
+ def make_request(path, params: nil, headers: nil, body: nil)
29
+ CONN.post(url(path)) do |req|
30
+ req.params.merge!(params) if params
31
+ req.headers.merge!(headers) if headers
32
+ req.body = body if body
25
33
  end
26
34
  end
35
+
36
+ def url(path)
37
+ "/bot#{@access_token}/#{path}"
38
+ end
39
+
40
+ def send_message(chat_id, **payload)
41
+ message_format, message = payload.first
42
+ handler = self.class.senders[message_format]
43
+
44
+ raise ArgumentError, "Message type invalid. sender :#{message_format} not defined" if handler.nil?
45
+
46
+ return handler.call(self, chat_id, message) if handler.respond_to?(:call)
47
+
48
+ public_send(handler, chat_id, message)
49
+ end
27
50
  end
28
51
  end
data/lib/te_bot.rb CHANGED
@@ -6,6 +6,7 @@ module TeBot
6
6
  autoload :Court, "te_bot/court.rb"
7
7
  autoload :Wire, "te_bot/wire.rb"
8
8
  autoload :Message, "te_bot/message.rb"
9
+ autoload :Cable, "te_bot/cable.rb"
9
10
 
10
11
  class Error < StandardError; end
11
12
  # Your code goes here...
data/te_bot.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
15
15
 
16
16
  spec.metadata["homepage_uri"] = spec.homepage
17
17
  spec.metadata["source_code_uri"] = "https://github.com/aaripurna/te_bot"
18
- spec.metadata["changelog_uri"] = "https://github.com/aaripurna/te_bot/blob/main/CHANGELOG.md)"
18
+ spec.metadata["changelog_uri"] = "https://github.com/aaripurna/te_bot/blob/main/CHANGELOG.md"
19
19
 
20
20
  # Specify which files should be added to the gem when it is released.
21
21
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -28,12 +28,6 @@ Gem::Specification.new do |spec|
28
28
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ["lib"]
30
30
 
31
- # Uncomment to register a new dependency of your gem
32
- # spec.add_dependency "example-gem", "~> 1.0"
33
-
34
31
  spec.add_dependency "rack", "~> 2.2"
35
32
  spec.add_dependency "faraday", "~> 2.3"
36
-
37
- # For more information and examples about making a new gem, check out our
38
- # guide at: https://bundler.io/guides/creating_gem.html
39
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: te_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nawa Aripurna
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-26 00:00:00.000000000 Z
11
+ date: 2022-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -53,8 +53,10 @@ files:
53
53
  - README.md
54
54
  - Rakefile
55
55
  - lib/te_bot.rb
56
+ - lib/te_bot/cable.rb
56
57
  - lib/te_bot/court.rb
57
58
  - lib/te_bot/message.rb
59
+ - lib/te_bot/sender_options.rb
58
60
  - lib/te_bot/version.rb
59
61
  - lib/te_bot/wire.rb
60
62
  - sig/te_bot.rbs
@@ -64,7 +66,7 @@ licenses: []
64
66
  metadata:
65
67
  homepage_uri: https://github.com/aaripurna/te_bot
66
68
  source_code_uri: https://github.com/aaripurna/te_bot
67
- changelog_uri: https://github.com/aaripurna/te_bot/blob/main/CHANGELOG.md)
69
+ changelog_uri: https://github.com/aaripurna/te_bot/blob/main/CHANGELOG.md
68
70
  post_install_message:
69
71
  rdoc_options: []
70
72
  require_paths: