te_bot 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: