telegram_meetup_bot 0.0.1
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 +14 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +50 -0
- data/Rakefile +2 -0
- data/bin/telegram_meetup_bot +18 -0
- data/config_samples/config.yml +4 -0
- data/config_samples/responses.yml +20 -0
- data/lib/telegram_meetup_bot/calendar.rb +58 -0
- data/lib/telegram_meetup_bot/client.rb +24 -0
- data/lib/telegram_meetup_bot/commands_handler.rb +108 -0
- data/lib/telegram_meetup_bot/initializers/base.rb +37 -0
- data/lib/telegram_meetup_bot/initializers/config_loader.rb +34 -0
- data/lib/telegram_meetup_bot/initializers/responses_loader.rb +13 -0
- data/lib/telegram_meetup_bot/initializers.rb +5 -0
- data/lib/telegram_meetup_bot/message_parser.rb +31 -0
- data/lib/telegram_meetup_bot/messenger.rb +14 -0
- data/lib/telegram_meetup_bot/params_parser.rb +29 -0
- data/lib/telegram_meetup_bot/storage.rb +19 -0
- data/lib/telegram_meetup_bot/version.rb +3 -0
- data/lib/telegram_meetup_bot.rb +21 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/telegram_meetup_bot/calendar_spec.rb +63 -0
- data/spec/telegram_meetup_bot/message_parser_spec.rb +44 -0
- data/spec/telegram_meetup_bot/params_parser_spec.rb +69 -0
- data/telegram_meetup_bot.gemspec +27 -0
- metadata +160 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d0b6bb180e431520c43ac177e3afbc0b705f16cf
|
4
|
+
data.tar.gz: eab2300653e6d119aeecb18573e86955153a80b0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 453de1b09b75f1350be93ea83b4ffcbc5e0908d372826a489c9268f7e97ae673e7b91830f40f80f17a89067a4126b9a157f3d18f77f7c5c6bf438320688389fc
|
7
|
+
data.tar.gz: 700aa76255a6106c6473014bdbf7b7dfdbe35c310bfa4758bcf55b7f4a5846bd6a7d7415d3c9bbb86114346c1de4965ea29482d83d62338af54ce216cc40b5fd
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Timur Yanberdin
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# TelegramMeetupBot
|
2
|
+
|
3
|
+
[](https://travis-ci.org/mendab1e/telegram_meetup_bot)
|
4
|
+
|
5
|
+
Telegram bot for meetups organisation. It suits really well for small communities, where people want to attend a place together, but not on regular basis.
|
6
|
+
|
7
|
+

|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Install redis: http://redis.io/
|
12
|
+
|
13
|
+
Install the gem:
|
14
|
+
|
15
|
+
$ gem install telegram_meetup_bot
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
Register your bot and [obtain a token](https://core.telegram.org/bots#botfather)
|
20
|
+
|
21
|
+
Run redis server:
|
22
|
+
|
23
|
+
$ redis-server
|
24
|
+
|
25
|
+
Generate sample configurations:
|
26
|
+
|
27
|
+
$ telegram_meetup_bot --generate
|
28
|
+
|
29
|
+
You should specify your bot_token in ```~/.telegram_meetup_bot/config.yml```.
|
30
|
+
```
|
31
|
+
bot_token: 'insert your token here'
|
32
|
+
redis_host: 'localhost'
|
33
|
+
redis_port: '6379'
|
34
|
+
redis_key: 'meetup_bot'
|
35
|
+
```
|
36
|
+
If you use more than one bot per redis server, use different redis_keys for each of them.
|
37
|
+
|
38
|
+
Also you could change sample responses in ```~/.telegram_meetup_bot/responses.yml```. It uses templates ```%first_name%``` and ```%date%``` to display actual name and date in messages.
|
39
|
+
|
40
|
+
Run your bot:
|
41
|
+
|
42
|
+
$ telegram_meetup_bot
|
43
|
+
|
44
|
+
## Contributing
|
45
|
+
|
46
|
+
1. Fork it ( https://github.com/[my-github-username]/telegram_meetup_bot/fork )
|
47
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
48
|
+
3. Commit your changes (`git commit -am 'add some feature'`)
|
49
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
50
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'telegram_meetup_bot'
|
5
|
+
|
6
|
+
config_path = File.join(ENV['HOME'], '.telegram_meetup_bot')
|
7
|
+
|
8
|
+
if ARGV.first == '--generate'
|
9
|
+
FileUtils.mkdir(config_path) unless Dir.exist?(config_path)
|
10
|
+
samples_dir = File.expand_path('../../config_samples', __FILE__)
|
11
|
+
%w(config.yml responses.yml).each do |sample|
|
12
|
+
file = File.join(samples_dir, sample)
|
13
|
+
FileUtils.cp(file, config_path)
|
14
|
+
puts "#{config_path}/#{sample} generated"
|
15
|
+
end
|
16
|
+
else
|
17
|
+
TelegramMeetupBot.run config_path
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
today: "We are waiting for you today, %first_name%."
|
2
|
+
today_list: "Today visitors:"
|
3
|
+
today_cancel: "We are waiting for you next time, %first_name%."
|
4
|
+
date: "We are waiting for you on %date%, %first_name%."
|
5
|
+
date_list: "%date% visitors:"
|
6
|
+
date_cancel: "We are waiting for you next time, %first_name%."
|
7
|
+
wrong_date_format: "Error: wrong date format. Correct formats are dd, dd.mm or dd.mm.yy."
|
8
|
+
old_date: "This date is too old."
|
9
|
+
nobody: "No one planned to come on %date%."
|
10
|
+
not_subscribed: "You wasn't subscribed on %date%."
|
11
|
+
no_username: "%first_name%, please set a username in the Telegram settings."
|
12
|
+
help: |
|
13
|
+
Hi, %first_name%. Use this commands list:
|
14
|
+
/today 14:00 - add yourself to the today list (time is optional);
|
15
|
+
/today_list - display the today list;
|
16
|
+
/today_cancel - remove yourself from the today list;
|
17
|
+
/date 23 14:00 - add yourself to the list on 23rd of the current month (time is optional);
|
18
|
+
/date_list 23.04 - display the list for April 23 of the current year;
|
19
|
+
/date_cancel 23.04.16 - remove yourself from the list on 23.04.16;
|
20
|
+
There are 3 formats for date available: 14 - day, 14.09 - day and month, 14.09.15 - day, month and year;
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module TelegramMeetupBot
|
2
|
+
class Calendar
|
3
|
+
attr_reader :storage, :user, :date, :time
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@storage = Initializers::ConfigLoader.storage
|
7
|
+
@date = args.fetch(:date)
|
8
|
+
@user = args.fetch(:user)
|
9
|
+
@time = args[:time]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.formated_users_for_date(date)
|
13
|
+
storage = Initializers::ConfigLoader.storage
|
14
|
+
users = storage.get_users_for_date(date)
|
15
|
+
users.map! do |user|
|
16
|
+
username = user[:username] ? " @#{user[:username]}" : ''
|
17
|
+
"#{user[:first_name]}#{username} #{user[:time]}"
|
18
|
+
end
|
19
|
+
users.join("\n")
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_user_to_date
|
23
|
+
process_user do |users, saved_user|
|
24
|
+
return if saved_user == user_hash
|
25
|
+
users.delete(saved_user) if saved_user
|
26
|
+
users << user_hash
|
27
|
+
storage.set_users_to_date(users, date)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def delete_user_from_date
|
32
|
+
process_user do |users, saved_user|
|
33
|
+
if saved_user
|
34
|
+
users.delete(saved_user)
|
35
|
+
storage.set_users_to_date(users, date)
|
36
|
+
true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def process_user(&block)
|
44
|
+
users = storage.get_users_for_date(date)
|
45
|
+
saved_user = users.find { |u| u[:id] == user.id }
|
46
|
+
|
47
|
+
yield users, saved_user
|
48
|
+
end
|
49
|
+
|
50
|
+
def user_hash
|
51
|
+
@user_hash ||= if time
|
52
|
+
user.to_h.merge(time: time)
|
53
|
+
else
|
54
|
+
user.to_h
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module TelegramMeetupBot
|
2
|
+
class Client
|
3
|
+
attr_reader :token
|
4
|
+
|
5
|
+
def initialize(token)
|
6
|
+
@token = token
|
7
|
+
end
|
8
|
+
|
9
|
+
def run
|
10
|
+
begin
|
11
|
+
Telegram::Bot::Client.run(token) do |bot|
|
12
|
+
bot.listen do |message|
|
13
|
+
messenger = Messenger.new(api: bot.api, chat_id: message.chat.id)
|
14
|
+
CommandsHandler.new(message: message, messenger: messenger).process
|
15
|
+
end
|
16
|
+
end
|
17
|
+
rescue Telegram::Bot::Exceptions::ResponseError => e
|
18
|
+
puts e
|
19
|
+
sleep 1
|
20
|
+
run # run again on telegram server error
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module TelegramMeetupBot
|
2
|
+
class CommandsHandler
|
3
|
+
COMMANDS = %w(today today_list today_cancel date date_list date_cancel help)
|
4
|
+
attr_reader :command, :params, :author, :messenger
|
5
|
+
|
6
|
+
def initialize(args)
|
7
|
+
parser = MessageParser.new(args.fetch(:message))
|
8
|
+
@messenger = args.fetch(:messenger)
|
9
|
+
@command = COMMANDS.include?(parser.command) ? parser.command : 'help'
|
10
|
+
@params = parser.params
|
11
|
+
@author = parser.author
|
12
|
+
end
|
13
|
+
|
14
|
+
def process
|
15
|
+
if method(command).arity == 0
|
16
|
+
send command
|
17
|
+
else
|
18
|
+
send command, params
|
19
|
+
end
|
20
|
+
|
21
|
+
no_username_notification unless author.username
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def today(params)
|
27
|
+
time = ParamsParser.new(params.first).parse_time if params.first
|
28
|
+
handle_date(Date.today, time)
|
29
|
+
end
|
30
|
+
|
31
|
+
def date(params)
|
32
|
+
date = ParamsParser.new(params.first).parse_date
|
33
|
+
time = ParamsParser.new(params[1]).parse_time if params[1]
|
34
|
+
handle_date(date, time) if date_is_valid?(date)
|
35
|
+
end
|
36
|
+
|
37
|
+
def handle_date(date, time)
|
38
|
+
Calendar.new(date: date, user: author, time: time).add_user_to_date
|
39
|
+
messenger.send build_response(date: date)
|
40
|
+
end
|
41
|
+
|
42
|
+
def today_list
|
43
|
+
handle_date_list Date.today
|
44
|
+
end
|
45
|
+
|
46
|
+
def date_list(params)
|
47
|
+
date = ParamsParser.new(params.first).parse_date
|
48
|
+
handle_date_list(date) if date_is_valid?(date)
|
49
|
+
end
|
50
|
+
|
51
|
+
def handle_date_list(date)
|
52
|
+
users = Calendar.formated_users_for_date(date)
|
53
|
+
messenger.send list_response(date, users)
|
54
|
+
end
|
55
|
+
|
56
|
+
def today_cancel
|
57
|
+
handle_date_cancel Date.today
|
58
|
+
end
|
59
|
+
|
60
|
+
def date_cancel(params)
|
61
|
+
date = ParamsParser.new(params.first).parse_date
|
62
|
+
handle_date_cancel(date) if date_is_valid?(date)
|
63
|
+
end
|
64
|
+
|
65
|
+
def handle_date_cancel(date)
|
66
|
+
calendar = Calendar.new(date: date, user: author)
|
67
|
+
deleted = calendar.delete_user_from_date
|
68
|
+
args = deleted ? {} : {key: 'not_subscribed', date: date}
|
69
|
+
messenger.send build_response(args)
|
70
|
+
end
|
71
|
+
|
72
|
+
def help
|
73
|
+
messenger.send build_response
|
74
|
+
end
|
75
|
+
|
76
|
+
def no_username_notification
|
77
|
+
messenger.send build_response(key: 'no_username')
|
78
|
+
end
|
79
|
+
|
80
|
+
def date_is_valid?(date)
|
81
|
+
if date.nil?
|
82
|
+
messenger.send build_response(key: 'wrong_date_format')
|
83
|
+
return false
|
84
|
+
elsif date < Date.today
|
85
|
+
messenger.send build_response(key: 'old_date')
|
86
|
+
return false
|
87
|
+
end
|
88
|
+
true
|
89
|
+
end
|
90
|
+
|
91
|
+
def list_response(date, list)
|
92
|
+
if list.empty?
|
93
|
+
build_response(key: 'nobody', date: date)
|
94
|
+
else
|
95
|
+
build_response(date: date) { |response| "#{response}\n#{list}" }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def build_response(args = {})
|
100
|
+
response_key = args.fetch(:key) { command }
|
101
|
+
response = Initializers::ResponsesLoader.responses[response_key].dup
|
102
|
+
response.gsub!('%first_name%', author.first_name)
|
103
|
+
response.gsub!('%date%', args[:date].strftime('%d %h %Y')) if args[:date]
|
104
|
+
|
105
|
+
block_given? ? yield(response) : response
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module TelegramMeetupBot
|
2
|
+
module Initializers
|
3
|
+
class Base
|
4
|
+
private
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def preload(config_path)
|
8
|
+
@configurations ||= begin
|
9
|
+
file = File.join(config_path, self::FILE_NAME)
|
10
|
+
check_if_exist(file)
|
11
|
+
config = YAML.load(File.open(file).read)
|
12
|
+
validate(config.keys, file)
|
13
|
+
config.map { |_,v| v.freeze }
|
14
|
+
config
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def check_if_exist(file)
|
19
|
+
unless File.exist? file
|
20
|
+
puts "Error: file not found #{file}"
|
21
|
+
exit
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate(keys, file)
|
26
|
+
missing_keys = self::AVAILABLE_KEYS - keys
|
27
|
+
|
28
|
+
if missing_keys.any?
|
29
|
+
puts "Error: missing params in #{file}\n#{missing_keys.join(', ')}"
|
30
|
+
exit
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'redis'
|
2
|
+
|
3
|
+
module TelegramMeetupBot
|
4
|
+
module Initializers
|
5
|
+
class ConfigLoader < Base
|
6
|
+
FILE_NAME = 'config.yml'
|
7
|
+
AVAILABLE_KEYS = %w(bot_token redis_key redis_port redis_host)
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def storage
|
11
|
+
@storage ||= Storage.new(redis: redis, redis_key: redis_key)
|
12
|
+
end
|
13
|
+
|
14
|
+
def token
|
15
|
+
@configurations['bot_token']
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def redis_key
|
21
|
+
@configurations['redis_key']
|
22
|
+
end
|
23
|
+
|
24
|
+
def redis
|
25
|
+
@redis ||= Redis.new(
|
26
|
+
host: @configurations['redis_host'],
|
27
|
+
port: @configurations['redis_port']
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module TelegramMeetupBot
|
2
|
+
module Initializers
|
3
|
+
class ResponsesLoader < Base
|
4
|
+
FILE_NAME = 'responses.yml'
|
5
|
+
AVAILABLE_KEYS = %w(today today_list today_cancel date date_list
|
6
|
+
date_cancel wrong_date_format old_date nobody not_subscribed help)
|
7
|
+
|
8
|
+
def self.responses
|
9
|
+
@configurations
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module TelegramMeetupBot
|
2
|
+
class MessageParser
|
3
|
+
attr_reader :message
|
4
|
+
User = Struct.new(:id, :username, :first_name)
|
5
|
+
|
6
|
+
def initialize(message)
|
7
|
+
@message = message
|
8
|
+
end
|
9
|
+
|
10
|
+
def author
|
11
|
+
from = message.from
|
12
|
+
User.new(from.id, from.username, from.first_name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def command
|
16
|
+
parse_message { |words| words.first }
|
17
|
+
end
|
18
|
+
|
19
|
+
def params
|
20
|
+
parse_message { |words| words.drop(1) } || []
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def parse_message(&block)
|
26
|
+
if message.text[0] == '/' && message.text.length > 1
|
27
|
+
yield message.text[1..-1].split(' ')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module TelegramMeetupBot
|
2
|
+
class Messenger
|
3
|
+
attr_reader :api, :chat_id
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@api = args.fetch(:api)
|
7
|
+
@chat_id = args.fetch(:chat_id)
|
8
|
+
end
|
9
|
+
|
10
|
+
def send(text)
|
11
|
+
api.send_message(chat_id: chat_id, text: text)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module TelegramMeetupBot
|
5
|
+
class ParamsParser
|
6
|
+
attr_reader :arg
|
7
|
+
|
8
|
+
def initialize(arg)
|
9
|
+
@arg = arg
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse_date
|
13
|
+
format = case arg
|
14
|
+
when /^[0-9]{,2}\.[0-9]{,2}\.[0-9][0-9]$/
|
15
|
+
"%d.%m.%y"
|
16
|
+
when /^[0-9]{,2}\.[0-9]{,2}$/
|
17
|
+
"%d.%m"
|
18
|
+
when /^[0-9]{,2}$/
|
19
|
+
"%d"
|
20
|
+
end
|
21
|
+
|
22
|
+
Date.strptime(arg, format) rescue nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_time
|
26
|
+
Time.parse(arg).strftime('%R') rescue nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module TelegramMeetupBot
|
2
|
+
class Storage
|
3
|
+
attr_reader :redis, :key
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@redis = args.fetch(:redis)
|
7
|
+
@key = args.fetch(:redis_key)
|
8
|
+
end
|
9
|
+
|
10
|
+
def get_users_for_date(date)
|
11
|
+
users_yml = redis.hget(key, date)
|
12
|
+
users_yml.nil? ? [] : YAML.load(users_yml)
|
13
|
+
end
|
14
|
+
|
15
|
+
def set_users_to_date(users, date)
|
16
|
+
redis.hset(key, date, users.to_yaml)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'telegram/bot'
|
2
|
+
|
3
|
+
require "telegram_meetup_bot/version"
|
4
|
+
require "telegram_meetup_bot/initializers"
|
5
|
+
require "telegram_meetup_bot/client"
|
6
|
+
require "telegram_meetup_bot/messenger"
|
7
|
+
require "telegram_meetup_bot/message_parser"
|
8
|
+
require "telegram_meetup_bot/storage"
|
9
|
+
require "telegram_meetup_bot/calendar"
|
10
|
+
require "telegram_meetup_bot/commands_handler"
|
11
|
+
require "telegram_meetup_bot/params_parser"
|
12
|
+
# require 'pry'
|
13
|
+
|
14
|
+
module TelegramMeetupBot
|
15
|
+
def self.run(config_path)
|
16
|
+
Initializers::ResponsesLoader.preload(config_path)
|
17
|
+
Initializers::ConfigLoader.preload(config_path)
|
18
|
+
|
19
|
+
Client.new(Initializers::ConfigLoader.token).run
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe TelegramMeetupBot::Calendar do
|
4
|
+
let(:storage) { double('storage') }
|
5
|
+
let(:user) { TelegramMeetupBot::MessageParser::User.new(1, 'Ikari01', 'Shinji') }
|
6
|
+
before { allow(TelegramMeetupBot::Initializers::ConfigLoader).to receive(:storage).and_return(storage)}
|
7
|
+
subject { described_class.new(user: user, date: Date.today, time: '10:00') }
|
8
|
+
|
9
|
+
describe '#delete_user_from_date' do
|
10
|
+
before { allow(storage).to receive(:set_users_to_date) }
|
11
|
+
|
12
|
+
context "when user exists in storage on selected date" do
|
13
|
+
before { allow(storage).to receive(:get_users_for_date).and_return([user.to_h]) }
|
14
|
+
|
15
|
+
it { expect(subject.delete_user_from_date).to eq(true) }
|
16
|
+
it 'set array without user to storage' do
|
17
|
+
expect(storage).to receive(:set_users_to_date).with([], Date.today)
|
18
|
+
subject.delete_user_from_date
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when user doesn't exists in storage on selected date" do
|
23
|
+
before { allow(storage).to receive(:get_users_for_date).and_return([]) }
|
24
|
+
|
25
|
+
it { expect(subject.delete_user_from_date).to eq(nil) }
|
26
|
+
it 'set array without user to storage' do
|
27
|
+
expect(storage).not_to receive(:set_users_to_date)
|
28
|
+
subject.delete_user_from_date
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#add_user_to_date' do
|
34
|
+
before { allow(storage).to receive(:set_users_to_date) }
|
35
|
+
|
36
|
+
context "when user exists in storage on selected date with equal hash" do
|
37
|
+
before { allow(storage).to receive(:get_users_for_date).and_return([user.to_h.merge(time: '10:00')]) }
|
38
|
+
|
39
|
+
it "doesn't update storage" do
|
40
|
+
expect(storage).not_to receive(:set_users_to_date)
|
41
|
+
subject.add_user_to_date
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when user exists in storage on selected date with different hash" do
|
46
|
+
before { allow(storage).to receive(:get_users_for_date).and_return([user.to_h.merge(time: '11:00')]) }
|
47
|
+
|
48
|
+
it "updates storage with new user hash" do
|
49
|
+
expect(storage).to receive(:set_users_to_date).with([user.to_h.merge(time: '10:00')], Date.today)
|
50
|
+
subject.add_user_to_date
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when user doesn't exist in storage on selected date " do
|
55
|
+
before { allow(storage).to receive(:get_users_for_date).and_return([]) }
|
56
|
+
|
57
|
+
it "updates storage with new user hash" do
|
58
|
+
expect(storage).to receive(:set_users_to_date).with([user.to_h.merge(time: '10:00')], Date.today)
|
59
|
+
subject.add_user_to_date
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe TelegramMeetupBot::MessageParser do
|
4
|
+
let(:from) { instance_double('from', id: 1, username: 'Ikari01', first_name: 'Shinji') }
|
5
|
+
let(:message) { instance_double('message', text: '/today', from: from) }
|
6
|
+
subject { described_class.new(message) }
|
7
|
+
|
8
|
+
describe '#command_with_params' do
|
9
|
+
context "when message doesn't start with / " do
|
10
|
+
let(:message) { instance_double('message', text: 'today', from: from) }
|
11
|
+
|
12
|
+
it { expect(subject.command).to eq(nil) }
|
13
|
+
it { expect(subject.params).to eq([]) }
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when message contain only / " do
|
17
|
+
let(:message) { instance_double('message', text: '/', from: from) }
|
18
|
+
|
19
|
+
it { expect(subject.command).to eq(nil) }
|
20
|
+
it { expect(subject.params).to eq([]) }
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when message without params" do
|
24
|
+
let(:message) { instance_double('message', text: '/today', from: from) }
|
25
|
+
|
26
|
+
it { expect(subject.command).to eq('today') }
|
27
|
+
it { expect(subject.params).to eq([]) }
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when message with params" do
|
31
|
+
let(:message) { instance_double('message', text: '/date 08.11.1998', from: from) }
|
32
|
+
|
33
|
+
it { expect(subject.command).to eq('date') }
|
34
|
+
it { expect(subject.params).to eq(['08.11.1998']) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#author' do
|
39
|
+
context "returns struct with author's data" do
|
40
|
+
user = TelegramMeetupBot::MessageParser::User.new(1, 'Ikari01', 'Shinji')
|
41
|
+
it { expect(subject.author).to eq(user) }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
RSpec.describe TelegramMeetupBot::ParamsParser do
|
5
|
+
describe '#parse_date' do
|
6
|
+
context 'fulldate' do
|
7
|
+
let(:dates) { %w(3.02.07 3.2.07 03.02.07 03.2.07) }
|
8
|
+
|
9
|
+
it 'works' do
|
10
|
+
dates.each do |date|
|
11
|
+
expect(described_class.new(date).parse_date).to eq(Date.parse('2007-02-03'))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'day with month' do
|
17
|
+
let(:dates) { %w(3.02 3.2 03.02 03.2) }
|
18
|
+
let(:year) { Date.today.year }
|
19
|
+
|
20
|
+
it 'works' do
|
21
|
+
dates.each do |date|
|
22
|
+
expect(described_class.new(date).parse_date).to eq(Date.parse("#{year}-02-03"))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'only day' do
|
28
|
+
let(:dates) { %w(3 03) }
|
29
|
+
|
30
|
+
it 'works' do
|
31
|
+
dates.each do |date|
|
32
|
+
expect(described_class.new(date).parse_date).to eq(Date.parse("03"))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'wrong format' do
|
38
|
+
let(:dates) { %w(abc 3.02.2007 3.02.7 2007.02.03 3-02-07 32.03.07 32) }
|
39
|
+
|
40
|
+
it 'returns nil' do
|
41
|
+
dates.each do |date|
|
42
|
+
expect(described_class.new(date).parse_date).to eq(nil)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#parse_time' do
|
49
|
+
context 'correct' do
|
50
|
+
let(:dates) { %w(01:05 1:05 1:5) }
|
51
|
+
|
52
|
+
it 'works' do
|
53
|
+
dates.each do |date|
|
54
|
+
expect(described_class.new(date).parse_time).to eq('01:05')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'wrong_format' do
|
60
|
+
let(:dates) { %w(abc 25:05 01:61 -3) }
|
61
|
+
|
62
|
+
it 'works' do
|
63
|
+
dates.each do |date|
|
64
|
+
expect(described_class.new(date).parse_time).to eq(nil)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'telegram_meetup_bot/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "telegram_meetup_bot"
|
8
|
+
spec.version = TelegramMeetupBot::VERSION
|
9
|
+
spec.authors = ["Timur Yanberdin"]
|
10
|
+
spec.email = ["yanberdint@gmail.com"]
|
11
|
+
spec.summary = "Telegram bot for meetups organisation"
|
12
|
+
spec.homepage = ""
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = "telegram_meetup_bot"
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
21
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
22
|
+
spec.add_development_dependency "rspec"
|
23
|
+
spec.add_development_dependency "pry"
|
24
|
+
|
25
|
+
spec.add_dependency 'redis'
|
26
|
+
spec.add_dependency 'telegram-bot-ruby'
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: telegram_meetup_bot
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Timur Yanberdin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-09-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: redis
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: telegram-bot-ruby
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description:
|
98
|
+
email:
|
99
|
+
- yanberdint@gmail.com
|
100
|
+
executables:
|
101
|
+
- telegram_meetup_bot
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- ".travis.yml"
|
107
|
+
- Gemfile
|
108
|
+
- LICENSE.txt
|
109
|
+
- README.md
|
110
|
+
- Rakefile
|
111
|
+
- bin/telegram_meetup_bot
|
112
|
+
- config_samples/config.yml
|
113
|
+
- config_samples/responses.yml
|
114
|
+
- lib/telegram_meetup_bot.rb
|
115
|
+
- lib/telegram_meetup_bot/calendar.rb
|
116
|
+
- lib/telegram_meetup_bot/client.rb
|
117
|
+
- lib/telegram_meetup_bot/commands_handler.rb
|
118
|
+
- lib/telegram_meetup_bot/initializers.rb
|
119
|
+
- lib/telegram_meetup_bot/initializers/base.rb
|
120
|
+
- lib/telegram_meetup_bot/initializers/config_loader.rb
|
121
|
+
- lib/telegram_meetup_bot/initializers/responses_loader.rb
|
122
|
+
- lib/telegram_meetup_bot/message_parser.rb
|
123
|
+
- lib/telegram_meetup_bot/messenger.rb
|
124
|
+
- lib/telegram_meetup_bot/params_parser.rb
|
125
|
+
- lib/telegram_meetup_bot/storage.rb
|
126
|
+
- lib/telegram_meetup_bot/version.rb
|
127
|
+
- spec/spec_helper.rb
|
128
|
+
- spec/telegram_meetup_bot/calendar_spec.rb
|
129
|
+
- spec/telegram_meetup_bot/message_parser_spec.rb
|
130
|
+
- spec/telegram_meetup_bot/params_parser_spec.rb
|
131
|
+
- telegram_meetup_bot.gemspec
|
132
|
+
homepage: ''
|
133
|
+
licenses:
|
134
|
+
- MIT
|
135
|
+
metadata: {}
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
requirements: []
|
151
|
+
rubyforge_project:
|
152
|
+
rubygems_version: 2.4.5
|
153
|
+
signing_key:
|
154
|
+
specification_version: 4
|
155
|
+
summary: Telegram bot for meetups organisation
|
156
|
+
test_files:
|
157
|
+
- spec/spec_helper.rb
|
158
|
+
- spec/telegram_meetup_bot/calendar_spec.rb
|
159
|
+
- spec/telegram_meetup_bot/message_parser_spec.rb
|
160
|
+
- spec/telegram_meetup_bot/params_parser_spec.rb
|