typeform_data 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -10
- data/lib/typeform_data/typeform.rb +11 -4
- data/lib/typeform_data/value_class.rb +5 -3
- data/lib/typeform_data/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acb9391db4cf1a80933452517bebcbfbfd888eda
|
4
|
+
data.tar.gz: e140a1e7dd8928725bfa115ef5d883a44e71c708
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cceb10daaf8beed9ed861b33b4de0ba44babe9b4ad00e29be85df4d72244d59dcd72d1cef7b8cef98cc0c86ed6e0212065377bd564360a81bd102f18d65f5785
|
7
|
+
data.tar.gz: ae4c2c7c404363b35b49cb575bdf2a87fde5ced318a77cbabdbea807d484b29a6ff2495bc330229de0d7e090d12bc15f9ee95cb2e30186e989444ba8be6399bb
|
data/README.md
CHANGED
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
A Ruby client for Typeform's [Data API](https://www.typeform.com/help/data-api/). Our documentation is available [here](http://www.rubydoc.info/gems/typeform_data/TypeformData/Typeform).
|
4
4
|
|
5
|
-
**Warning**: this is alpha software, and hasn't been thoroughly vetted in production yet. Use at your own risk :).
|
6
|
-
|
7
5
|
## Usage:
|
8
6
|
|
9
7
|
```
|
@@ -27,8 +25,6 @@ Unless you specify a limit, `TypeformData::Typeform#responses` will not paginate
|
|
27
25
|
|
28
26
|
You can also specify any of the ["Filtering Options"](https://www.typeform.com/help/data-api/) to pass along to the API call:
|
29
27
|
|
30
|
-
(*Warning*: the `token` parameter isn't working yet.)
|
31
|
-
|
32
28
|
```
|
33
29
|
some_complete_responses = typeform.responses(limit: 500, offset: 2000, completed: true)
|
34
30
|
two_days_of_responses = typeform.responses(from: 1470143917, since: 1470316722)
|
@@ -37,7 +33,7 @@ two_days_of_responses = typeform.responses(from: 1470143917, since: 1470316722)
|
|
37
33
|
|
38
34
|
### Questions & answers
|
39
35
|
|
40
|
-
The response data you get back is represented using classes with defined relationships
|
36
|
+
The response data you get back is represented using classes with defined relationships. All `TypeformData::*` objects should be treated as immutable.
|
41
37
|
|
42
38
|
```
|
43
39
|
typeform.responses.first.answers.first.typeform == typeform
|
@@ -46,7 +42,7 @@ typeform.responses.first.answers.first.typeform == typeform
|
|
46
42
|
typeform.fields.map(&:text)
|
47
43
|
=> ["What is your name?", "What are your favorite colors?", ...]
|
48
44
|
|
49
|
-
typeform.responses.first.answers.map { |answer| [answer.field_text, answer.value] }
|
45
|
+
typeform.responses.first.answers.map { |answer| [answer.field_text, answer.value] }
|
50
46
|
=> [["What is your name?", "Foo Bar"], ["What are your favorite colors?", ["blue", "orange"]]]
|
51
47
|
|
52
48
|
```
|
@@ -55,18 +51,18 @@ To access a Typeform's questions, we recommend using `TypeformData::Typeform#fie
|
|
55
51
|
|
56
52
|
## Notes on the API
|
57
53
|
|
58
|
-
So far, we've found Typeform's current Data API to be confusing. In particular, there are a couple design decisions that have been a
|
54
|
+
So far, we've found Typeform's current Data API to be confusing. In particular, there are a couple design decisions that have been a source of friction for us:
|
59
55
|
|
60
56
|
- Statements (which are sections of text in a Typeform, and can't be answered) and Hidden Fields (data passed into a form, and not provided by the user) are both included under the `'questions'` key in the API's response JSON. From the perspective of a user, we don't think of these as "questions".
|
61
57
|
- Each option in a "Picture choice" (and, IIRC "Multiple choice" as well, if multiple choices are allowed) is returned as its own "question" in the response JSON for questions and answers. We feel that it makes more sense to model these as multiple answers to one question, i.e. an Array-valued answer.
|
62
58
|
|
63
|
-
The main goal of this API wrapper is to encapsulate these implementation details
|
59
|
+
The main goal of this API wrapper is to encapsulate these implementation details and provide a more intuitive API for our application code. This means that our data model must deviate in specific places from the implicit data model expressed in the Data API's JSON responses. We're sacrificing consistency for a more intuitive client API.
|
64
60
|
|
65
61
|
## Notes
|
66
62
|
|
67
|
-
- We haven't tested against any Ruby versions other than 2.3.
|
68
63
|
- At the moment, this gem has no runtime dependencies.
|
69
|
-
-
|
64
|
+
- We've only tested this gem against Ruby 2.3. I'm not sure whether it works with older versions.
|
65
|
+
- Under the hood, the object relationships are implemented by storing a reference to a config object containing your API key. This is what allows you to say `answer.typeform.responses` and ultimately make an API call originating from a `TypeformData::Typeform::Answer` without having to pass in a reference to a client or your API key (again). To avoid leaking your API key, make sure to clear out the `@config` reference if you add functionality to serialize any of the objects! We've already done some work here: if you call `Marshal.dump` on a `TypeformData::ValueClass`, we only serialize attributes, and not the `@config` object.
|
70
66
|
|
71
67
|
### Installation
|
72
68
|
|
@@ -63,10 +63,10 @@ module TypeformData
|
|
63
63
|
@_stats ||= fetch_stats
|
64
64
|
end
|
65
65
|
|
66
|
-
# This method will make an AJAX request if this Typeform's name hasn't already been set
|
66
|
+
# This method will make an AJAX request if this Typeform's name hasn't already been set during
|
67
|
+
# initialization.
|
67
68
|
# @return [String]
|
68
69
|
def name
|
69
|
-
return name if name
|
70
70
|
@name ||= client.all_typeforms.find { |typeform| typeform.id == id }.name
|
71
71
|
end
|
72
72
|
|
@@ -121,7 +121,7 @@ module TypeformData
|
|
121
121
|
@_questions = questions_hashes.map { |hash| Question.new(config, hash) }
|
122
122
|
end
|
123
123
|
|
124
|
-
# @param Hash stats_hash of the form {"responses"=>{"showing"=>2, "total"=>2, "completed"=>0}}
|
124
|
+
# @param [Hash] stats_hash of the form {"responses"=>{"showing"=>2, "total"=>2, "completed"=>0}}
|
125
125
|
def set_stats(hash)
|
126
126
|
@_stats = Stats.new(config, hash)
|
127
127
|
end
|
@@ -155,7 +155,14 @@ module TypeformData
|
|
155
155
|
"provided: #{params['limit']}"
|
156
156
|
end
|
157
157
|
|
158
|
-
params['
|
158
|
+
if params['token']
|
159
|
+
if params.keys.length > 1
|
160
|
+
raise ::TypeformData::ArgumentError, "'token' may not be combined with other filters"
|
161
|
+
end
|
162
|
+
else
|
163
|
+
params['offset'] ||= 0
|
164
|
+
end
|
165
|
+
|
159
166
|
params
|
160
167
|
end
|
161
168
|
|
@@ -13,9 +13,11 @@ module TypeformData
|
|
13
13
|
keys = attribute_keys
|
14
14
|
|
15
15
|
attrs.each do |key, value|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
# Previously, we would throw an error if an unexpected attribute was present. Unfortunately,
|
17
|
+
# this causes exceptions in production if Typeform adds new fields to their API responses.
|
18
|
+
# We could filter the fields to the expected keys, but that defeats the purpose of having
|
19
|
+
# the validation.
|
20
|
+
next unless keys.include?(key) || keys.include?(key.to_sym)
|
19
21
|
instance_variable_set("@#{key}", value)
|
20
22
|
end
|
21
23
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typeform_data
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Max Wallace
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|