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.
@@ -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
@@ -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
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,8 @@
1
+ require "flowerpot/flowerpot"
2
+ require "flowerpot/telegram"
3
+ require "flowerpot/version"
4
+ require "flowerpot/cmtelecom"
5
+ require "flowerpot/twilio"
6
+
7
+ module Flowerpot
8
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module Flowerpot
2
+ VERSION = "1.0.0"
3
+ 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: []