caren-api 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -2,14 +2,37 @@
2
2
 
3
3
  This is the reference implementation for the Caren CareProvider API (http://caren-cares.com).
4
4
 
5
- To get started you will need a care provider API shared key. Set `Caren::Api.shared_key` to the key file.
5
+ == Getting started
6
6
 
7
- Generate a private key using: `openssl genrsa -out example 1024`
8
- Then extract the public key from it: `openssl rsa -in example -pubout -out example.pub`
9
- Send the public key to info@caren-cares.com with an access request.
7
+ To get started you will need a care provider API private/public keypair.
10
8
 
11
- Next you will need to set your care provider url `Caren::Api.url` to your specific URL like https://example.caren-cares.com.
12
- This url will be provided.
9
+ * Generate a private key using: `openssl genrsa -out example 1024`
10
+ * Extract the public key from it: `openssl rsa -in example -pubout -out example.pub`
11
+ * Send the public key to info@caren-cares.com with an access request.
12
+ * Set your care provider url `Caren::Api.url` to the provided URL like https://example.caren-cares.com.
13
+
14
+ == Getting information from Caren
15
+
16
+ This implementation shows you how to get information from Caren. You can gather information about Links (linking your people to caren's),
17
+ care_providers (including updating your settings) and external_messages (chat messages between you and caren people).
18
+
19
+ == Providing information to Caren
20
+
21
+ Some information you can push to Caren (like updates to care_provider settings and new messages) using the basic API.
22
+ Additionally Caren requires you to provide XML resources for People (search) and Events (daterange).
23
+ You can specify your API base url within your care_provider settings. You are required to implement the following resources:
24
+
25
+ * Finding a person by identifier: GET [BASE_URL]/people/?uid=[VALUE]
26
+ * Finding a list of events for a given person: GET [BASE_URL]/people/[EXTERNAL_ID]/events?from=[DATE]&to=[DATE]
27
+
28
+ The uid is your public customer number for this person, the external_id is your internal identifier (usually database id) for this person.
29
+ These urls should yield Caren compatible XML (the included Caren objects for Event and Person can generate that for you)
30
+
31
+ == Push notifications of changes from Caren
32
+
33
+ Caren supports a push link. Caren will regularly post a XML file with changes (Links, CareProviders, ExternalMessages) to any url.
34
+ Passing this XML and the corresponsing header signature into `Caren::Api.incoming` will yield the updated Caren objects.
35
+ You can optionally specify a push url within your care_provider settings.
13
36
 
14
37
  == Contributing to caren-api
15
38
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
data/caren-api.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{caren-api}
8
- s.version = "0.2.0"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andre Foeken"]
@@ -50,6 +50,7 @@ Gem::Specification.new do |s|
50
50
  "spec/fixtures/caren_links.xml",
51
51
  "spec/fixtures/caren_links_search.xml",
52
52
  "spec/fixtures/caren_unauthorized.xml",
53
+ "spec/fixtures/incoming.xml",
53
54
  "spec/link_spec.rb",
54
55
  "spec/person_spec.rb",
55
56
  "spec/spec.opts",
data/lib/caren/base.rb CHANGED
@@ -11,8 +11,10 @@ class Caren::Base
11
11
  self.class.keys.each do |key|
12
12
  self.attributes[key] = args[key] || args[key.to_s] || nil
13
13
  end
14
+ # We want to use #id
15
+ self.instance_eval('undef id')
14
16
  end
15
-
17
+
16
18
  # List of available attributes for this object
17
19
  def self.keys
18
20
  []
@@ -5,7 +5,7 @@
5
5
  class Caren::CareProvider < Caren::Base
6
6
 
7
7
  def self.keys
8
- [ :caren_id, # String (The id of this CP inside Caren)
8
+ [ :id, # String (The id of this CP inside Caren)
9
9
  :name, # String
10
10
  :telephone, # String
11
11
  :website, # String
@@ -19,7 +19,9 @@ class Caren::CareProvider < Caren::Base
19
19
  :max_start, # String (23:00)
20
20
  :min_start, # String (07:00)
21
21
  :show_employee_name_as_title, # Boolean
22
- :communication # Boolean
22
+ :communication, # Boolean
23
+ :push_hook_url, # String (Optional url to push api acceptor)
24
+ :api_url # String (Required url to api resources)
23
25
  ]
24
26
  end
25
27
 
@@ -32,11 +34,11 @@ class Caren::CareProvider < Caren::Base
32
34
  end
33
35
 
34
36
  def update
35
- Caren::Api.put(self.resource_url(self.caren_id), self.to_xml)
37
+ Caren::Api.put(self.resource_url(self.id), self.to_xml)
36
38
  end
37
39
 
38
40
  def update_logo logo_hash_or_path
39
- Caren::Api.put(self.resource_url(self.caren_id), self.to_logo_xml(logo_hash_or_path))
41
+ Caren::Api.put(self.resource_url(self.id), self.to_logo_xml(logo_hash_or_path))
40
42
  end
41
43
 
42
44
  def as_xml
data/lib/caren/caren.rb CHANGED
@@ -76,6 +76,28 @@ module Caren
76
76
  end
77
77
  end
78
78
 
79
+ # These types of Caren objects are supported by the Caren::Api.incoming method
80
+ def self.supported_incoming_objects
81
+ { :links => Caren::Link,
82
+ :external_messages => Caren::ExternalMessage,
83
+ :care_providers => Caren::CareProvider
84
+ }
85
+ end
86
+
87
+ # Pass an XML string to be handled. Only a valid caren_objects xml hash will be parsed.
88
+ def self.incoming xml, signature
89
+ if self.verify_signature(signature,xml)
90
+ objects = []
91
+ hash = Hash.from_xml(xml)["caren_objects"]
92
+ self.supported_incoming_objects.each do |key,klass|
93
+ objects << (hash[key]||hash[key.to_s]||[]).map{ |h| klass.new(h) }
94
+ end
95
+ return objects.flatten
96
+ else
97
+ raise Caren::Exceptions::SignatureMismatch.new
98
+ end
99
+ end
100
+
79
101
  # Sign your string using Caren::Api.private_key
80
102
  def self.sign string=""
81
103
  encrypted_digest = Caren::Api.private_key.sign( "sha1", string )
@@ -1,12 +1,13 @@
1
1
  class Caren::ExternalMessage < Caren::Base
2
2
 
3
3
  def self.keys
4
- [ :caren_id, # String (Caren message id)
4
+ [ :id, # String (Caren message id)
5
5
  :person_name, # String (Andre Foeken)
6
- :external_person_id, # String (Your person id)
6
+ :external_person_id, # String (Your person id)
7
7
  :body, # Text
8
8
  :external_id, # String (Your message id)
9
9
  :in_reply_to_id, # Integer (Caren message id)
10
+ :in_reply_to_type, # The type of message this is a reply to. (Always ExternalMessage if reply is set)
10
11
  :subject_id # Integer (Caren person id)
11
12
  ]
12
13
  end
@@ -16,7 +17,7 @@ class Caren::ExternalMessage < Caren::Base
16
17
  end
17
18
 
18
19
  def delete
19
- Caren::Api.delete self.class.resource_url(self.subject_id,self.caren_id)
20
+ Caren::Api.delete self.class.resource_url(self.subject_id,self.id)
20
21
  end
21
22
 
22
23
  def self.array_root
data/lib/caren/link.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  class Caren::Link < Caren::Base
2
2
 
3
3
  def self.keys
4
- [:person_name, # String (Caren person name)
4
+ [:id, # String (Caren id)
5
+ :person_name, # String (Caren person name)
5
6
  :person_id, # String (Caren person id)
6
7
  :person_photo, # String (url of photo)
7
8
  :patient_number, # String (12345)
@@ -83,11 +83,11 @@ describe "CareProvider", "REST methods" do
83
83
  end
84
84
 
85
85
  it "should be able to update a care provider" do
86
- lambda{ Caren::CareProvider.new( :caren_id => 1, :name => "Test" ).update }.should_not raise_error
86
+ lambda{ Caren::CareProvider.new( :id => 1, :name => "Test" ).update }.should_not raise_error
87
87
  end
88
88
 
89
89
  it "should be able to update the logo for a care provider" do
90
- lambda{ Caren::CareProvider.new( :caren_id => 1 ).update_logo( "spec/fixtures/bacon.jpg" ) }.should_not raise_error
90
+ lambda{ Caren::CareProvider.new( :id => 1 ).update_logo( "spec/fixtures/bacon.jpg" ) }.should_not raise_error
91
91
  end
92
92
 
93
93
  it "should be able to search for a specific care provider" do
data/spec/caren_spec.rb CHANGED
@@ -71,4 +71,14 @@ describe "Caren", "signature checks" do
71
71
  end
72
72
  end
73
73
 
74
+ it "should be able to handle incoming xml from caren" do
75
+ incoming = File.read "spec/fixtures/incoming.xml"
76
+ results = Caren::Api.incoming(incoming, Caren::Api.sign(incoming))
77
+ results.should have(4).things
78
+ external_messages = results.select{ |x| x.is_a?(Caren::ExternalMessage) }
79
+ external_messages.first.id.should == 1
80
+ links = results.select{ |x| x.is_a?(Caren::Link) }
81
+ links.last.id.should == 3
82
+ end
83
+
74
84
  end
@@ -42,7 +42,7 @@ describe "ExternalMessage", "REST methods" do
42
42
  end
43
43
 
44
44
  it "should be able to delete an external message" do
45
- lambda{ Caren::ExternalMessage.new( :subject_id => 1, :caren_id => 1 ).delete }.should_not raise_error
45
+ lambda{ Caren::ExternalMessage.new( :subject_id => 1, :id => 1 ).delete }.should_not raise_error
46
46
  end
47
47
 
48
48
  end
@@ -0,0 +1,54 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <caren_objects type="hash">
3
+ <external-messages type="array">
4
+ <external-message>
5
+ <created-at type="datetime">2011-09-09T15:14:13+02:00</created-at>
6
+ <body>Expecting this to work somehow ...</body>
7
+ <updated-at type="datetime">2011-09-09T15:14:13+02:00</updated-at>
8
+ <in-reply-to-id type="integer" nil="true"></in-reply-to-id>
9
+ <subject-id type="integer">5</subject-id>
10
+ <id type="integer">1</id>
11
+ <in-reply-to-type nil="true"></in-reply-to-type>
12
+ <care-provider-id type="integer">1</care-provider-id>
13
+ <person-id type="integer">2</person-id>
14
+ <person-first-name>Matthijs Langenberg</person-first-name>
15
+ <person-last-name></person-last-name>
16
+ <person-photo>http://example.com/1.png</person-photo>
17
+ </external-message>
18
+ </external-messages>
19
+ <links type="array">
20
+ <link>
21
+ <created-at type="datetime">2011-10-10T10:38:49+02:00</created-at>
22
+ <updated-at type="datetime">2011-10-10T10:40:35+02:00</updated-at>
23
+ <id type="integer">1</id>
24
+ <care-provider-id type="integer">1</care-provider-id>
25
+ <person-id type="integer">3</person-id>
26
+ <person-name>Andre Foeken</person-name>
27
+ <person-photo>http://example.com/1.png</person-photo>
28
+ <external-id>1</external-id>
29
+ <status>confirmed</status>
30
+ </link>
31
+ <link>
32
+ <created-at type="datetime">2011-10-10T10:42:42+02:00</created-at>
33
+ <updated-at type="datetime">2011-10-10T10:53:07+02:00</updated-at>
34
+ <id type="integer">2</id>
35
+ <care-provider-id type="integer">1</care-provider-id>
36
+ <person-id type="integer">3</person-id>
37
+ <person-name>Andre Foeken</person-name>
38
+ <person-photo>http://example.com/1.png</person-photo>
39
+ <external-id>2</external-id>
40
+ <status>confirmed</status>
41
+ </link>
42
+ <link>
43
+ <created-at type="datetime">2011-10-10T11:05:28+02:00</created-at>
44
+ <updated-at type="datetime">2011-10-10T11:06:44+02:00</updated-at>
45
+ <id type="integer">3</id>
46
+ <care-provider-id type="integer">1</care-provider-id>
47
+ <person-id type="integer">3</person-id>
48
+ <person-name>Andre Foeken</person-name>
49
+ <person-photo>http://example.com/1.png</person-photo>
50
+ <external-id>3</external-id>
51
+ <status>confirmed</status>
52
+ </link>
53
+ </links>
54
+ </caren_objects>
data/spec/link_spec.rb CHANGED
@@ -34,6 +34,7 @@ describe "Link", "REST methods" do
34
34
  it "should be find all links using the API" do
35
35
  links = Caren::Link.all
36
36
  links.should have(3).things
37
+ links.first.id.should == 1
37
38
  links.first.status.should == "confirmed"
38
39
  links.first.external_id.should == "1"
39
40
  links.first.person_name.should == "Andre Foeken"
metadata CHANGED
@@ -4,10 +4,10 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
7
+ - 3
8
8
  - 0
9
9
  segments_generated: true
10
- version: 0.2.0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andre Foeken
@@ -191,6 +191,7 @@ files:
191
191
  - spec/fixtures/caren_links.xml
192
192
  - spec/fixtures/caren_links_search.xml
193
193
  - spec/fixtures/caren_unauthorized.xml
194
+ - spec/fixtures/incoming.xml
194
195
  - spec/link_spec.rb
195
196
  - spec/person_spec.rb
196
197
  - spec/spec.opts