amplitude-api 0.0.10 → 0.3.2
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 +5 -5
- data/.gitignore +2 -1
- data/.rubocop.yml +32 -0
- data/.travis.yml +2 -3
- data/Changelog.md +41 -0
- data/Gemfile +9 -7
- data/Gemfile.lock +48 -43
- data/Rakefile +7 -5
- data/amplitude-api.gemspec +17 -16
- data/lib/amplitude-api.rb +3 -4
- data/lib/amplitude_api.rb +99 -40
- data/lib/amplitude_api/config.rb +52 -0
- data/lib/amplitude_api/event.rb +124 -89
- data/lib/amplitude_api/identification.rb +4 -2
- data/lib/amplitude_api/version.rb +3 -1
- data/readme.md +53 -4
- data/spec/lib/amplitude_api/event_spec.rb +236 -90
- data/spec/lib/amplitude_api/identification_spec.rb +19 -17
- data/spec/lib/amplitude_api_spec.rb +388 -189
- data/spec/spec_helper.rb +7 -4
- metadata +30 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 275373a4c26fc2028070205735f535ab9411dad8c98986c1dae0793e44098106
|
4
|
+
data.tar.gz: 5d79d4ff3ebc1218f5ce1ddff49fc5c323b250862db1e4c4e5136f76c3eb6f1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af5c1085ae807de968a2737ec4eab0da585baca1596ac38caed7960b457d854d7e83e4a0fa0fbf9826164239891d047fbc0e3e1801104696e5323fd05f0e3b7c
|
7
|
+
data.tar.gz: 12817cbd4e8929d02cea2b2499bbe309d459fcc1388e9b70003503e6d3df00e974185342bfae02e9d61cdf5d8b4af296616af1dc720db42f91a456b56f70452c
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,3 +1,35 @@
|
|
1
1
|
require: rubocop-rspec
|
2
|
+
|
3
|
+
AllCops:
|
4
|
+
TargetRubyVersion: 2.4
|
5
|
+
|
2
6
|
Metrics/LineLength:
|
3
7
|
Max: 120
|
8
|
+
|
9
|
+
Style/StringLiterals:
|
10
|
+
EnforcedStyle: double_quotes
|
11
|
+
SupportedStyles:
|
12
|
+
- single_quotes
|
13
|
+
- double_quotes
|
14
|
+
|
15
|
+
Style/BlockDelimiters:
|
16
|
+
Enabled: true
|
17
|
+
Exclude:
|
18
|
+
- spec/**/*
|
19
|
+
|
20
|
+
# Disable some failing rspec cops that fail from upgrading gems until we can clean things up a bit.
|
21
|
+
Naming/FileName:
|
22
|
+
Exclude:
|
23
|
+
- lib/amplitude-api.rb
|
24
|
+
RSpec/ExampleLength:
|
25
|
+
Enabled: false
|
26
|
+
Metrics/BlockLength:
|
27
|
+
Enabled: false
|
28
|
+
RSpec/MultipleExpectations:
|
29
|
+
Enabled: false
|
30
|
+
RSpec/NestedGroups:
|
31
|
+
Enabled: false
|
32
|
+
RSpec/MessageSpies:
|
33
|
+
Enabled: false
|
34
|
+
RSpec/ContextWording:
|
35
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/Changelog.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Amplitude API Changelog
|
2
|
+
|
3
|
+
We would like to think our many [contributors](https://github.com/toothrot/amplitude-api/graphs/contributors) for
|
4
|
+
suggestions, ideas and improvements to Amplitude API.
|
5
|
+
|
6
|
+
## 0.3.2 (2021-02-23)
|
7
|
+
* Creates new properties on initialization
|
8
|
+
|
9
|
+
## 0.3.1 (2021-02-23)
|
10
|
+
* Allows sending options to Amplitude
|
11
|
+
* Solves an error when accessing event properties not been created yet
|
12
|
+
|
13
|
+
## 0.3.0 (2021-02-22)
|
14
|
+
|
15
|
+
* Changes Typhoeus to Faraday to launch requests (**breaking change**)
|
16
|
+
* Adds new API fields to Event
|
17
|
+
* Event can now include arbitrary properties, so it could be used if the API adds new ones.
|
18
|
+
|
19
|
+
## 0.2.0 (2021-02-14)
|
20
|
+
|
21
|
+
* Updates gem to use HTTP API V2.
|
22
|
+
|
23
|
+
## 0.1.1 (2019-01-01)
|
24
|
+
|
25
|
+
* Fix #41 - Delete API now correctly handles Arrays of IDs.
|
26
|
+
|
27
|
+
## 0.1.0 (2019-01-01)
|
28
|
+
|
29
|
+
* Update Gem dependencies (thanks @kolorahl, @itamar, @krettan)
|
30
|
+
* Minimum ruby version is now 2.2
|
31
|
+
* Support Delete API (thanks @samjohn)
|
32
|
+
* Fix bundle Inline (thanks @jonduarte)
|
33
|
+
* Many fixes from @kolorahl
|
34
|
+
|
35
|
+
## 0.0.10 (2017-09-13)
|
36
|
+
|
37
|
+
* Allow to use "Event Segmentation" via API ([#23](https://github.com/toothrot/amplitude-api/pull/23)).
|
38
|
+
|
39
|
+
## Older releases
|
40
|
+
|
41
|
+
Please see the v0.0.9 tag.
|
data/Gemfile
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Generated from /Users/alex/development/amplitude-api/amplitude-api.gemspec
|
2
|
-
source
|
4
|
+
source "https://rubygems.org"
|
3
5
|
|
4
|
-
gem
|
6
|
+
gem "faraday", "~> 1.3"
|
5
7
|
|
6
8
|
group :development, :test do
|
7
|
-
gem
|
8
|
-
gem
|
9
|
-
gem
|
10
|
-
gem
|
11
|
-
gem
|
9
|
+
gem "pry", "~> 0.12.2"
|
10
|
+
gem "rake", ">= 12.0"
|
11
|
+
gem "rspec", ">= 2.99.0"
|
12
|
+
gem "rubocop", "~> 0.66.0", require: false
|
13
|
+
gem "rubocop-rspec"
|
12
14
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,58 +1,63 @@
|
|
1
1
|
GEM
|
2
2
|
remote: https://rubygems.org/
|
3
3
|
specs:
|
4
|
-
ast (2.
|
5
|
-
coderay (1.1.
|
6
|
-
diff-lcs (1.
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
rspec
|
25
|
-
rspec-
|
26
|
-
|
4
|
+
ast (2.4.0)
|
5
|
+
coderay (1.1.2)
|
6
|
+
diff-lcs (1.3)
|
7
|
+
faraday (1.3.0)
|
8
|
+
faraday-net_http (~> 1.0)
|
9
|
+
multipart-post (>= 1.2, < 3)
|
10
|
+
ruby2_keywords
|
11
|
+
faraday-net_http (1.0.1)
|
12
|
+
jaro_winkler (1.5.2)
|
13
|
+
method_source (0.9.2)
|
14
|
+
multipart-post (2.1.1)
|
15
|
+
parallel (1.17.0)
|
16
|
+
parser (2.6.2.0)
|
17
|
+
ast (~> 2.4.0)
|
18
|
+
pry (0.12.2)
|
19
|
+
coderay (~> 1.1.0)
|
20
|
+
method_source (~> 0.9.0)
|
21
|
+
psych (3.1.0)
|
22
|
+
rainbow (3.0.0)
|
23
|
+
rake (12.3.3)
|
24
|
+
rspec (3.8.0)
|
25
|
+
rspec-core (~> 3.8.0)
|
26
|
+
rspec-expectations (~> 3.8.0)
|
27
|
+
rspec-mocks (~> 3.8.0)
|
28
|
+
rspec-core (3.8.0)
|
29
|
+
rspec-support (~> 3.8.0)
|
30
|
+
rspec-expectations (3.8.2)
|
27
31
|
diff-lcs (>= 1.2.0, < 2.0)
|
28
|
-
rspec-support (~> 3.
|
29
|
-
rspec-mocks (3.
|
32
|
+
rspec-support (~> 3.8.0)
|
33
|
+
rspec-mocks (3.8.0)
|
30
34
|
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
-
rspec-support (~> 3.
|
32
|
-
rspec-support (3.
|
33
|
-
rubocop (0.
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
rspec-support (~> 3.8.0)
|
36
|
+
rspec-support (3.8.0)
|
37
|
+
rubocop (0.66.0)
|
38
|
+
jaro_winkler (~> 1.5.1)
|
39
|
+
parallel (~> 1.10)
|
40
|
+
parser (>= 2.5, != 2.5.1.1)
|
41
|
+
psych (>= 3.1.0)
|
42
|
+
rainbow (>= 2.2.2, < 4.0)
|
37
43
|
ruby-progressbar (~> 1.7)
|
38
|
-
unicode-display_width (
|
39
|
-
rubocop-rspec (1.
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
unicode-display_width (0.3.1)
|
44
|
+
unicode-display_width (>= 1.4.0, < 1.6)
|
45
|
+
rubocop-rspec (1.32.0)
|
46
|
+
rubocop (>= 0.60.0)
|
47
|
+
ruby-progressbar (1.10.0)
|
48
|
+
ruby2_keywords (0.0.4)
|
49
|
+
unicode-display_width (1.5.0)
|
45
50
|
|
46
51
|
PLATFORMS
|
47
52
|
ruby
|
48
53
|
|
49
54
|
DEPENDENCIES
|
50
|
-
|
51
|
-
|
55
|
+
faraday (~> 1.3)
|
56
|
+
pry (~> 0.12.2)
|
57
|
+
rake (>= 12.0)
|
52
58
|
rspec (>= 2.99.0)
|
53
|
-
rubocop (~> 0.
|
59
|
+
rubocop (~> 0.66.0)
|
54
60
|
rubocop-rspec
|
55
|
-
typhoeus (~> 1.0.2)
|
56
61
|
|
57
62
|
BUNDLED WITH
|
58
|
-
1.
|
63
|
+
1.17.3
|
data/Rakefile
CHANGED
@@ -1,14 +1,16 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rubocop/rake_task"
|
3
5
|
|
4
6
|
RuboCop::RakeTask.new
|
5
7
|
|
6
8
|
begin
|
7
|
-
require
|
9
|
+
require "rspec/core/rake_task"
|
8
10
|
RSpec::Core::RakeTask.new(:spec)
|
9
11
|
rescue LoadError
|
10
|
-
puts
|
12
|
+
puts "Unable to load rspec. Have you run `bundle install`?"
|
11
13
|
end
|
12
14
|
|
13
15
|
task(:default).clear
|
14
|
-
task default: [
|
16
|
+
task default: ["rubocop:auto_correct", :spec]
|
data/amplitude-api.gemspec
CHANGED
@@ -1,26 +1,27 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
5
|
+
require "amplitude_api/version"
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
8
|
+
spec.name = "amplitude-api"
|
8
9
|
spec.version = AmplitudeAPI::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
10
|
+
spec.authors = ["Alex Rakoczy"]
|
11
|
+
spec.email = ["arakoczy@gmail.com"]
|
12
|
+
spec.summary = "Send events to the Amplitude API"
|
13
|
+
spec.description = "Provides an integration for sending events to Amplitude"
|
14
|
+
spec.homepage = "https://github.com/toothrot/amplitude-api"
|
15
|
+
spec.license = "MIT"
|
15
16
|
|
16
17
|
spec.files = `git ls-files -z`.split("\x0")
|
17
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
20
|
+
spec.require_paths = ["lib"]
|
20
21
|
|
21
|
-
spec.add_development_dependency
|
22
|
-
spec.add_development_dependency
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_dependency
|
25
|
-
spec.required_ruby_version =
|
22
|
+
spec.add_development_dependency "pry", "~> 0.12.2"
|
23
|
+
spec.add_development_dependency "rake", "~> 12.0", ">= 12.0"
|
24
|
+
spec.add_development_dependency "rspec", "~> 2.99", ">= 2.99.0"
|
25
|
+
spec.add_dependency "faraday", "~> 1.3"
|
26
|
+
spec.required_ruby_version = ">= 2.4"
|
26
27
|
end
|
data/lib/amplitude-api.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
# Whoops.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "amplitude_api"
|
data/lib/amplitude_api.rb
CHANGED
@@ -1,25 +1,37 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
|
5
|
-
require_relative 'amplitude_api/identification'
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
require "faraday"
|
6
5
|
|
7
6
|
# AmplitudeAPI
|
8
7
|
class AmplitudeAPI
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
require_relative "amplitude_api/config"
|
9
|
+
require_relative "amplitude_api/event"
|
10
|
+
require_relative "amplitude_api/identification"
|
11
|
+
|
12
|
+
TRACK_URI_STRING = "https://api.amplitude.com/2/httpapi"
|
13
|
+
IDENTIFY_URI_STRING = "https://api.amplitude.com/identify"
|
14
|
+
SEGMENTATION_URI_STRING = "https://amplitude.com/api/2/events/segmentation"
|
15
|
+
DELETION_URI_STRING = "https://amplitude.com/api/2/deletions/users"
|
12
16
|
|
13
|
-
USER_WITH_NO_ACCOUNT = "user who doesn't have an account"
|
17
|
+
USER_WITH_NO_ACCOUNT = "user who doesn't have an account"
|
14
18
|
|
15
19
|
class << self
|
16
|
-
|
17
|
-
|
18
|
-
|
20
|
+
def config
|
21
|
+
Config.instance
|
22
|
+
end
|
19
23
|
|
20
|
-
|
21
|
-
|
22
|
-
|
24
|
+
def configure
|
25
|
+
yield config
|
26
|
+
end
|
27
|
+
|
28
|
+
def api_key
|
29
|
+
config.api_key
|
30
|
+
end
|
31
|
+
|
32
|
+
def secret_key
|
33
|
+
config.secret_key
|
34
|
+
end
|
23
35
|
|
24
36
|
# ==== Event Tracking related methods
|
25
37
|
|
@@ -28,12 +40,12 @@ class AmplitudeAPI
|
|
28
40
|
# @param [ String ] event_name a string that describes the event, e.g. "clicked on Home"
|
29
41
|
# @param [ String ] user a string or integer that uniquely identifies a user.
|
30
42
|
# @param [ String ] device a string that uniquely identifies the device.
|
31
|
-
# @
|
43
|
+
# @option options [ Hash ] event_properties a hash that is serialized to JSON,
|
32
44
|
# and can contain any other property to be stored on the Event
|
33
|
-
# @
|
45
|
+
# @option options [ Hash ] user_properties a hash that is serialized to JSON,
|
34
46
|
# and contains user properties to be associated with the user
|
35
47
|
#
|
36
|
-
# @return [
|
48
|
+
# @return [ Faraday::Response ]
|
37
49
|
def send_event(event_name, user, device, options = {})
|
38
50
|
event = AmplitudeAPI::Event.new(
|
39
51
|
user_id: user,
|
@@ -58,10 +70,13 @@ class AmplitudeAPI
|
|
58
70
|
def track_body(*events)
|
59
71
|
event_body = events.flatten.map(&:to_hash)
|
60
72
|
|
61
|
-
{
|
73
|
+
body = {
|
62
74
|
api_key: api_key,
|
63
|
-
|
75
|
+
events: event_body
|
64
76
|
}
|
77
|
+
body[:options] = config.options if config.options
|
78
|
+
|
79
|
+
JSON.generate(body)
|
65
80
|
end
|
66
81
|
|
67
82
|
# @overload track(event)
|
@@ -70,11 +85,11 @@ class AmplitudeAPI
|
|
70
85
|
# @overload track([events])
|
71
86
|
# @param [ Array<AmplitudeAPI::Event> ] Send an array of events in a single request to Amplitude
|
72
87
|
#
|
73
|
-
# @return [
|
88
|
+
# @return [ Faraday::Response ]
|
74
89
|
#
|
75
90
|
# Send one or more Events to the Amplitude API
|
76
91
|
def track(*events)
|
77
|
-
|
92
|
+
Faraday.post(TRACK_URI_STRING, track_body(events), "Content-Type" => "application/json")
|
78
93
|
end
|
79
94
|
|
80
95
|
# ==== Identification related methods
|
@@ -113,45 +128,89 @@ class AmplitudeAPI
|
|
113
128
|
# @overload identify([identifications])
|
114
129
|
# @param [ Array<AmplitudeAPI::Identify> ] Send an array of identifications in a single request to Amplitude
|
115
130
|
#
|
116
|
-
# @return [
|
131
|
+
# @return [ Faraday::Response ]
|
117
132
|
#
|
118
133
|
# Send one or more Identifications to the Amplitude Identify API
|
119
134
|
def identify(*identifications)
|
120
|
-
|
135
|
+
Faraday.post(IDENTIFY_URI_STRING, identify_body(identifications))
|
121
136
|
end
|
122
137
|
|
123
138
|
# ==== Event Segmentation related methods
|
124
139
|
|
125
140
|
# Get metrics for an event with segmentation.
|
126
141
|
#
|
127
|
-
# @param [ Hash ]
|
142
|
+
# @param [ Hash ] event a hash that defines event.
|
128
143
|
# @param [ Time ] start_time a start time.
|
129
144
|
# @param [ Time ] end_time a end time.
|
130
|
-
# @
|
145
|
+
# @option options [ String ] m a string that defines aggregate function.
|
131
146
|
# For non-property metrics: "uniques", "totals", "pct_dau", or "average" (default: "uniques").
|
132
147
|
# For property metrics: "histogram", "sums", or "value_avg"
|
133
148
|
# (note: a valid "group_by" value is required in parameter e).
|
134
|
-
# @
|
149
|
+
# @option options [ Integer ] i an integer that defines segmentation interval.
|
135
150
|
# Set to -300000, -3600000, 1, 7, or 30 for realtime, hourly, daily, weekly,
|
136
151
|
# and monthly counts, respectively (default: 1). Realtime segmentation is capped at 2 days,
|
137
152
|
# hourly segmentation is capped at 7 days, and daily at 365 days.
|
138
|
-
# @
|
139
|
-
# @
|
140
|
-
# @
|
153
|
+
# @option options [ Array ] s an array that defines segment definitions.
|
154
|
+
# @option options [ String ] g a string that defines property to group by.
|
155
|
+
# @option options [ Integer ] limit an integer that defines number of Group By values
|
141
156
|
# returned (default: 100). The maximum limit is 1000.
|
142
157
|
#
|
143
|
-
# @return [
|
144
|
-
def segmentation(
|
145
|
-
|
146
|
-
e:
|
147
|
-
m:
|
148
|
-
start: start_time.strftime(
|
149
|
-
end:
|
150
|
-
i:
|
151
|
-
s:
|
152
|
-
g:
|
158
|
+
# @return [ Faraday::Response ]
|
159
|
+
def segmentation(event, start_time, end_time, **options)
|
160
|
+
Faraday.get SEGMENTATION_URI_STRING, userpwd: "#{api_key}:#{secret_key}", params: {
|
161
|
+
e: event.to_json,
|
162
|
+
m: options[:m],
|
163
|
+
start: start_time.strftime("%Y%m%d"),
|
164
|
+
end: end_time.strftime("%Y%m%d"),
|
165
|
+
i: options[:i],
|
166
|
+
s: (options[:s] || []).map(&:to_json),
|
167
|
+
g: options[:g],
|
153
168
|
limit: options[:limit]
|
154
169
|
}.delete_if { |_, value| value.nil? }
|
155
170
|
end
|
171
|
+
|
172
|
+
# Delete a user from amplitude
|
173
|
+
#
|
174
|
+
# You must pass in either an array of user_ids or an array of amplitude_ids
|
175
|
+
#
|
176
|
+
# @param [ Array<String> ] (optional) the user_ids to delete
|
177
|
+
# based on your database
|
178
|
+
# @param [ Array<Integer> ] (optional) the amplitude_ids to delete
|
179
|
+
# based on the amplitude database
|
180
|
+
# @param [ String ] requester the email address of the person who
|
181
|
+
# is requesting the deletion, optional but useful for reporting
|
182
|
+
# @param [ Boolean ] (optional) ignore any invalid user IDs(users that do no
|
183
|
+
# exist in the project) that were passed in
|
184
|
+
# @param [ Boolean ] (optional) delete from the entire org rather than just
|
185
|
+
# this project.
|
186
|
+
# @return [ Faraday::Response ]
|
187
|
+
def delete(user_ids: nil, amplitude_ids: nil, requester: nil, ignore_invalid_id: nil, delete_from_org: nil)
|
188
|
+
user_ids = Array(user_ids)
|
189
|
+
amplitude_ids = Array(amplitude_ids)
|
190
|
+
|
191
|
+
faraday = Faraday.new do |conn|
|
192
|
+
conn.basic_auth config.api_key, config.secret_key
|
193
|
+
end
|
194
|
+
|
195
|
+
faraday.post(
|
196
|
+
DELETION_URI_STRING,
|
197
|
+
delete_body(user_ids, amplitude_ids, requester, ignore_invalid_id, delete_from_org),
|
198
|
+
"Content-Type" => "application/json"
|
199
|
+
)
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
|
204
|
+
def delete_body(user_ids, amplitude_ids, requester, ignore_invalid_id, delete_from_org)
|
205
|
+
body = {
|
206
|
+
amplitude_ids: amplitude_ids,
|
207
|
+
user_ids: user_ids,
|
208
|
+
requester: requester
|
209
|
+
}.delete_if { |_, value| value.nil? || value.empty? }
|
210
|
+
|
211
|
+
body[:ignore_invalid_id] = ignore_invalid_id.to_s if ignore_invalid_id
|
212
|
+
body[:delete_from_org] = delete_from_org.to_s if delete_from_org
|
213
|
+
JSON.generate(body)
|
214
|
+
end
|
156
215
|
end
|
157
216
|
end
|