Skip to content

Commit

Permalink
Merge pull request #7 from ekohe/feature/single_event_request_and_sub…
Browse files Browse the repository at this point in the history
…scription_support

FEATURE #3335 single event request and subscription support
  • Loading branch information
encoreshao authored Aug 8, 2024
2 parents f5b6ada + 3c316cc commit 4a2c698
Show file tree
Hide file tree
Showing 13 changed files with 337 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/.bundle/
/.idea/
/.yardoc
/_yardoc/
/coverage/
Expand Down
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ irb(main):005:0> client.events[:results]
irb(main):005:0> client.events[:next_link]
```

**Get my event by id**

```ruby
irb(main):005:0> client.event('identifier')
irb(main):005:0> client.event('identifier')[:results]
```

Results will return an array even if it is a single result.

**Get my mails by access token**

```ruby
Expand Down Expand Up @@ -171,6 +180,37 @@ irb(main):005:0> response.refresh_token
=> "0.ARgA7EiQdLv1qECnFqPfrznKsT9ERYaGfG9Ki5WzQtEllj8YAJk.AgABAAEAAAD--DLA3VO7QrddgJg7WevrAgDs_wQA9P-Q1ODlBsrdZi-5s2mfLtEsavBgiEhGcz1KEf26fMrGFU3LM_og5l6wjSAtQ83XHLuje0_KYGol26_LGV_uH0F1MwCFR1N3ctwg4_...."
```

**Create Subscription: it will create a webhook for Office365**

```ruby
args = {
changeType: "updated,deleted",
notificationUrl: "https://hello-world.com/office365/notifications",
lifecycleNotificationUrl: "https://hello-world.com/office365/lifecycle_notifications",
resource: "/me/{type}",
expirationDateTime: "2024-08-07T12:00:00.0000000Z",
clientState: "SecretClientState"
}

irb(main):005:0> subscription = client.create_subscription(args)
```

will return the subscription object `Office365::Models::Subscription`

**Renew Subscription**

```ruby
args = {
identifier: "subscription-identifier",
expirationDateTime: "2024-08-08T12:00:00.0000000Z"
}

irb(main):005:0> subscription = client.renew_subscription(args)
```

will return the subscription object `Office365::Models::Subscription`


## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
Expand Down
1 change: 1 addition & 0 deletions lib/office365/models.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ module Models
autoload :Contact, "office365/models/contact"
autoload :AccessToken, "office365/models/access_token"
autoload :Event, "office365/models/event"
autoload :Subscription, "office365/models/subscription"
end
end
8 changes: 8 additions & 0 deletions lib/office365/models/subscription.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

module Office365
module Models
class Subscription < Base
end
end
end
2 changes: 2 additions & 0 deletions lib/office365/rest/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
require_relative "./calendar"
require_relative "./contact"
require_relative "./event"
require_relative "./subscription"
require_relative "./token"

module Office365
Expand All @@ -16,6 +17,7 @@ module API
include Office365::REST::Event
include Office365::REST::Contact
include Office365::REST::Token
include Office365::REST::Subscription
end
end
end
9 changes: 7 additions & 2 deletions lib/office365/rest/concerns/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ module Base
private

def wrap_results(args)
kclass = args.delete(:kclass)
response = get_request(args: args)
kclass = args.delete(:kclass)
identifier = args.delete(:identifier)

response = get_request(args: args)

# If we are getting a single item by id, return the result as an array
return { results: [kclass.new(response)].flatten } unless identifier.nil?

{
results: response["value"].map { |v| kclass.new(v) },
Expand Down
9 changes: 8 additions & 1 deletion lib/office365/rest/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,18 @@ module Office365
module REST
module Event
include Concerns::Base
BASE_URI = "/me/events"

# params: args => { next_link: (nil / next_page_url) }
# response { results: [], next_link: '...' }
def events(args = {})
wrap_results(args.merge(kclass: Models::Event, base_uri: "/me/events"))
wrap_results(args.merge(kclass: Models::Event, base_uri: BASE_URI))
end

def event(identifier)
raise ArgumentError, "Identifier must be provided" if identifier.nil? || identifier.empty?

wrap_results(kclass: Models::Event, base_uri: [BASE_URI, identifier].join("/"), identifier: identifier)
end
end
end
Expand Down
26 changes: 19 additions & 7 deletions lib/office365/rest/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,35 @@ def get(uri, args: {})
end

def post(uri, args)
req_url = URI(uri.start_with?("https") ? uri : (Office365::API_HOST + uri))
response = faraday_action(__method__, uri, args)
parse_respond(response)
end

response = Faraday.new(url: [req_url.scheme, "://", req_url.hostname].join, headers: post_headers) do |faraday|
faraday.adapter Faraday.default_adapter
faraday.response :json
faraday.response :logger, ::Logger.new($stdout), bodies: true if dev_developement?
end.post(req_url.request_uri, args.ms_hash_to_query)
def patch(uri, args)
response = faraday_action(__method__, uri, args)

parse_respond(response)
end

private

def faraday_action(method_name, uri, args)
req_url = URI(uri.start_with?("https") ? uri : (Office365::API_HOST + uri))
json_header = args.delete(:json_header)

faraday = Faraday.new(url: [req_url.scheme, "://", req_url.hostname].join, headers: json_header ? headers : post_headers) do |f|
f.adapter Faraday.default_adapter
f.response :json
f.response :logger, ::Logger.new($stdout), bodies: true if dev_developement?
end

faraday.send(method_name, req_url.request_uri, json_header ? args.to_json : args.ms_hash_to_query)
end

def parse_respond(response)
resp_body = response.body

return resp_body if response.status == 200
return resp_body if [200, 201].include?(response.status)

raise InvaliRequestError, resp_body["error_description"] if response.status == 400
raise InvalidAuthenticationTokenError, resp_body.dig("error", "message") if response.status == 401
Expand Down
29 changes: 29 additions & 0 deletions lib/office365/rest/subscription.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

module Office365
module REST
module Subscription
def create_subscription(args = {})
raise ArgumentError, "Missing changeType" if args[:changeType].nil?
raise ArgumentError, "Missing notificationUrl" if args[:notificationUrl].nil?
raise ArgumentError, "Missing resource" if args[:resource].nil?
raise ArgumentError, "Missing expirationDateTime" if args[:expirationDateTime].nil?
raise ArgumentError, "Missing clientState" if args[:clientState].nil?

Models::Subscription.new(
Request.new(access_token, debug: debug).post("/v1.0/subscriptions", { json_header: true }.merge(args))
)
end

def renew_subscription(args = {})
raise ArgumentError, "Missing subscription identifier" if args[:identifier].nil?

identifier = args.delete(:identifier)

Models::Subscription.new(
Request.new(access_token, debug: debug).patch("/v1.0/subscriptions/#{identifier}", { json_header: true }.merge(args))
)
end
end
end
end
49 changes: 49 additions & 0 deletions spec/fixtures/vcr_cassettes/office365_create_subscription.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

87 changes: 87 additions & 0 deletions spec/fixtures/vcr_cassettes/office365_event_by_id.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 47 additions & 0 deletions spec/fixtures/vcr_cassettes/office365_renew_subscription.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 4a2c698

Please sign in to comment.