cronofy 0.24.1 → 0.25.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 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