cronofy 0.24.1 → 0.25.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 639cf154e0bae1368e59a8c506f52dcdd0d80d7d
4
- data.tar.gz: cc17141d1b0eb4b1710dd7a90773a61bfca76e00
3
+ metadata.gz: bed8b488fc8541bce5c97cd5295059a35b11712d
4
+ data.tar.gz: 98a3c423e351ec564a4ff3456b1ba6149614cd7e
5
5
  SHA512:
6
- metadata.gz: 8c0bbd381139093ebf7ae94c5004ad9099bdcbb9a6aee097a9e8e2d0d1f86b3edeb5e89c9657a294f62360b997cc0b03079e454ad739866aebda7d2360083da3
7
- data.tar.gz: 4a8f8cb63977c3364e8acdf5c46fa4f4eabacf29de6d5768b4507061241afe6d78de927d3abfef75e58c0483752c523269ec56f59ba8022db98824f68b1208f5
6
+ metadata.gz: fd6f0a7779ba848f996df1339cf1e353948a2c12f47c9e79ab0e29cf8a92e4b5075d3077e4e7118adad395885aa19d3e5679c903219dafad1eedf4ec056d7523
7
+ data.tar.gz: c6adc9c8be4946c7b018c704b5b5850ef7abdd09619e396664a6b0d52b72e6e2e03584a83df30279e0dcba818765d6cc96776a667b2143d0f04cafff7492804d
@@ -1,3 +1,8 @@
1
+ ## [0.25.0]
2
+
3
+ * Support for Smart Invites [#49]
4
+ * Fix warning in Ruby 2.4 [#50]
5
+
1
6
  ## [0.24.1]
2
7
 
3
8
  * Disable Hashie warnings [#52]
@@ -80,6 +85,7 @@
80
85
  [0.23.0]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.23.0
81
86
  [0.24.0]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.24.0
82
87
  [0.24.1]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.24.1
88
+ [0.25.0]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.25.0
83
89
 
84
90
  [#13]: https://github.com/cronofy/cronofy-ruby/pull/13
85
91
  [#16]: https://github.com/cronofy/cronofy-ruby/pull/16
@@ -101,4 +107,6 @@
101
107
  [#45]: https://github.com/cronofy/cronofy-ruby/pull/45
102
108
  [#46]: https://github.com/cronofy/cronofy-ruby/pull/46
103
109
  [#48]: https://github.com/cronofy/cronofy-ruby/pull/48
110
+ [#49]: https://github.com/cronofy/cronofy-ruby/pull/49
111
+ [#50]: https://github.com/cronofy/cronofy-ruby/pull/50
104
112
  [#52]: https://github.com/cronofy/cronofy-ruby/pull/52
@@ -1,6 +1,7 @@
1
1
  require "cronofy/version"
2
2
  require "cronofy/errors"
3
3
  require "cronofy/types"
4
+ require "cronofy/api_key"
4
5
  require "cronofy/auth"
5
6
  require "cronofy/client"
6
7
  require "cronofy/response_parser"
@@ -0,0 +1,73 @@
1
+ require "oauth2"
2
+
3
+ module Cronofy
4
+ class ApiKey
5
+ def initialize(client, client_secret)
6
+ @client = client
7
+ @client_secret = client_secret
8
+ end
9
+
10
+ # Make a request with the API Key
11
+ #
12
+ # @param [Symbol] verb the HTTP request method
13
+ # @param [String] path the HTTP URL path of the request
14
+ # @param [Hash] opts the options to make the request with
15
+ # @see Client#request
16
+ def request(verb, path, opts = {}, &block)
17
+ configure_authentication!(opts)
18
+ do_request { @client.request(verb, path, opts, &block) }
19
+ end
20
+
21
+ # Make a GET request with the API Key
22
+ #
23
+ # @see ApiKey#request
24
+ def get(path, opts = {}, &block)
25
+ request(:get, path, opts, &block)
26
+ end
27
+
28
+ # Make a POST request with the API Key
29
+ #
30
+ # @see ApiKey#request
31
+ def post(path, opts = {}, &block)
32
+ request(:post, path, opts, &block)
33
+ end
34
+
35
+ # Make a PUT request with the API Key
36
+ #
37
+ # @see ApiKey#request
38
+ def put(path, opts = {}, &block)
39
+ request(:put, path, opts, &block)
40
+ end
41
+
42
+ # Make a PATCH request with the API Key
43
+ #
44
+ # @see ApiKey#request
45
+ def patch(path, opts = {}, &block)
46
+ request(:patch, path, opts, &block)
47
+ end
48
+
49
+ private
50
+
51
+ def headers
52
+ {'Authorization' => "Bearer #{@client_secret}"}
53
+ end
54
+
55
+ def configure_authentication!(opts)
56
+ opts[:headers] ||= {}
57
+ opts[:headers].merge!(headers)
58
+ end
59
+
60
+ def do_request(&block)
61
+ if blank?(@client_secret)
62
+ raise CredentialsMissingError.new("OAuth client_id and client_secret must be set")
63
+ end
64
+ block.call
65
+ rescue OAuth2::Error => e
66
+ raise Errors.map_error(e)
67
+ end
68
+
69
+ def blank?(value)
70
+ value.nil? || value.strip.empty?
71
+ end
72
+ end
73
+ end
@@ -4,6 +4,7 @@ module Cronofy
4
4
  # Internal: Class for dealing with authentication and authorization issues.
5
5
  class Auth
6
6
  attr_reader :access_token
7
+ attr_reader :api_key
7
8
 
8
9
  def initialize(options = {})
9
10
  access_token = options[:access_token]
@@ -18,6 +19,7 @@ module Cronofy
18
19
  @api_client = OAuth2::Client.new(client_id, client_secret, site: ::Cronofy.api_url(data_centre), connection_opts: { headers: { "User-Agent" => "Cronofy Ruby #{::Cronofy::VERSION}" } })
19
20
 
20
21
  set_access_token(access_token, refresh_token) if access_token || refresh_token
22
+ set_api_key(client_secret) if client_secret
21
23
  end
22
24
 
23
25
  # Internal: generate a URL for authorizing the application with Cronofy
@@ -81,6 +83,10 @@ module Cronofy
81
83
  @access_token = OAuth2::AccessToken.new(@api_client, token, refresh_token: refresh_token)
82
84
  end
83
85
 
86
+ def set_api_key(client_secret)
87
+ @api_key = ApiKey.new(@api_client, client_secret)
88
+ end
89
+
84
90
  # Internal: Revokes the refresh token and corresponding access tokens.
85
91
  #
86
92
  # Returns nothing.
@@ -974,6 +974,105 @@ module Cronofy
974
974
  nil
975
975
  end
976
976
 
977
+ # Public: Creates or updates smart invite.
978
+ #
979
+ # smart_invite_id - A String uniquely identifying the event for your
980
+ # application (note: this is NOT an ID generated
981
+ # by Cronofy).
982
+ # callback_url - The URL within your application you want Cronofy to
983
+ # send notifications to about user interactions with
984
+ # the Smart Invite.
985
+ # recipient - A Hash containing the intended recipient of the invite
986
+ # :email - A String for thee email address you are
987
+ # going to send the Smart Invite to.
988
+ # event - A Hash describing the event with symbolized keys:
989
+ # :summary - A String to use as the summary, sometimes
990
+ # referred to as the name or title, of the
991
+ # event.
992
+ # :description - A String to use as the description, sometimes
993
+ # referred to as the notes or body, of the
994
+ # event.
995
+ # :start - The Time or Date the event starts.
996
+ # :end - The Time or Date the event ends.
997
+ # :url - The URL associated with the event.
998
+ # :location - A Hash describing the location of the event
999
+ # with symbolized keys (optional):
1000
+ # :description - A String describing the
1001
+ # location.
1002
+ # :lat - A String of the location's latitude.
1003
+ # :long - A String of the location's longitude.
1004
+ # :reminders - An Array of Hashes describing the desired
1005
+ # reminders for the event. Reminders should be
1006
+ # specified in priority order as, for example,
1007
+ # when the underlying provider only supports a
1008
+ # single reminder then the first reminder will
1009
+ # be used.
1010
+ # :minutes - An Integer specifying the number
1011
+ # of minutes before the start of the
1012
+ # event that the reminder should
1013
+ # occur.
1014
+ # :transparency - The transparency state for the event (optional).
1015
+ # Accepted values are "transparent" and "opaque".
1016
+ # :color - The color of the event (optional).
1017
+ #
1018
+ # Examples
1019
+ #
1020
+ # client.upsert_smart_invite(
1021
+ # smart_invite_id: "qTtZdczOccgaPncGJaCiLg",
1022
+ # callback_url: "http://www.example.com",
1023
+ # attendee: {
1024
+ # email: "example@example.com"
1025
+ # },
1026
+ # event: {
1027
+ # summary: "Board meeting",
1028
+ # description: "Discuss plans for the next quarter.",
1029
+ # start: Time.utc(2014, 8, 5, 15, 30),
1030
+ # end: Time.utc(2014, 8, 5, 17, 30),
1031
+ # location: {
1032
+ # description: "Board room",
1033
+ # lat: "1.2345",
1034
+ # long: "0.1234"
1035
+ # }
1036
+ # )
1037
+ #
1038
+ # See http://www.cronofy.com/developers/alpha/api#smart-invite for reference.
1039
+ #
1040
+ # Returns a SmartInviteResponse.
1041
+ #
1042
+ # Raises Cronofy::CredentialsMissingError if no credentials available.
1043
+ # Raises Cronofy::InvalidRequestError if the request contains invalid
1044
+ # parameters.
1045
+ # Raises Cronofy::TooManyRequestsError if the request exceeds the rate
1046
+ # limits for the application.
1047
+ def upsert_smart_invite(body={})
1048
+ body[:event][:start] = encode_event_time(body[:event][:start])
1049
+ body[:event][:end] = encode_event_time(body[:event][:end])
1050
+
1051
+ response = wrapped_request { api_key!.post("/v1/smart_invites", json_request_args(body)) }
1052
+ parse_json(SmartInviteResponse, nil, response)
1053
+ end
1054
+
1055
+ # Public: Gets the details for a smart invite.
1056
+ #
1057
+ # smart_invite_id - A String uniquely identifying the event for your
1058
+ # application (note: this is NOT an ID generated
1059
+ # by Cronofy).
1060
+ # recipient_email - The email address for the recipient to get details for.
1061
+ #
1062
+ # See http://www.cronofy.com/developers/alpha/api#smart-invite for reference.
1063
+ #
1064
+ # Returns a SmartInviteResponse.
1065
+ #
1066
+ # Raises Cronofy::CredentialsMissingError if no credentials available.
1067
+ # Raises Cronofy::InvalidRequestError if the request contains invalid
1068
+ # parameters.
1069
+ # Raises Cronofy::TooManyRequestsError if the request exceeds the rate
1070
+ # limits for the application.
1071
+ def get_smart_invite(smart_invite_id, recipient_email)
1072
+ response = wrapped_request { api_key!.get("/v1/smart_invites?recipient_email=#{recipient_email}&smart_invite_id=#{smart_invite_id}") }
1073
+ parse_json(SmartInviteResponse, nil, response)
1074
+ end
1075
+
977
1076
  private
978
1077
 
979
1078
  def translate_available_periods(periods)
@@ -1035,7 +1134,7 @@ module Cronofy
1035
1134
 
1036
1135
  def map_availability_required_duration(required_duration)
1037
1136
  case required_duration
1038
- when Fixnum
1137
+ when Integer
1039
1138
  { minutes: required_duration }
1040
1139
  else
1041
1140
  required_duration
@@ -1065,6 +1164,11 @@ module Cronofy
1065
1164
  @auth.access_token
1066
1165
  end
1067
1166
 
1167
+ def api_key!
1168
+ raise CredentialsMissingError.new unless @auth.api_key
1169
+ @auth.api_key
1170
+ end
1171
+
1068
1172
  def get(url, opts = {})
1069
1173
  wrapped_request { access_token!.get(url, opts) }
1070
1174
  end
@@ -283,6 +283,9 @@ module Cronofy
283
283
  class AddToCalendarResponse < CronofyMash
284
284
  end
285
285
 
286
+ class SmartInviteResponse < Hashie::Mash
287
+ end
288
+
286
289
  module ParticipantEnumerable
287
290
  def self.coerce(values)
288
291
  values.map { |v| Participant.new(v) }
@@ -1,3 +1,3 @@
1
1
  module Cronofy
2
- VERSION = "0.24.1".freeze
2
+ VERSION = "0.25.0".freeze
3
3
  end
@@ -1744,4 +1744,86 @@ describe Cronofy::Client do
1744
1744
  expect(client.hmac_match?(body: body, hmac: "something-else")).to be false
1745
1745
  end
1746
1746
  end
1747
+
1748
+ describe "Smart Invite" do
1749
+ let(:request_url) { "https://api.cronofy.com/v1/smart_invites" }
1750
+ let(:url) { URI("https://example.com") }
1751
+ let(:method) { :post }
1752
+
1753
+ let(:request_headers) do
1754
+ {
1755
+ "Authorization" => "Bearer #{client_secret}",
1756
+ "User-Agent" => "Cronofy Ruby #{::Cronofy::VERSION}",
1757
+ "Content-Type" => "application/json; charset=utf-8",
1758
+ }
1759
+ end
1760
+
1761
+ let(:location) { { :description => "Board room" } }
1762
+ let(:client_id) { 'example_id' }
1763
+ let(:client_secret) { 'example_secret' }
1764
+
1765
+ let(:client) do
1766
+ Cronofy::Client.new(
1767
+ client_id: client_id,
1768
+ client_secret: client_secret,
1769
+ )
1770
+ end
1771
+
1772
+ let(:start_datetime) { Time.utc(2014, 8, 5, 15, 30, 0) }
1773
+ let(:end_datetime) { Time.utc(2014, 8, 5, 17, 0, 0) }
1774
+ let(:encoded_start_datetime) { "2014-08-05T15:30:00Z" }
1775
+ let(:encoded_end_datetime) { "2014-08-05T17:00:00Z" }
1776
+
1777
+ let(:args) do
1778
+ {
1779
+ smart_invite_id: "qTtZdczOccgaPncGJaCiLg",
1780
+ callback_url: url.to_s,
1781
+ event: {
1782
+ :summary => "Board meeting",
1783
+ :description => "Discuss plans for the next quarter.",
1784
+ :url => url.to_s,
1785
+ :start => start_datetime,
1786
+ :end => encoded_end_datetime,
1787
+ :location => location,
1788
+ :reminders => [
1789
+ { :minutes => 60 },
1790
+ { :minutes => 0 },
1791
+ { :minutes => 10 },
1792
+ ],
1793
+ },
1794
+ }
1795
+ end
1796
+
1797
+ let(:request_body) do
1798
+ {
1799
+ smart_invite_id: "qTtZdczOccgaPncGJaCiLg",
1800
+ callback_url: url.to_s,
1801
+ event: {
1802
+ :summary => "Board meeting",
1803
+ :description => "Discuss plans for the next quarter.",
1804
+ :url => url.to_s,
1805
+ :start => encoded_start_datetime,
1806
+ :end => encoded_end_datetime,
1807
+ :location => location,
1808
+ :reminders => [
1809
+ { :minutes => 60 },
1810
+ { :minutes => 0 },
1811
+ { :minutes => 10 },
1812
+ ],
1813
+ },
1814
+ }
1815
+ end
1816
+ let(:correct_response_code) { 202 }
1817
+ let(:correct_response_body) do
1818
+ request_body.merge({
1819
+ attachments: []
1820
+ })
1821
+ end
1822
+
1823
+ subject { client.upsert_smart_invite(request_body) }
1824
+
1825
+ it_behaves_like 'a Cronofy request'
1826
+
1827
+ end
1828
+
1747
1829
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cronofy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.24.1
4
+ version: 0.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergii Paryzhskyi
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-10-13 00:00:00.000000000 Z
12
+ date: 2017-10-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: oauth2
@@ -116,6 +116,7 @@ files:
116
116
  - Rakefile
117
117
  - cronofy.gemspec
118
118
  - lib/cronofy.rb
119
+ - lib/cronofy/api_key.rb
119
120
  - lib/cronofy/auth.rb
120
121
  - lib/cronofy/client.rb
121
122
  - lib/cronofy/errors.rb
@@ -149,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
150
  version: '0'
150
151
  requirements: []
151
152
  rubyforge_project:
152
- rubygems_version: 2.6.6
153
+ rubygems_version: 2.6.12
153
154
  signing_key:
154
155
  specification_version: 4
155
156
  summary: Cronofy - one API for all the calendars