circuit_client 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c8e1508915ce91398ef199c6f21c03eb84f0c614
4
+ data.tar.gz: b94c3dd4990da34a3ac0b34a7ea5d7869214c1b2
5
+ SHA512:
6
+ metadata.gz: 177e67970945a50d5468c57adcb8530d24096b877113a048f731b2d1265f95bdc32f4675bc10ced3a1e6936040ccc2e3e5a409db8d632899acf73c939c34f7ae
7
+ data.tar.gz: 19b15b3cfb43e6799cfa2676888a2017fdfd1cb26de7c4f0b7341316ef939da1a1798ab479fb97336eb3234ae4f6258e04f7556cf15b8d7368db5d6a8a321043
data/Dockerfile ADDED
@@ -0,0 +1,9 @@
1
+ FROM ruby:2.4
2
+
3
+ WORKDIR /usr/src/module
4
+
5
+ COPY Gemfile* ./
6
+ RUN bundle install
7
+
8
+ COPY . .
9
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # Circuit Client
2
+
3
+ circuit\_client is a minimal client for the Circuit REST API.
4
+
5
+ * [Circuit](https://www.circuit.com/)
6
+ * [Circuit REST API](https://circuitsandbox.net/rest/v2/swagger/ui/index.html)
7
+
8
+ It is not a full-featured API client and current only supports:
9
+
10
+ * only client\_credentials authentication
11
+ * list and create conversations
12
+ * create new messages
13
+
14
+ ## API Documentation
15
+
16
+ Available at [rubydoc.info](http://www.rubydoc.info/gems/circuit_client).
17
+
18
+ ## Usage
19
+
20
+ ### Basic usage
21
+
22
+ ```ruby
23
+ require 'circuit_client'
24
+
25
+ client = CircuitClient::Client.new do |c|
26
+ c.client_id = '<client_id>'
27
+ c.client_secret = '<client_secret>'
28
+ end
29
+
30
+ client.create_message('<convId>', 'Hello World!')
31
+ ```
32
+
33
+ ## Command line interface
34
+
35
+ The `send-circuit` command shipped with circuit\_client has the following options:
36
+
37
+ ```
38
+ Usage: send-circuit [OPTIONS]
39
+ --help | -h display this help text
40
+ --config | -c <file> path to configuration file
41
+ (default: /etc/send-circuit.yaml)
42
+ --trace print http debug information
43
+
44
+ List conversations:
45
+ --list | -l list conversations of user
46
+
47
+ Send message:
48
+ --subject | -s <text> Set subject for message
49
+
50
+ --conversation | -c <id> Id of the conversation to send a message to
51
+ or
52
+ --new | -n creates a new conversation
53
+ --topic | -t <text> topic of the new conversation
54
+ --participant | -p
55
+ <email or id> adds a participant to the conversation
56
+
57
+ The command will read the message body from stdin.
58
+ ```
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'rake/clean'
2
+ require 'rubygems'
3
+ require 'rubygems/package_task'
4
+ require 'rdoc/task'
5
+
6
+ spec = eval(File.read('circuit_client.gemspec'))
7
+ Gem::PackageTask.new(spec) do |pkg|
8
+ end
9
+
10
+ Rake::RDocTask.new do |rd|
11
+ rd.rdoc_files.include("lib/**/*.rb","bin/**/*")
12
+ rd.title = 'Circuit Client for REST API'
13
+ end
14
+
data/bin/send-circuit ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'circuit_client/send_message_cli'
4
+
5
+ app = CircuitClient::SendMessageCli.new
6
+ app.run
7
+
@@ -0,0 +1 @@
1
+ require 'circuit_client/client'
@@ -0,0 +1,190 @@
1
+ require 'faraday'
2
+ require 'typhoeus'
3
+ require 'typhoeus/adapters/faraday'
4
+ require 'uri'
5
+ require 'json'
6
+
7
+ module CircuitClient
8
+ class Client
9
+ # Set the hostname of the circuit system
10
+ attr_accessor :host
11
+
12
+ # The base path of the API
13
+ attr_accessor :base_path
14
+
15
+ # The protocol to use 'http' or 'https'
16
+ attr_accessor :protocol
17
+
18
+ # Timeout for http requests
19
+ attr_accessor :timeout
20
+
21
+ # The client_id for authentication
22
+ attr_accessor :client_id
23
+
24
+ # The client_secret for authentication
25
+ attr_accessor :client_secret
26
+
27
+ # The authentication method to use (currently only :client_credentials supported)
28
+ attr_accessor :auth_method
29
+
30
+ # Enable tracing (outputs http requests to STDOUT)
31
+ attr_accessor :trace
32
+
33
+ # Initialize a new client
34
+ #
35
+ # Examples
36
+ #
37
+ # CircuitClient::Client.new do |c|
38
+ # c.client_id = '4de34a3...'
39
+ # c.client_secret = '234df2...'
40
+ # end
41
+ #
42
+ # Returns a new CircuitClient::Client
43
+ def initialize
44
+ @host = 'eu.yourcircuit.com'
45
+ @base_path = '/rest/v2'
46
+ @protocol = 'https'
47
+ @auth_method = :client_credentials
48
+ @timeout = 60
49
+ @trace = false
50
+ yield self
51
+ end
52
+
53
+ # The faraday http connection object
54
+ def connection
55
+ @connection ||= Faraday.new(url: base_uri.to_s) do |faraday|
56
+ faraday.response :logger if @trace
57
+ faraday.use Faraday::Response::RaiseError
58
+ faraday.adapter :typhoeus
59
+ end
60
+ end
61
+
62
+ # The token used for authentication
63
+ def access_token
64
+ return @access_token unless @access_token.nil?
65
+ case @auth_method
66
+ when :client_credentials
67
+ auth_client_credentials
68
+ else
69
+ raise "Unknown auth_method: #{@auth_method}"
70
+ end
71
+ end
72
+
73
+ # Authenticate using client_credentials method
74
+ def auth_client_credentials
75
+ raise "client_id parameter required" if @client_id.nil?
76
+ raise "client_secret parameter required" if @client_secret.nil?
77
+ response = connection.post(build_uri('/oauth/token'), {
78
+ client_id: @client_id,
79
+ client_secret: @client_secret,
80
+ grant_type: 'client_credentials',
81
+ scope: 'ALL',
82
+ } )
83
+ data = JSON.parse(response.body)
84
+ data['access_token']
85
+ end
86
+
87
+ # Return URI with path elements
88
+ def base_uri
89
+ URI("#{@protocol}://#{@host}")
90
+ end
91
+
92
+ # Returns an URI with the base_uri and the supplied path
93
+ def build_uri(path)
94
+ uri = base_uri
95
+ uri.path = path
96
+ uri.to_s
97
+ end
98
+
99
+ # Returns an URI and with a path relative to the base_path of the API
100
+ def build_api_uri(path)
101
+ build_uri("#{@base_path}#{path}")
102
+ end
103
+
104
+ # Create a new message in a existing conversation
105
+ #
106
+ # Examples
107
+ #
108
+ # client.create_message('<convId>', 'my message text...', subject: 'Todays meeting')
109
+ #
110
+ def create_message(conv, text, **options)
111
+ call(:post, "/conversations/#{conv}/messages", {
112
+ 'content' => text,
113
+ **options,
114
+ } )
115
+ end
116
+
117
+ # List all conversation of the user
118
+ def list_conversations
119
+ call(:get, "/conversations")
120
+ end
121
+
122
+ # Create a new group conversation
123
+ def create_group_conversation(participants, topic)
124
+ call(:post, '/conversations/group', {
125
+ participants: participants,
126
+ topic: topic,
127
+ } )
128
+ end
129
+
130
+ # Create a new 1:1 conversation
131
+ def create_direct_conversation(participant)
132
+ call(:post, '/conversations/direct', {
133
+ participant: participant,
134
+ } )
135
+ end
136
+
137
+ # Remove participants from a conversation
138
+ def delete_group_conversation_participants(conv, participants)
139
+ call(:delete, "/conversations/group/#{conv}/participants", {
140
+ participants: participants,
141
+ } )
142
+ end
143
+
144
+ # Remove the current_user from a conversation
145
+ def leave_group_conversation(conv)
146
+ delete_group_conversation_participants(conv, [current_user['userId']])
147
+ end
148
+
149
+ # Get the profile of the connections user
150
+ def get_user_profile
151
+ call(:get, "/users/profile")
152
+ end
153
+
154
+ # A cached version of the current connections user profile
155
+ def current_user
156
+ @current_user ||= get_user_profile
157
+ end
158
+
159
+ # Get profile of a user
160
+ def get_users(id)
161
+ call(:get, "/users/#{id}")
162
+ end
163
+
164
+ # Get presence information of a user
165
+ def get_users_presence(id)
166
+ call(:get, "/users/#{id}/presence")
167
+ end
168
+
169
+ private
170
+
171
+ def call(method, path, payload = {}, headers = {})
172
+ response = connection.send(method) do |req|
173
+ req.url build_api_uri(path)
174
+ req.options.timeout = @timeout
175
+ req.headers['Accept'] = 'application/json'
176
+ req.headers['Authorization'] = "Bearer #{access_token}"
177
+ case method
178
+ when :post
179
+ req.body = payload.to_json
180
+ req.headers['Content-Type'] = 'application/json'
181
+ when :get, :delete
182
+ req.params = payload
183
+ end
184
+ end
185
+ return JSON.parse(response.body) if response.success?
186
+ end
187
+
188
+ end
189
+ end
190
+
@@ -0,0 +1,142 @@
1
+ require 'circuit_client'
2
+ require 'getoptlong'
3
+ require 'yaml'
4
+
5
+ module CircuitClient
6
+ class SendMessageCli
7
+
8
+ class Config
9
+ DEFAULTS = {
10
+ timeout: 60,
11
+ host: 'eu.yourcircuit.com',
12
+ client_id: nil,
13
+ client_secret: nil,
14
+ }
15
+ def self.load_config(path)
16
+ @@data = YAML.load_file(path)
17
+ end
18
+ def self.method_missing(method_name)
19
+ if DEFAULTS.has_key?(method_name)
20
+ @@data[method_name.to_s] || DEFAULTS[method_name]
21
+ else
22
+ super
23
+ end
24
+ end
25
+ end
26
+
27
+ def initialize
28
+ @trace = false
29
+ @list = false
30
+ @new = false
31
+ @participants = []
32
+ @config_file = '/etc/send-circuit.yaml'
33
+ @topic = ''
34
+ end
35
+
36
+ def usage
37
+ puts <<-END_USAGE
38
+ Usage: send-circuit [OPTIONS]
39
+ --help | -h display this help text
40
+ --config | -c <file> path to configuration file
41
+ (default: /etc/send-circuit.yaml)
42
+ --trace print http debug information
43
+
44
+ List conversations:
45
+ --list | -l list conversations of user
46
+
47
+ Send message:
48
+ --subject | -s <text> Set subject for message
49
+
50
+ --conversation | -c <id> Id of the conversation to send a message to
51
+ or
52
+ --new | -n creates a new conversation
53
+ --topic | -t <text> topic of the new conversation
54
+ --participant | -p
55
+ <email or id> adds a participant to the conversation
56
+
57
+
58
+ The command will read the message body from stdin.
59
+ END_USAGE
60
+ end
61
+
62
+ def getopts
63
+ opts = GetoptLong.new(
64
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
65
+ [ '--conversation', '-c', GetoptLong::REQUIRED_ARGUMENT ],
66
+ [ '--subject', '-s', GetoptLong::REQUIRED_ARGUMENT ],
67
+ [ '--topic', '-t', GetoptLong::REQUIRED_ARGUMENT ],
68
+ [ '--trace', GetoptLong::NO_ARGUMENT ],
69
+ [ '--list', '-l', GetoptLong::NO_ARGUMENT ],
70
+ [ '--new', '-n', GetoptLong::NO_ARGUMENT ],
71
+ [ '--participant', '-p', GetoptLong::REQUIRED_ARGUMENT ],
72
+ [ '--config', '-f', GetoptLong::REQUIRED_ARGUMENT ],
73
+ )
74
+ opts.each do |opt, arg|
75
+ case opt
76
+ when '--help'
77
+ usage
78
+ exit 0
79
+ when '--conversation'
80
+ @conversation = arg.to_s
81
+ when '--subject'
82
+ @subject = arg.to_s
83
+ when '--trace'
84
+ @trace = true
85
+ when '--list'
86
+ @list = true
87
+ when '--new'
88
+ @new = true
89
+ when '--participant'
90
+ @participants << arg.to_s
91
+ when '--config'
92
+ @config_file = arg.to_s
93
+ when '--topic'
94
+ @topic = arg.to_s
95
+ end
96
+ end
97
+ end
98
+
99
+ def run
100
+ getopts
101
+ Config.load_config(@config_file)
102
+
103
+ if @list == true
104
+ list_conversations
105
+ exit 0
106
+ end
107
+
108
+ # read msg from stdin
109
+ body = $stdin.readlines.join
110
+
111
+ if @new == true
112
+ puts "creating new group conversation..."
113
+ conv = client.create_group_conversation(@participants, @topic)['convId']
114
+ else
115
+ conv = @conversation
116
+ end
117
+
118
+ options = {}
119
+ options[:subject] = @subject unless @subject.nil?
120
+ puts "sending message to #{conv}..."
121
+ client.create_message( conv, body, **options )
122
+ end
123
+
124
+ def client
125
+ CircuitClient::Client.new do |c|
126
+ c.host = Config.host
127
+ c.client_id = Config.client_id
128
+ c.client_secret = Config.client_secret
129
+ c.trace = @trace
130
+ c.timeout = Config.timeout
131
+ end
132
+ end
133
+
134
+ def list_conversations
135
+ client.list_conversations.each do |c|
136
+ puts "- #{c['topic']} (#{c['convId']})"
137
+ end
138
+ end
139
+
140
+ end
141
+ end
142
+
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: circuit_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Markus Benning
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-02-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
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: rdoc
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
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: aruba
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: faraday
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
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: typhoeus
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
+ description:
84
+ email: ich@markusbenning.de
85
+ executables:
86
+ - send-circuit
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - Dockerfile
91
+ - Gemfile
92
+ - README.md
93
+ - Rakefile
94
+ - bin/send-circuit
95
+ - lib/circuit_client.rb
96
+ - lib/circuit_client/client.rb
97
+ - lib/circuit_client/send_message_cli.rb
98
+ homepage: https://github.com/benningm/circuit_client
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.6.8
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: Simple client for circuit REST API
123
+ test_files: []