flowerpot 1.0.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/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/flowerpot.rb +8 -0
- data/lib/flowerpot/cmtelecom.rb +110 -0
- data/lib/flowerpot/flowerpot.rb +54 -0
- data/lib/flowerpot/telegram.rb +96 -0
- data/lib/flowerpot/twilio.rb +34 -0
- data/lib/flowerpot/version.rb +3 -0
- metadata +108 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a7ede51670e2f4cee3e5bc4c23eafc988ffcf43f
|
4
|
+
data.tar.gz: 9418087b9c1feada77fc4103cdcd30a8b2121de6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c8b8e66e3a40853cb70124c6cfba3f6ca16528d9fd7c01b0ac89f4f1939f89993bbf63892fdd20301c858ce2f123fc5b7c2457185a3285054c96f518ad69c155
|
7
|
+
data.tar.gz: 28313dabcf469ffdaa6d118db0ce39beaaf94f101f7bc8b68661e482b970f219c2bf9915c7737a20e2ce82047dfa60515d4cb0693aeed4d6ab9fa5593416eeba
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "flowerpot"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/lib/flowerpot.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require "json"
|
2
|
+
require "net/http"
|
3
|
+
|
4
|
+
module Flowerpot
|
5
|
+
class CMTelecomMessage
|
6
|
+
attr_accessor :from
|
7
|
+
attr_accessor :token
|
8
|
+
|
9
|
+
def initialize(number, text, from=nil)
|
10
|
+
@number = number
|
11
|
+
@text = text
|
12
|
+
@from = from
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid_from?
|
16
|
+
if /^[0-9]{1,15}$/.match(@from) == nil and /^[0-9a-zA-Z]{1,11}$/.match(@from) == nil
|
17
|
+
return false
|
18
|
+
end
|
19
|
+
return true
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid_length?
|
23
|
+
if @text.length > 160 or @text.length < 1
|
24
|
+
return false
|
25
|
+
end
|
26
|
+
return true
|
27
|
+
end
|
28
|
+
|
29
|
+
def valid_number?
|
30
|
+
if /^0{2}[0-9]+$/.match(@number) == nil
|
31
|
+
return false
|
32
|
+
end
|
33
|
+
return true
|
34
|
+
end
|
35
|
+
|
36
|
+
def valid_token?
|
37
|
+
if /^[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}$/.match(@token) == nil
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
return true
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_json(*a)
|
44
|
+
if !valid_from?
|
45
|
+
raise "from must not be empty and either shorter than 16 digits or shorter than 12 characters"
|
46
|
+
end
|
47
|
+
|
48
|
+
if !valid_length?
|
49
|
+
raise "text must not be empty or longer than 160 characters"
|
50
|
+
end
|
51
|
+
|
52
|
+
if !valid_number?
|
53
|
+
raise "number must not be empty, start with 00 and only consist of numerals"
|
54
|
+
end
|
55
|
+
|
56
|
+
if !valid_token?
|
57
|
+
raise "invalid api token"
|
58
|
+
end
|
59
|
+
|
60
|
+
return {
|
61
|
+
messages: {
|
62
|
+
authentication: {
|
63
|
+
producttoken: @token
|
64
|
+
},
|
65
|
+
msg: [
|
66
|
+
{
|
67
|
+
from: @from,
|
68
|
+
to: [ { number: @number }],
|
69
|
+
body: { content: @text }
|
70
|
+
}
|
71
|
+
]
|
72
|
+
}
|
73
|
+
}.to_json(*a)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class CMTelecomClient
|
78
|
+
def initialize(token, from)
|
79
|
+
if token.length == 0
|
80
|
+
raise "token must be set"
|
81
|
+
end
|
82
|
+
|
83
|
+
if from.length == 0
|
84
|
+
raise "default from must be set"
|
85
|
+
end
|
86
|
+
|
87
|
+
@token = token
|
88
|
+
@from = from
|
89
|
+
end
|
90
|
+
|
91
|
+
def send_message(message)
|
92
|
+
if message.from == nil
|
93
|
+
message.from = @from
|
94
|
+
end
|
95
|
+
|
96
|
+
message.token = @token
|
97
|
+
|
98
|
+
uri = URI('https://gw.cmtelecom.com/v1.0/message')
|
99
|
+
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
|
100
|
+
req.body = message.to_json
|
101
|
+
res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') do |http|
|
102
|
+
http.request(req)
|
103
|
+
end
|
104
|
+
|
105
|
+
if res.code != "200"
|
106
|
+
raise "#{res.code} #{res.message}"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "json"
|
2
|
+
require "net/http"
|
3
|
+
|
4
|
+
module Flowerpot
|
5
|
+
class Message
|
6
|
+
attr_accessor :text
|
7
|
+
end
|
8
|
+
|
9
|
+
class Flowerpot
|
10
|
+
attr_reader :telegram
|
11
|
+
attr_reader :cmtelecom
|
12
|
+
attr_reader :twilio
|
13
|
+
|
14
|
+
def initialize(config)
|
15
|
+
if config[:telegram]
|
16
|
+
@telegram = TelegramClient.new(config[:telegram][:token], config[:telegram][:webhook_url],config[:telegram][:chat_id_get], config[:telegram][:chat_id_save])
|
17
|
+
end
|
18
|
+
|
19
|
+
if config[:cmtelecom]
|
20
|
+
@cmtelecom = CMTelecomClient.new(config[:cmtelecom][:token], config[:cmtelecom][:from])
|
21
|
+
end
|
22
|
+
|
23
|
+
if config[:twilio]
|
24
|
+
@twilio = TwilioClient.new(config[:twilio][:account_sid], config[:twilio][:auth_token], config[:twilio][:from])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def transports
|
29
|
+
return {telegram: @telegram != nil, cmtelecom: @cmtelecom != nil, twilio: @twilio != nil}
|
30
|
+
end
|
31
|
+
|
32
|
+
def send_message(message)
|
33
|
+
case
|
34
|
+
when message.class == TelegramMessage
|
35
|
+
if @telegram
|
36
|
+
@telegram.send_message(message)
|
37
|
+
return
|
38
|
+
end
|
39
|
+
when message.class == CMTelecomMessage
|
40
|
+
if @cmtelecom
|
41
|
+
@cmtelecom.send_message(message)
|
42
|
+
return
|
43
|
+
end
|
44
|
+
when message.class == TwilioMessage
|
45
|
+
if @twilio
|
46
|
+
@twilio.send_message(message)
|
47
|
+
return
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
raise "unknown message type"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require "json"
|
2
|
+
require "net/http"
|
3
|
+
|
4
|
+
module Flowerpot
|
5
|
+
class TelegramMessage
|
6
|
+
attr_reader :username
|
7
|
+
attr_reader :text
|
8
|
+
|
9
|
+
def initialize(username, text)
|
10
|
+
@username = username
|
11
|
+
@text = text
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class TelegramClient
|
16
|
+
# method used to get a username/chat_id mapping
|
17
|
+
attr_accessor :chat_id_get
|
18
|
+
|
19
|
+
# method used to set a username/chat_id mapping
|
20
|
+
attr_accessor :chat_id_save
|
21
|
+
|
22
|
+
# access is allowed to this to make it possible to initialize the buildin username/chat_id mapping
|
23
|
+
# use this if you know what you do.
|
24
|
+
attr_accessor :telegram_users
|
25
|
+
|
26
|
+
# creates a new TelegramClient.
|
27
|
+
# token is your telegram bot token
|
28
|
+
# webhook_url is the url where the webhook can be called
|
29
|
+
# chat_id_get is a proc used to retrieve a username/chat_id mapping
|
30
|
+
# chat_id_save is a proc used to save a username/chat_id mapping
|
31
|
+
def initialize(token, webhook_url=nil, chat_id_get=nil, chat_id_save=nil)
|
32
|
+
@token = token
|
33
|
+
@telegram_users = {}
|
34
|
+
|
35
|
+
# set both methods for storing username/chat_id mappings
|
36
|
+
# to the ones supplied as parameters or the internal ones
|
37
|
+
if !chat_id_get.nil? && !chat_id_save.nil?
|
38
|
+
@chat_id_get = chat_id_get
|
39
|
+
@chat_id_save = chat_id_save
|
40
|
+
else
|
41
|
+
@chat_id_get = lambda do |username|
|
42
|
+
@telegram_users[username]
|
43
|
+
end
|
44
|
+
@chat_id_save = lambda do |username, id|
|
45
|
+
@telegram_users[username] = id
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# set the webhook if we have one
|
50
|
+
if !webhook_url.nil?
|
51
|
+
set_webhook(url)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# set the webhook url with the telegram servers
|
56
|
+
def set_webhook(url)
|
57
|
+
send_request('setWebhook', {"url":url})
|
58
|
+
end
|
59
|
+
|
60
|
+
# delete the webhook url from the telegram servers
|
61
|
+
def delete_webhook
|
62
|
+
send_request('deleteWebhook', {})
|
63
|
+
end
|
64
|
+
|
65
|
+
# webhook has to be called with the body of a request to the webhook url.
|
66
|
+
# see https://core.telegram.org/bots/api#setwebhook
|
67
|
+
def webhook(body)
|
68
|
+
x = JSON.parse(body)
|
69
|
+
if !x.has_key?("message")
|
70
|
+
raise "update isn't a message"
|
71
|
+
end
|
72
|
+
|
73
|
+
username = x["message"]["chat"]["username"]
|
74
|
+
chat_id = x["message"]["chat"]["id"]
|
75
|
+
|
76
|
+
@chat_id_save.call(username, chat_id)
|
77
|
+
end
|
78
|
+
|
79
|
+
# send a telegram message
|
80
|
+
def send_message(message)
|
81
|
+
chat_id = @chat_id_get.call(message.username)
|
82
|
+
send_request("sendMessage", {"chat_id": chat_id, "text": message.text})
|
83
|
+
end
|
84
|
+
|
85
|
+
# send a request to telegram
|
86
|
+
def send_request(method, params)
|
87
|
+
uri = URI("https://api.telegram.org/bot#{@token}/#{method}")
|
88
|
+
res = Net::HTTP.post_form(uri, params)
|
89
|
+
if res.code != "200"
|
90
|
+
raise "#{res.code} #{res.message}"
|
91
|
+
end
|
92
|
+
|
93
|
+
return res
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'twilio-ruby'
|
2
|
+
|
3
|
+
module Flowerpot
|
4
|
+
class TwilioMessage
|
5
|
+
attr_reader :number
|
6
|
+
attr_reader :text
|
7
|
+
|
8
|
+
def initialize(number, text)
|
9
|
+
@number = number
|
10
|
+
@text = text
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid_number?
|
14
|
+
if /^0{2}[0-9]+$/.match(@number) == nil and /^\+[0-9]+$/.match(@number) == nil
|
15
|
+
return false
|
16
|
+
end
|
17
|
+
return true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class TwilioClient
|
22
|
+
def initialize(account_sid, auth_token, from)
|
23
|
+
@from = from
|
24
|
+
@client = Twilio::REST::Client.new account_sid, auth_token
|
25
|
+
end
|
26
|
+
|
27
|
+
def send_message(message)
|
28
|
+
if !message.valid_number?
|
29
|
+
raise "number must be in a valid international format"
|
30
|
+
end
|
31
|
+
@client.messages.create(from: @from, to: message.number, body: message.text)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: flowerpot
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ruben Schuller
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-03-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: twilio-ruby
|
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: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.13'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.13'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
description: Flowerpot is a wrapper for various messaging channels. Currently Telegram,
|
70
|
+
CM Telecom and Twilio are supported.
|
71
|
+
email:
|
72
|
+
- schuller@bytemine.net
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- bin/console
|
78
|
+
- bin/setup
|
79
|
+
- lib/flowerpot.rb
|
80
|
+
- lib/flowerpot/cmtelecom.rb
|
81
|
+
- lib/flowerpot/flowerpot.rb
|
82
|
+
- lib/flowerpot/telegram.rb
|
83
|
+
- lib/flowerpot/twilio.rb
|
84
|
+
- lib/flowerpot/version.rb
|
85
|
+
homepage: https://github.com/bytemine/flowerpot
|
86
|
+
licenses: []
|
87
|
+
metadata: {}
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 2.4.8
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: Flowerpot is a wrapper for various messaging channels.
|
108
|
+
test_files: []
|