telegram_bot_ruby 0.1.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 +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +87 -0
- data/Rakefile +1 -0
- data/lib/telegram_bot/audio.rb +10 -0
- data/lib/telegram_bot/auto_from_methods.rb +67 -0
- data/lib/telegram_bot/blank_slate.rb +11 -0
- data/lib/telegram_bot/chat.rb +20 -0
- data/lib/telegram_bot/contact.rb +13 -0
- data/lib/telegram_bot/date.rb +32 -0
- data/lib/telegram_bot/document.rb +16 -0
- data/lib/telegram_bot/force_reply.rb +5 -0
- data/lib/telegram_bot/group_chat.rb +3 -0
- data/lib/telegram_bot/handler.rb +72 -0
- data/lib/telegram_bot/location.rb +12 -0
- data/lib/telegram_bot/matcher.rb +75 -0
- data/lib/telegram_bot/message.rb +95 -0
- data/lib/telegram_bot/objects.rb +14 -0
- data/lib/telegram_bot/photo_size.rb +10 -0
- data/lib/telegram_bot/poll_listener.rb +29 -0
- data/lib/telegram_bot/reply_keyboard_hide.rb +5 -0
- data/lib/telegram_bot/reply_keyboard_markup.rb +7 -0
- data/lib/telegram_bot/request.rb +36 -0
- data/lib/telegram_bot/request_methods.rb +107 -0
- data/lib/telegram_bot/sticker.rb +17 -0
- data/lib/telegram_bot/update.rb +16 -0
- data/lib/telegram_bot/user.rb +4 -0
- data/lib/telegram_bot/version.rb +3 -0
- data/lib/telegram_bot/video.rb +25 -0
- data/lib/telegram_bot.rb +57 -0
- data/telegram_bot_ruby.gemspec +29 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2c01b6b954e0b513b8a0e29ef88b0f1554c9a50a
|
4
|
+
data.tar.gz: 0b0186efea939835e34f71aa34481e723a631218
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 45c73516b817ccb7d12d38fd7220221a31ddabf27d3398869adcd85ce47265a633e4e3b5a7718acc27ee595cc3588510a92d882595f3b17603c6839887957830
|
7
|
+
data.tar.gz: 0d82339b0ae3fde83a6d209416862c1bbeef5dd218bcda50ec26213b885e433a7f0b07b6081b124a9dd54cd63caf795f4778d9f581950b72f8eccd87d264cf27
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Shou Ya
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# TelegramBotRuby
|
2
|
+
|
3
|
+
**This project is not finished yet**
|
4
|
+
|
5
|
+
|
6
|
+
utilizing telegram bots api in ruby
|
7
|
+
([telegram api doc](https://core.telegram.org/bots/api))
|
8
|
+
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'telegram_bot_ruby'
|
16
|
+
```
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
```bash
|
21
|
+
$ bundle
|
22
|
+
```
|
23
|
+
|
24
|
+
Or install it yourself as:
|
25
|
+
|
26
|
+
```bash
|
27
|
+
$ gem install telegram_bot_ruby
|
28
|
+
```
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
### Set up client
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
require 'telegram_bot_ruby'
|
36
|
+
|
37
|
+
bot = TelegramBot.new(token: <token>)
|
38
|
+
bot.listen(method: :webhook, url: '/meow/meow')
|
39
|
+
# or
|
40
|
+
bot.listen(method: :poll, interval: 5)
|
41
|
+
```
|
42
|
+
|
43
|
+
### Set up update listeners
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
bot.on_command 'ping' do # /ping
|
47
|
+
reply 'pong'
|
48
|
+
end
|
49
|
+
|
50
|
+
bot.on_command 'plus' do |num1, num2| # /plus 1 2
|
51
|
+
reply (num1.to_i + num2.to_i).to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
bot.on_text 'ping' do # plain 'ping'
|
55
|
+
send_message 'pong'
|
56
|
+
end
|
57
|
+
|
58
|
+
# with block: false, message will keep passing through other listeners
|
59
|
+
bot.on_text /(\d+)\+(\d+)\=\?/, block: false do
|
60
|
+
send_chat_action :typing
|
61
|
+
send_message ($1.to_i + $2.to_i).to_s
|
62
|
+
forward_message 2333
|
63
|
+
send_chat_action :upload_photo
|
64
|
+
send_photo <IO obj implements read>
|
65
|
+
end
|
66
|
+
|
67
|
+
# a simple history logger
|
68
|
+
bot.anything do |msg|
|
69
|
+
Database.save [msg.from.username, msg.text] if !msg.text.empty?
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
### Start && Stop
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
# register service at telegram or start long polling
|
77
|
+
bot.start!
|
78
|
+
```
|
79
|
+
|
80
|
+
## Contributing
|
81
|
+
|
82
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/shouya/telegram-bot.
|
83
|
+
|
84
|
+
|
85
|
+
## License
|
86
|
+
|
87
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,67 @@
|
|
1
|
+
class TelegramBot
|
2
|
+
module AutoFromMethods
|
3
|
+
module ClassMethods
|
4
|
+
def from(id)
|
5
|
+
case id
|
6
|
+
when self
|
7
|
+
id
|
8
|
+
when nil
|
9
|
+
nil
|
10
|
+
when Hash
|
11
|
+
parse(id)
|
12
|
+
when Integer
|
13
|
+
new(id)
|
14
|
+
when others
|
15
|
+
warn "unknown stuff passed in [#{id}]"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def extra_types
|
20
|
+
{}
|
21
|
+
end
|
22
|
+
|
23
|
+
def hash_key_aliases
|
24
|
+
{}
|
25
|
+
end
|
26
|
+
|
27
|
+
def parse(hsh)
|
28
|
+
obj = new(*parse_attrs(hsh))
|
29
|
+
parse_extra_types
|
30
|
+
obj
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def parse_attrs(hsh)
|
36
|
+
aliases = hash_key_aliases
|
37
|
+
members.map do |attr|
|
38
|
+
if aliases.include? attr
|
39
|
+
hash_attr = aliases[attr]
|
40
|
+
else
|
41
|
+
hash_attr = attr
|
42
|
+
end
|
43
|
+
hsh[attr] || hsh[hash_attr.to_s]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def parse_extra_types
|
48
|
+
extra_types.each do |attr, typ|
|
49
|
+
case typ
|
50
|
+
when Class
|
51
|
+
obj[attr] = typ.from(obj[attr])
|
52
|
+
when Array
|
53
|
+
obj[attr] = obj[attr].map { |x| typ[0].from(x) }
|
54
|
+
else
|
55
|
+
warn 'unknown type #{type}'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.included(clazz)
|
63
|
+
clazz.extend ClassMethods
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Chat < Struct.new(:id)
|
2
|
+
def self.from(id)
|
3
|
+
case id
|
4
|
+
when Integer
|
5
|
+
Chat.new(id)
|
6
|
+
when GroupChat, User
|
7
|
+
id
|
8
|
+
when Hash
|
9
|
+
if id.has_key? 'title'
|
10
|
+
GroupChat.from(id)
|
11
|
+
elsif id.has_key? 'first_name'
|
12
|
+
User.from(id)
|
13
|
+
else
|
14
|
+
Chat.from(id['id'])
|
15
|
+
end
|
16
|
+
else
|
17
|
+
warn 'unknown chat'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'datetime'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
class TelegramBot::Date < Struct.new()
|
5
|
+
include AutoFromMethods
|
6
|
+
|
7
|
+
def self.from(date)
|
8
|
+
case date
|
9
|
+
when ::DateTime, ::Date, ::Time
|
10
|
+
new(date)
|
11
|
+
when Integer
|
12
|
+
new(Time.at(date).to_datetime)
|
13
|
+
when String
|
14
|
+
new(Datetime.parse(date))
|
15
|
+
when TelegramBot::Date
|
16
|
+
date
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
attr_accessor :datetime
|
24
|
+
|
25
|
+
def initialize(datetime)
|
26
|
+
@self.datetime = datetime
|
27
|
+
end
|
28
|
+
|
29
|
+
def method_missing(sym, *args, &blk)
|
30
|
+
@datetime.send(sym, *args, &blk)
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class TelegramBot::Document <
|
2
|
+
Struct.new(:id, :thumb, :file_name, :meme_type, :file_size)
|
3
|
+
include AutoFromMethods
|
4
|
+
|
5
|
+
def self.hash_key_aliases
|
6
|
+
{
|
7
|
+
:id => :file_id
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.extra_types
|
12
|
+
{
|
13
|
+
thumb: PhotoSize
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'active_support/inflector'
|
3
|
+
|
4
|
+
require_relative 'matcher'
|
5
|
+
require_relative 'blank_slate'
|
6
|
+
|
7
|
+
module TelegramBot
|
8
|
+
module EventHandler
|
9
|
+
class Handler
|
10
|
+
attr_accessor :type, :action, :pass
|
11
|
+
|
12
|
+
def initialize(matcher, action, pass)
|
13
|
+
@matcher = matcher
|
14
|
+
@action = action
|
15
|
+
@pass = pass
|
16
|
+
end
|
17
|
+
|
18
|
+
def pass?
|
19
|
+
@pass
|
20
|
+
end
|
21
|
+
|
22
|
+
def ===(msg)
|
23
|
+
@matcher === msg
|
24
|
+
end
|
25
|
+
|
26
|
+
def arguments(msg)
|
27
|
+
@matcher.arguments(msg)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def self.included(clazz)
|
33
|
+
clazz.send :prepend, Class.new do
|
34
|
+
attr_accessor :handlers
|
35
|
+
|
36
|
+
def initialize(*args, &block)
|
37
|
+
@handlers = []
|
38
|
+
super(*args, &block)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def on(type, *args, pass: false, &block)
|
45
|
+
matcher_class = "#{type}_matcher".classify
|
46
|
+
matcher = matcher_class.new(*args)
|
47
|
+
handler = Handler.new(matcher, block, pass)
|
48
|
+
@handlers << handler
|
49
|
+
end
|
50
|
+
|
51
|
+
def handle(msg)
|
52
|
+
env = BlankSlate.new
|
53
|
+
self.extend_env(env)
|
54
|
+
msg.extend_env(env)
|
55
|
+
|
56
|
+
@handlers.each do |hndlr|
|
57
|
+
next unless hndlr === msg
|
58
|
+
|
59
|
+
hndlr.matcher.extend_env(env, msg)
|
60
|
+
|
61
|
+
env.extend do
|
62
|
+
define_method :handler do
|
63
|
+
hndlr
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
env.call(handler.arguments(msg),
|
68
|
+
&handler.action)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module TelegramBot
|
2
|
+
class Matcher
|
3
|
+
def env(msg)
|
4
|
+
msg.extend(BasicObject.new)
|
5
|
+
end
|
6
|
+
|
7
|
+
def ===(_)
|
8
|
+
false
|
9
|
+
end
|
10
|
+
|
11
|
+
def arguments(msg)
|
12
|
+
[]
|
13
|
+
end
|
14
|
+
|
15
|
+
def extend_env(obj, msg)
|
16
|
+
obj
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class TextMatcher < Matcher
|
21
|
+
attr_accessor :pattern
|
22
|
+
|
23
|
+
def initialize(pat = nil)
|
24
|
+
@pattern = pat
|
25
|
+
end
|
26
|
+
|
27
|
+
def ===(msg)
|
28
|
+
return false unless msg.type == :text
|
29
|
+
return true if @pattern.nil?
|
30
|
+
@pattern === msg.text
|
31
|
+
end
|
32
|
+
|
33
|
+
def extend_env(obj, msg)
|
34
|
+
obj = super
|
35
|
+
|
36
|
+
if Regexp === @pattern
|
37
|
+
md = @pattern.match(msg.text)
|
38
|
+
obj.extend do
|
39
|
+
md.names.each do |grp|
|
40
|
+
value = md[grp]
|
41
|
+
define_method grp { value }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
obj
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class CommandMatcher < Matcher
|
51
|
+
attr_accessor :command
|
52
|
+
|
53
|
+
def initialize(command)
|
54
|
+
@command = command
|
55
|
+
end
|
56
|
+
|
57
|
+
def ===(msg)
|
58
|
+
msg.type == :text and msg.text.start_with?("/#{@command}")
|
59
|
+
end
|
60
|
+
|
61
|
+
def arguments(msg)
|
62
|
+
msg.text.split[1..-1]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class AnythingMatcher < Matcher
|
67
|
+
def ===(_)
|
68
|
+
true
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class FallbackMatcher < AnythingMatcher
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
class TelegramBot::Message <
|
2
|
+
Struct(:id,
|
3
|
+
:from,
|
4
|
+
:date,
|
5
|
+
:chat,
|
6
|
+
:forward_from,
|
7
|
+
:forward_date,
|
8
|
+
:reply_to_message,
|
9
|
+
:text,
|
10
|
+
:audio,
|
11
|
+
:document,
|
12
|
+
:photo,
|
13
|
+
:sticker,
|
14
|
+
:video,
|
15
|
+
:contact,
|
16
|
+
:location,
|
17
|
+
:new_chat_participant,
|
18
|
+
:left_chat_participant,
|
19
|
+
:new_chat_title,
|
20
|
+
:new_chat_photo,
|
21
|
+
:delete_chat_photo,
|
22
|
+
:group_chat_created)
|
23
|
+
|
24
|
+
include AutoFromMethods
|
25
|
+
|
26
|
+
def self.hash_key_aliases
|
27
|
+
{
|
28
|
+
:id => :message_id,
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.extra_types
|
33
|
+
{
|
34
|
+
from: User,
|
35
|
+
chat: Chat,
|
36
|
+
forward_from: User,
|
37
|
+
forward_date: Date,
|
38
|
+
reply_to_message: Message,
|
39
|
+
text: String,
|
40
|
+
audio: Audio,
|
41
|
+
document: Document,
|
42
|
+
photo: [PhotoSize],
|
43
|
+
sticker: Sticker,
|
44
|
+
video: Video,
|
45
|
+
contact: Contact,
|
46
|
+
location: Location,
|
47
|
+
new_chat_participant: User,
|
48
|
+
left_chat_participant: User
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def type
|
53
|
+
case
|
54
|
+
when text then :text
|
55
|
+
when photo then :photo
|
56
|
+
when audio then :audio
|
57
|
+
when document then :document
|
58
|
+
when sticker then :sticker
|
59
|
+
when video then :video
|
60
|
+
when contact then :contact
|
61
|
+
when location then :location
|
62
|
+
when new_chat_participant then :member_entered
|
63
|
+
when left_chat_participant then :member_left
|
64
|
+
when new_chat_title then :chat_title_updatd
|
65
|
+
when new_chat_photo then :chat_photo_updated
|
66
|
+
when delete_chat_photo then :chat_photo_deleted
|
67
|
+
when group_chat_created then :group_chat_created
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def is_forward?
|
72
|
+
!!forward_from
|
73
|
+
end
|
74
|
+
|
75
|
+
def is_reply?
|
76
|
+
!!reply_to_message
|
77
|
+
end
|
78
|
+
|
79
|
+
def extend_env(obj)
|
80
|
+
msg = self
|
81
|
+
obj.instace_eval do
|
82
|
+
@message = msg
|
83
|
+
end
|
84
|
+
|
85
|
+
members = self.members
|
86
|
+
|
87
|
+
obj.extend do
|
88
|
+
attr_reader :message
|
89
|
+
def_delegators :@message, *members
|
90
|
+
def_delegators :@message, :is_forward?, :is_reply?
|
91
|
+
end
|
92
|
+
|
93
|
+
obj
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative 'auto_from_methods'
|
2
|
+
|
3
|
+
require_relative 'user'
|
4
|
+
require_relative 'chat'
|
5
|
+
require_relative 'group_chat'
|
6
|
+
require_relative 'message'
|
7
|
+
require_relative 'photo_size'
|
8
|
+
require_relative 'audio'
|
9
|
+
require_relative 'document'
|
10
|
+
require_relative 'video'
|
11
|
+
require_relative 'contact'
|
12
|
+
require_relative 'location'
|
13
|
+
require_relative 'update'
|
14
|
+
require_relative 'date'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module TelegramBot
|
2
|
+
class PollListener
|
3
|
+
def initialize(client, interval)
|
4
|
+
@client = client
|
5
|
+
@interval = interval
|
6
|
+
@offset_id = nil
|
7
|
+
end
|
8
|
+
|
9
|
+
def message_received(msg)
|
10
|
+
@client.append_history(msg)
|
11
|
+
@client.handle(msg)
|
12
|
+
end
|
13
|
+
|
14
|
+
def start!
|
15
|
+
loop do
|
16
|
+
get_updates
|
17
|
+
sleep @interval
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_updates
|
22
|
+
updates = @client.get_updates(@offset_id, 50)
|
23
|
+
updates.each do |update|
|
24
|
+
@offset_id = update.id
|
25
|
+
message_received(update.message)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
require 'json'
|
3
|
+
require 'active_support/inflector'
|
4
|
+
|
5
|
+
module TelegramBot
|
6
|
+
module Request
|
7
|
+
class PrependMethods
|
8
|
+
attr_accessor :token
|
9
|
+
|
10
|
+
def initialize(*args, token:, &block)
|
11
|
+
@token = token
|
12
|
+
super(*args, &block)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
API_BASE = 'https://api.telegram.org/bot'
|
17
|
+
|
18
|
+
def self.included(clazz)
|
19
|
+
clazz.prepend PrependMethods
|
20
|
+
end
|
21
|
+
|
22
|
+
def request(method, params)
|
23
|
+
url = construct_url(method)
|
24
|
+
resp = RestClient.post(url, params)
|
25
|
+
return JONS.parse(resp.body) if resp.code.to_s =~ /^2\d\d$/
|
26
|
+
raise Exception.new(resp)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def construct_url(method)
|
32
|
+
method_camelized = method.to_s.camelize(:lower)
|
33
|
+
"#{API_BASE}#{@token}/#{method_camelized}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module TelegramBot
|
2
|
+
module RequestMethods
|
3
|
+
def get_updates(offset: nil, limit: nil, timeout: nil)
|
4
|
+
params = {
|
5
|
+
offset: offset,
|
6
|
+
limit: limit,
|
7
|
+
timouet: timeout
|
8
|
+
}.reject {|_,v| v.nil?}
|
9
|
+
|
10
|
+
request(:get_update, params).map do |update|
|
11
|
+
Update.from(update)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_me
|
16
|
+
User.from(request(:get_me, {}))
|
17
|
+
end
|
18
|
+
|
19
|
+
def send_message(chat, text,
|
20
|
+
disable_web_page_preview: nil,
|
21
|
+
reply_to: nil,
|
22
|
+
reply_markup: nil)
|
23
|
+
params = {
|
24
|
+
chat_id: Chat.from(chat).id,
|
25
|
+
text: text,
|
26
|
+
disable_web_page_preview: disable_web_page_preview,
|
27
|
+
reply_to_message_id: Chat.from(reply_to).id
|
28
|
+
# TODO:
|
29
|
+
# reply_markup: reply_markup
|
30
|
+
}.reject {|_,v| v.nil?}
|
31
|
+
|
32
|
+
Message.from(request(:send_message, params))
|
33
|
+
end
|
34
|
+
|
35
|
+
def forward_message(msg, to, from = nil)
|
36
|
+
from_chat = from.nil? ? msg.chat : Chat.from(from)
|
37
|
+
|
38
|
+
params = {
|
39
|
+
chat_id: Chat.from(chat).id,
|
40
|
+
from_chat_id: from_chat.id,
|
41
|
+
message_id: Message.from(msg).id
|
42
|
+
}
|
43
|
+
|
44
|
+
Message.from(request(:forward_message, params))
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
CHAT_ACTIONS = [
|
49
|
+
:typing,
|
50
|
+
:upload_photo,
|
51
|
+
:record_video,
|
52
|
+
:update_video,
|
53
|
+
:record_audio,
|
54
|
+
:upload_audio,
|
55
|
+
:upload_document,
|
56
|
+
:find_location
|
57
|
+
]
|
58
|
+
|
59
|
+
def send_chat_action(chat, action)
|
60
|
+
unless CHAT_ACTIONS.include?(action.intern)
|
61
|
+
warn "invalid chat action #{action}, available actions are" +
|
62
|
+
" #{CHAT_ACTIONS.join(', ')}."
|
63
|
+
action = CHAT_ACTIONS.first
|
64
|
+
end
|
65
|
+
|
66
|
+
params = {
|
67
|
+
chat_id: Chat.from(chat).id,
|
68
|
+
action: action.to_s
|
69
|
+
}
|
70
|
+
|
71
|
+
request(:send_chat_action, params)
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
75
|
+
METHODS = [
|
76
|
+
:get_me,
|
77
|
+
:send_message,
|
78
|
+
:forward_message,
|
79
|
+
:send_photo,
|
80
|
+
:send_document,
|
81
|
+
:send_sticker,
|
82
|
+
:send_video,
|
83
|
+
:send_location,
|
84
|
+
:send_chat_action,
|
85
|
+
:get_user_profile_photos,
|
86
|
+
:get_updates,
|
87
|
+
:set_webhook
|
88
|
+
]
|
89
|
+
|
90
|
+
METHODS.each do |method|
|
91
|
+
is_defined = self.instance_methods(false).include?(method)
|
92
|
+
unless is_defined
|
93
|
+
alias_method method, :todo
|
94
|
+
end
|
95
|
+
|
96
|
+
alias_method "#{method}_raw", method
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def todo(*args, &block)
|
103
|
+
defn_at = self.method(__callee__).source_location
|
104
|
+
warn "#{defn_at[0]}:<#{__callee__}>: not implemented"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class TelegramBot::Video <
|
2
|
+
Struct.new(:id,
|
3
|
+
:width,
|
4
|
+
:height,
|
5
|
+
:duration,
|
6
|
+
:thumb,
|
7
|
+
:mime_type,
|
8
|
+
:file_size,
|
9
|
+
:caption)
|
10
|
+
|
11
|
+
include AutoFromMethods
|
12
|
+
|
13
|
+
def self.hash_key_aliases
|
14
|
+
{
|
15
|
+
:id => :file_id
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.extra_types
|
20
|
+
{
|
21
|
+
thumb: PhotoSize
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/lib/telegram_bot.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'telegram_bot/version'
|
2
|
+
require 'telegram_bot/objects'
|
3
|
+
require 'telegram_bot/handler'
|
4
|
+
require 'telegram_bot/request'
|
5
|
+
require 'telegram_bot/request_methods'
|
6
|
+
require 'telegram_bot/poll_listener'
|
7
|
+
|
8
|
+
class TelegramBot
|
9
|
+
include TelegramBot::EventHandler
|
10
|
+
include TelegramBot::Request
|
11
|
+
include TelegramBot::RequestMethods
|
12
|
+
|
13
|
+
attr_accessor :token, :handlers, :history
|
14
|
+
|
15
|
+
def initialize(history: 50, token:)
|
16
|
+
@token = token
|
17
|
+
@handlers = []
|
18
|
+
@history = []
|
19
|
+
@history_length = 50
|
20
|
+
end
|
21
|
+
|
22
|
+
def listen(method: :poll, interval: 5, path: '/hook')
|
23
|
+
@listen = {
|
24
|
+
method: method,
|
25
|
+
interval: interval,
|
26
|
+
path: path
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def extend_env(env)
|
31
|
+
telegram_bot = self
|
32
|
+
env.extend do
|
33
|
+
define_method :bot do
|
34
|
+
telegram_bot
|
35
|
+
end
|
36
|
+
alias_method :client, :bot
|
37
|
+
|
38
|
+
define_method :history do
|
39
|
+
telegram_bot.history
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def append_history(message)
|
45
|
+
@history << message
|
46
|
+
@history = @history.last(@history_length || 0)
|
47
|
+
end
|
48
|
+
|
49
|
+
def start!
|
50
|
+
case @listen[:method]
|
51
|
+
when :poll
|
52
|
+
PollListener.new(self, @listen[:interval])
|
53
|
+
when :webhook
|
54
|
+
warn 'not implemented'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'telegram_bot/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "telegram_bot_ruby"
|
8
|
+
spec.version = TelegramBot::VERSION
|
9
|
+
spec.authors = ["Shou Ya"]
|
10
|
+
spec.email = ["shouyatf@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{This is a bot framework that utilizes telegram's bots api}
|
13
|
+
spec.homepage = "https://github.com/shouya/telegram-bot"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
17
|
+
# delete this section to allow pushing this gem to any host.
|
18
|
+
|
19
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_dependency 'rest-client'
|
25
|
+
spec.add_dependency 'active_support'
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
28
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: telegram_bot_ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Shou Ya
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: active_support
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.10'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.10'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- shouyatf@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".travis.yml"
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- lib/telegram_bot.rb
|
83
|
+
- lib/telegram_bot/audio.rb
|
84
|
+
- lib/telegram_bot/auto_from_methods.rb
|
85
|
+
- lib/telegram_bot/blank_slate.rb
|
86
|
+
- lib/telegram_bot/chat.rb
|
87
|
+
- lib/telegram_bot/contact.rb
|
88
|
+
- lib/telegram_bot/date.rb
|
89
|
+
- lib/telegram_bot/document.rb
|
90
|
+
- lib/telegram_bot/force_reply.rb
|
91
|
+
- lib/telegram_bot/group_chat.rb
|
92
|
+
- lib/telegram_bot/handler.rb
|
93
|
+
- lib/telegram_bot/location.rb
|
94
|
+
- lib/telegram_bot/matcher.rb
|
95
|
+
- lib/telegram_bot/message.rb
|
96
|
+
- lib/telegram_bot/objects.rb
|
97
|
+
- lib/telegram_bot/photo_size.rb
|
98
|
+
- lib/telegram_bot/poll_listener.rb
|
99
|
+
- lib/telegram_bot/reply_keyboard_hide.rb
|
100
|
+
- lib/telegram_bot/reply_keyboard_markup.rb
|
101
|
+
- lib/telegram_bot/request.rb
|
102
|
+
- lib/telegram_bot/request_methods.rb
|
103
|
+
- lib/telegram_bot/sticker.rb
|
104
|
+
- lib/telegram_bot/update.rb
|
105
|
+
- lib/telegram_bot/user.rb
|
106
|
+
- lib/telegram_bot/version.rb
|
107
|
+
- lib/telegram_bot/video.rb
|
108
|
+
- telegram_bot_ruby.gemspec
|
109
|
+
homepage: https://github.com/shouya/telegram-bot
|
110
|
+
licenses:
|
111
|
+
- MIT
|
112
|
+
metadata: {}
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
require_paths:
|
116
|
+
- lib
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
requirements: []
|
128
|
+
rubyforge_project:
|
129
|
+
rubygems_version: 2.4.6
|
130
|
+
signing_key:
|
131
|
+
specification_version: 4
|
132
|
+
summary: This is a bot framework that utilizes telegram's bots api
|
133
|
+
test_files: []
|