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 +4 -4
- data/Gemfile.lock +2 -1
- data/README.md +59 -29
- data/lib/te_bot/cable.rb +22 -0
- data/lib/te_bot/court.rb +7 -14
- data/lib/te_bot/sender_options.rb +37 -0
- data/lib/te_bot/version.rb +1 -1
- data/lib/te_bot/wire.rb +31 -8
- data/lib/te_bot.rb +1 -0
- data/te_bot.gemspec +1 -7
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84afe807cfff02952abed21f9ad1e9cd4c4a337c2fc9d789960fe68de2e37b6c
|
4
|
+
data.tar.gz: 6b0616f98f5fca8cfe3583e97f59a5ce4149adaadfd2bb130f88a9f9449f436b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1fe827e9835f85e930776fd4cb35964f20c3565d99ab2d2bb893cee9e0d61ab713858b3e218ef9157380d9e3af12b8f1c41ab511f559f36e0bd9f5f90392254d
|
7
|
+
data.tar.gz: 2cfbf9af5f37a95b1581cc2d44b883ecc8c49ffc1e639f693d53564115bbf705c315ad20ee5dbe9c23914621d40f8f06b89945a06987af5605c275c068c01b03
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,21 +1,24 @@
|
|
1
1
|
# ::TeBot
|
2
2
|
|
3
|
-
|
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
|
-
|
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
|
13
|
+
gem 'te_bot', '~> 0.2.0'
|
14
|
+
|
12
15
|
Then run
|
13
16
|
|
14
|
-
|
17
|
+
bundle install
|
15
18
|
|
16
19
|
If bundler is not being used to manage dependencies, install the gem by executing:
|
17
20
|
|
18
|
-
|
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
|
-
|
34
|
+
access_token ENV["YOUR_BOT_ACCESS_TOKEN"]
|
31
35
|
|
32
|
-
|
33
|
-
|
34
|
-
|
36
|
+
command("/start") do |conn|
|
37
|
+
conn.reply text: "Welcome aboard my friend!"
|
38
|
+
end
|
35
39
|
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
70
|
-
|
71
|
-
|
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
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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.
|
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
|
-
|
94
|
-
|
95
|
-
|
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
|
-
|
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
|
|
data/lib/te_bot/cable.rb
ADDED
@@ -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(
|
75
|
+
handler.call(conn)
|
83
76
|
elsif self.class.default_command.respond_to?(:call)
|
84
|
-
self.class.default_command.call(
|
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(
|
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(
|
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
|
data/lib/te_bot/version.rb
CHANGED
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
|
22
|
-
CONN.post(url(
|
23
|
-
req.params
|
24
|
-
req.
|
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
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.
|
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-
|
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:
|