send_sonar 1.1.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -8
- data/README.md +113 -37
- data/RELEASE.md +18 -11
- data/lib/send_sonar.rb +39 -5
- data/lib/send_sonar/client.rb +32 -18
- data/lib/send_sonar/configuration.rb +5 -1
- data/lib/send_sonar/endpoints.yml +16 -0
- data/lib/send_sonar/exceptions.rb +5 -2
- data/lib/send_sonar/version.rb +1 -1
- data/send_sonar.gemspec +7 -7
- data/spec/integrations/simple_desk_spec.rb +308 -41
- data/spec/vcr_cassettes/add_update_customer.yml +58 -0
- data/spec/vcr_cassettes/available_phone_number.yml +54 -0
- data/spec/vcr_cassettes/available_phone_number_bad_publishable_key.yml +52 -0
- data/spec/vcr_cassettes/close_customer.yml +58 -0
- data/spec/vcr_cassettes/close_customer_bad_token.yml +56 -0
- data/spec/vcr_cassettes/delete_customer_property_bad_token.yml +56 -0
- data/spec/vcr_cassettes/delete_customer_property_with_email.yml +58 -0
- data/spec/vcr_cassettes/delete_customer_property_with_phone_number.yml +58 -0
- data/spec/vcr_cassettes/get_customer.yml +50 -0
- data/spec/vcr_cassettes/get_customer_bad_token.yml +48 -0
- data/spec/vcr_cassettes/send_campaign.yml +56 -0
- data/spec/vcr_cassettes/send_campaign_bad_token.yml +56 -0
- metadata +67 -20
- data/Gemfile.ruby-18 +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bac118203bd847590ed9e476d8a925e11a5e62e6
|
4
|
+
data.tar.gz: 1de02c5eae8e19502632dfc4ff8fd7b73cdb91e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94d13650e4fc278ba73b6677ace1a8dbbfa874c857a0991c7abde7caf2edad629a6bee84cecc77217c38f93fa7fbd896bb6e635dc7113bc60ad292f76be21751
|
7
|
+
data.tar.gz: b721dff6b9620be05daa6eeccb319509f6a249e05fe149717abadd1a7772debea94cb19f3bc2e24d86c7d017bbe11436260fdf4be3eb5a97627937052aa4a90f
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
[![Build Status](https://travis-ci.org/sendsonar/send_sonar_gem.svg)](https://travis-ci.org/sendsonar/send_sonar_gem)
|
2
2
|
|
3
|
-
# Upgrading from SimpleDesk Gem
|
4
|
-
Be sure to change your initializer and API calls from `SimpleDesk` to `SendSonar`.
|
5
|
-
|
6
3
|
# SendSonar
|
7
4
|
|
8
5
|
[Sonar](https://www.sendsonar.com) is an SMS customer engagement platform that allows companies to have 2-way conversations with their customers over SMS - whether it's for sales, customer service, funnel abandonment, or transactional messages.
|
@@ -20,21 +17,22 @@ And then execute:
|
|
20
17
|
$ bundle
|
21
18
|
|
22
19
|
## Compatibility
|
23
|
-
Works with Ruby
|
20
|
+
Works with Ruby 2.0.0 or greater
|
24
21
|
|
25
22
|
## Changes
|
26
23
|
See RELEASE.md
|
27
24
|
|
28
|
-
*
|
29
|
-
*
|
30
|
-
*
|
25
|
+
* Ruby 2.0.0 or greater is now required
|
26
|
+
* Included `publishable_key` in configuration
|
27
|
+
* Added support for 5 new API endpoints
|
28
|
+
* `add_customer` has been aliased to `add_update_customer`
|
31
29
|
|
32
30
|
|
33
31
|
## Setup
|
34
32
|
Initialize the gem by creating an initializer.
|
35
33
|
|
36
|
-
* Your production token can be found
|
37
|
-
* Your sandbox token can be found at https://sandbox.sendsonar.com
|
34
|
+
* Your production token can be found if you log into https://sendsonar.com, click the left menu and select Settings, then Company Settings
|
35
|
+
* Your sandbox token can be found if you log into or sign up at https://sandbox.sendsonar.com/, click on the left menu and select Settings, then Company Settings
|
38
36
|
|
39
37
|
```ruby
|
40
38
|
# config/initializers/send_sonar.rb
|
@@ -43,61 +41,138 @@ SendSonar.configure do |config|
|
|
43
41
|
if Rails.env.production?
|
44
42
|
config.env = :live
|
45
43
|
config.token = ENV['SONAR_PRODUCTION_TOKEN'] || 'YOUR_PRODUCTION_TOKEN'
|
44
|
+
config.publishable_key = ENV['SONAR_PRODUCTION_PUBLISHABLE_KEY'] || 'YOUR_PRODUCTION_PUBLISHABLE_KEY'
|
46
45
|
|
47
46
|
elsif Rails.env.staging?
|
48
47
|
config.env = :sandbox
|
49
|
-
config.token = ENV['SONAR_SANDBOX_TOKEN'] || '
|
48
|
+
config.token = ENV['SONAR_SANDBOX_TOKEN'] || 'YOUR_SANDBOX_TOKEN'
|
49
|
+
config.publishable_key = ENV['SONAR_SANDBOX_PUBLISHABLE_KEY'] || 'YOUR_SANDBOX_PUBLISHABLE_KEY'
|
50
50
|
end
|
51
51
|
end
|
52
52
|
```
|
53
53
|
|
54
|
-
|
55
|
-
|
56
54
|
## Usage
|
55
|
+
The gem offers connections to the following API endpoints:
|
56
|
+
* [Send Message](#send-message "Send Message")
|
57
|
+
* [Add / Update Customer](#add--update-customer "Add Update Customer")
|
58
|
+
* [Send Campaign](#send-campaign "Send Campaign")
|
59
|
+
* [Delete Customer Property](#delete-customer-property "Delete Customer Property")
|
60
|
+
* [Close Customer](#close-customer "Close Customer")
|
61
|
+
* [Get Customer](#get-customer "Get Customer")
|
62
|
+
* [Available Phone Number](#available-phone-number "Available Phone Number")
|
57
63
|
|
58
|
-
|
64
|
+
**Note:** Please include a country code for phone numbers (such as +1 for US) in all API calls to us.
|
59
65
|
|
60
|
-
|
66
|
+
### [Send Message](http://docs.sendsonar.com/docs/send-message)
|
67
|
+
---
|
68
|
+
[Visit Documentation](http://docs.sendsonar.com/docs/send-message)
|
61
69
|
|
62
70
|
```ruby
|
63
|
-
SendSonar.message_customer(
|
71
|
+
SendSonar.message_customer(
|
72
|
+
text: 'message text',
|
73
|
+
to: '+12234567890',
|
74
|
+
tag_names: ["attribution"],
|
75
|
+
media_url: "http://where_the_pics_live.com/the_bermanator.png"
|
76
|
+
)
|
64
77
|
```
|
65
|
-
The response is a `SendSonar::Message` object with the following accessors:
|
66
|
-
|
67
|
-
* to (phone number as string)
|
68
|
-
* text
|
69
|
-
* status
|
70
|
-
|
71
|
-
Status is one of "queued" or "unsubscribed". Messages with "queued" status are usually sent within seconds. Messages with "unsubscribed" status will not be sent, as customer has previously unsubscribed from API messages.
|
72
78
|
|
73
|
-
|
79
|
+
The response is a `SendSonar::Message` object with accessors for the parameters listed in the [documentation](http://docs.sendsonar.com/docs/send-message).
|
74
80
|
|
75
|
-
|
81
|
+
Important Notes:
|
82
|
+
1. If you send a message to a new phone number the API will automatically create a new user.
|
83
|
+
2. We prevent companies from sending the exact same message to customers within 7 seconds to prevent spamming and to preserve the great SMS experience.
|
84
|
+
3. In the response, "status" will either be "queued" or "unsubscribed". A "queued" status is a successful response, and means that the message should be sent within seconds. An "unsubscribed" status means that the message will not be sent, as the customer has previously unsubscribed from messages from your business.
|
76
85
|
|
77
|
-
|
78
|
-
|
79
|
-
|
86
|
+
### [Add / Update Customer](http://docs.sendsonar.com/docs/addupdate-customer)
|
87
|
+
---
|
88
|
+
[Visit Documentation](http://docs.sendsonar.com/docs/addupdate-customer)
|
80
89
|
|
81
90
|
```ruby
|
82
|
-
SendSonar.
|
91
|
+
SendSonar.add_update_customer(
|
83
92
|
phone_number: "5555555555",
|
84
93
|
email: "user@example.com",
|
85
94
|
first_name: "john",
|
86
95
|
last_name: "doe",
|
96
|
+
picture_url: "http://where_the_pics_live.com/the_bermanator.png",
|
87
97
|
properties: { great_customer: "true" }
|
88
98
|
)
|
89
99
|
```
|
90
|
-
You can send an unlimited number of properties with arbitrary keys and values.
|
91
100
|
|
92
|
-
|
101
|
+
Important Notes:
|
102
|
+
1. You can send an unlimited number of properties with arbitrary keys and values.
|
103
|
+
2. If a customer already exists with the given phone number, that customer will be updated.
|
104
|
+
3. The old `add_customer` method continues to work but was aliased to `add_update_customer` for clarity.
|
105
|
+
|
106
|
+
The response is a `SendSonar::Customer` object with accessors for the parameters listed in the [documentation](http://docs.sendsonar.com/docs/addupdate-customer).
|
107
|
+
|
108
|
+
### [Send Campaign](http://docs.sendsonar.com/docs/send-campaign)
|
109
|
+
---
|
110
|
+
[Visit Documentation](http://docs.sendsonar.com/docs/send-campaign)
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
SendSonar.send_campaign(
|
114
|
+
to: "+15555555555",
|
115
|
+
campaign_id: "XXXXXXXX_XXXX_XXXX"
|
116
|
+
)
|
117
|
+
```
|
118
|
+
|
119
|
+
The response is a `SendSonar::Response` object with accessors for the parameters listed in the [documentation](http://docs.sendsonar.com/docs/send-campaign).
|
120
|
+
|
121
|
+
### [Delete Customer Property](http://docs.sendsonar.com/docs/delete-customer-pro---perties)
|
122
|
+
|
123
|
+
[Visit Documentation](http://docs.sendsonar.com/docs/delete-customer-properties)
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
SendSonar.delete_customer_property(
|
127
|
+
phone_number: "+15555555555",
|
128
|
+
property_name: "delete_me"
|
129
|
+
)
|
130
|
+
```
|
131
|
+
|
132
|
+
The customer's `email` can be used instead of `phone_number`, so the following is also valid:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
SendSonar.delete_customer_property(
|
136
|
+
email: "user@example.com",
|
137
|
+
property_name: "delete_me"
|
138
|
+
)
|
139
|
+
```
|
140
|
+
|
141
|
+
The response is a `SendSonar::Response` object with accessors for the parameters listed in the [documentation](http://docs.sendsonar.com/docs/delete-customer-properties)
|
142
|
+
|
143
|
+
### [Close Customer](http://docs.sendsonar.com/docs/close-customer)
|
144
|
+
---
|
145
|
+
[Visit Documentation](http://docs.sendsonar.com/docs/close-customer)
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
SendSonar.close_customer(
|
149
|
+
phone_number: "+15555555555"
|
150
|
+
)
|
151
|
+
```
|
152
|
+
|
153
|
+
The response is a `SendSonar::Response` object with accessors for the parameters listed in the [documentation](http://docs.sendsonar.com/docs/close-customer)
|
154
|
+
|
155
|
+
### [Get Customer](http://docs.sendsonar.com/docs/get-customer)
|
156
|
+
---
|
157
|
+
[Visit Documentation](http://docs.sendsonar.com/docs/get-customer)
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
SendSonar.get_customer(
|
161
|
+
phone_number: "+15555555555"
|
162
|
+
)
|
163
|
+
```
|
164
|
+
|
165
|
+
The response is a `SendSonar::Customer` object with accessors for the parameters listed in the [documentation](http://docs.sendsonar.com/docs/get-customer)
|
166
|
+
|
167
|
+
### [Available Phone Number](http://docs.sendsonar.com/docs/available-phone-number)
|
168
|
+
---
|
169
|
+
[Visit Documentation](http://docs.sendsonar.com/docs/available-phone-number)
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
SendSonar.available_phone_number
|
173
|
+
```
|
93
174
|
|
94
|
-
|
95
|
-
* phone_number (string)
|
96
|
-
* email
|
97
|
-
* first_name
|
98
|
-
* last_name
|
99
|
-
* subscribed (boolean)
|
100
|
-
* properties (hash)
|
175
|
+
The response is a `SendSonar::Response` object with accessors for the parameters listed in the [documentation](http://docs.sendsonar.com/docs/available-phone-number)
|
101
176
|
|
102
177
|
## Errors
|
103
178
|
There are many reasons why requests can fail. There are custom error classes to help you figure out what went wrong.
|
@@ -105,6 +180,7 @@ There are many reasons why requests can fail. There are custom error classes to
|
|
105
180
|
Note, all request errors inherit from `SendSonar::RequestException`. Therefore you can rescue all request errors with `rescue SendSonar::RequestException`. The current supported error classes are:
|
106
181
|
|
107
182
|
* SendSonar::BadToken
|
183
|
+
* SendSonar::TokenOrPublishableKeyNotFound
|
108
184
|
* SendSonar::NoActiveSubscription
|
109
185
|
* SendSonar::ApiDisabledForCompany
|
110
186
|
* SendSonar::RequestTimeout
|
data/RELEASE.md
CHANGED
@@ -1,37 +1,44 @@
|
|
1
|
+
v 2.0.0
|
2
|
+
-------
|
3
|
+
* Ruby 2.0.0 or greater is now required
|
4
|
+
* Included `publishable_key` in configuration
|
5
|
+
* Added support for 5 new API endpoints (`send_campaign`, `close_customer`, `delete_customer_property`, `get_customer`, and `available_phone_number`)
|
6
|
+
* `add_customer` has been aliased to `add_update_customer`
|
7
|
+
|
1
8
|
v 1.1.0
|
2
9
|
-------
|
3
|
-
Added invalid phone number error and tests for it.
|
10
|
+
* Added invalid phone number error and tests for it.
|
4
11
|
|
5
12
|
v 1.0.9
|
6
13
|
-------
|
7
|
-
Temporary solution giving more information about why a request failed.
|
14
|
+
* Temporary solution giving more information about why a request failed.
|
8
15
|
|
9
16
|
v 1.0.0
|
10
17
|
-------
|
11
|
-
Configuration is now done through an initializer
|
12
|
-
Support for sandbox server
|
13
|
-
When creating a customer, properties is no longer a separate param (see readme)
|
18
|
+
* Configuration is now done through an initializer
|
19
|
+
* Support for sandbox server
|
20
|
+
* When creating a customer, properties is no longer a separate param (see readme)
|
14
21
|
|
15
22
|
v 0.3.4
|
16
23
|
-------
|
17
|
-
Added ability to send properties
|
24
|
+
* Added ability to send properties
|
18
25
|
|
19
26
|
v 0.3.3
|
20
27
|
-------
|
21
|
-
Remove item from to do list in readme
|
28
|
+
* Remove item from to do list in readme
|
22
29
|
|
23
30
|
v 0.3.2
|
24
31
|
-------
|
25
|
-
Restructure readme
|
32
|
+
* Restructure readme
|
26
33
|
|
27
34
|
v 0.3.1
|
28
35
|
-------
|
29
|
-
Update the readme to note the dynamic token assignment
|
36
|
+
* Update the readme to note the dynamic token assignment
|
30
37
|
|
31
38
|
v 0.3.0
|
32
39
|
-------
|
33
|
-
Make dynamic for API token
|
40
|
+
* Make dynamic for API token
|
34
41
|
|
35
42
|
v 0.2.0
|
36
43
|
-------
|
37
|
-
Add documentation
|
44
|
+
* Add documentation
|
data/lib/send_sonar.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'send_sonar/version'
|
3
2
|
require 'send_sonar/configuration'
|
4
3
|
require 'send_sonar/exceptions'
|
@@ -14,22 +13,57 @@ module SendSonar
|
|
14
13
|
yield @config ||= Configuration.new
|
15
14
|
end
|
16
15
|
|
17
|
-
def add_customer
|
16
|
+
def add_customer params
|
18
17
|
resp = Client.post url_for(:customers), params, headers
|
19
18
|
Customer.new(JSON.parse(resp))
|
20
19
|
end
|
21
20
|
|
22
|
-
|
21
|
+
alias_method :add_update_customer, :add_customer
|
22
|
+
|
23
|
+
def message_customer params
|
23
24
|
resp = Client.post url_for(:messages), params, headers
|
24
25
|
Message.new(JSON.parse(resp))
|
25
26
|
end
|
26
27
|
|
28
|
+
def send_campaign params
|
29
|
+
resp = Client.post url_for(:campaigns), params, headers
|
30
|
+
Response.new(JSON.parse(resp))
|
31
|
+
end
|
32
|
+
|
33
|
+
def close_customer params
|
34
|
+
resp = Client.post url_for(:close_customer), params, headers
|
35
|
+
Response.new(JSON.parse(resp))
|
36
|
+
end
|
37
|
+
|
38
|
+
def delete_customer_property params
|
39
|
+
resp = Client.delete url_for(:delete_customer_property), params, headers
|
40
|
+
Response.new(JSON.parse(resp))
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_customer params
|
44
|
+
query = params.merge({ :token => config.token })
|
45
|
+
# RestClient forms the GET query string from the params field of the header
|
46
|
+
# Set the query hash above to the params field of the header hash below
|
47
|
+
resp = Client.get url_for(:customers), { params: query }
|
48
|
+
Customer.new(JSON.parse(resp))
|
49
|
+
end
|
50
|
+
|
51
|
+
def available_phone_number
|
52
|
+
keys_in_header = { :publishable_key => true, :token => false }
|
53
|
+
resp = Client.get url_for(:available_phone_number), headers(keys_in_header)
|
54
|
+
Response.new(JSON.parse(resp))
|
55
|
+
end
|
56
|
+
|
27
57
|
private
|
28
58
|
|
29
59
|
attr_reader :config
|
30
60
|
|
31
|
-
def headers
|
32
|
-
{
|
61
|
+
def headers include_headers={}
|
62
|
+
include_headers = include_headers.merge({:token => true}) unless include_headers.key? :token
|
63
|
+
headers = { :client => "rubygem #{SendSonar::VERSION}" }
|
64
|
+
headers = headers.merge({ :token => config.token }) if include_headers[:token]
|
65
|
+
headers = headers.merge({ :x_publishable_key => config.publishable_key }) if include_headers[:publishable_key]
|
66
|
+
headers
|
33
67
|
end
|
34
68
|
|
35
69
|
def url_for(key)
|
data/lib/send_sonar/client.rb
CHANGED
@@ -1,26 +1,40 @@
|
|
1
1
|
module SendSonar
|
2
2
|
module Client
|
3
|
+
|
3
4
|
def self.post(url, payload, headers={}, &block)
|
4
|
-
RestClient::Request.execute(:method => :post, :url => url, :payload => payload, :headers => headers, &block)
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
5
|
+
execute_with_exceptions { RestClient::Request.execute(:method => :post, :url => url, :payload => payload, :headers => headers, &block) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.delete(url, payload, headers={}, &block)
|
9
|
+
execute_with_exceptions { RestClient::Request.execute(:method => :delete, :url => url, :payload => payload, :headers => headers, &block) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.get(url, headers={}, &block)
|
13
|
+
execute_with_exceptions { RestClient::Request.execute(:method => :get, :url => url, :headers => headers, &block) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.execute_with_exceptions
|
17
|
+
yield
|
18
|
+
|
19
|
+
rescue Errno::ECONNREFUSED => e
|
20
|
+
raise ConnectionRefused.new(e)
|
21
|
+
|
22
|
+
rescue RestClient::RequestTimeout => e
|
23
|
+
raise RequestTimeout.new(e)
|
24
|
+
|
25
|
+
rescue RestClient::Exception => e
|
26
|
+
if e.http_code == 400
|
27
|
+
raise BadRequest.new(e)
|
20
28
|
else
|
21
|
-
|
29
|
+
response = e.response && JSON.parse(e.response) || {}
|
30
|
+
error = response["error"]
|
31
|
+
if exception_class = Exceptions::EXCEPTIONS_MAP[error]
|
32
|
+
raise exception_class.new(e)
|
33
|
+
else
|
34
|
+
raise "SONAR ERROR: #{e.response} - #{e.message}"
|
35
|
+
end
|
22
36
|
end
|
23
|
-
end
|
24
37
|
end
|
38
|
+
|
25
39
|
end
|
26
40
|
end
|
@@ -5,7 +5,7 @@ module SendSonar
|
|
5
5
|
ENV_URLS = YAML.load_file(File.expand_path('../endpoints.yml', __FILE__))
|
6
6
|
ALLOWED_ENVS = ENV_URLS.keys
|
7
7
|
|
8
|
-
attr_writer :token
|
8
|
+
attr_writer :token, :publishable_key
|
9
9
|
|
10
10
|
def env
|
11
11
|
@env || :sandbox
|
@@ -15,6 +15,10 @@ module SendSonar
|
|
15
15
|
@token || raise(SendSonar::ConfigurationError.new('You need to set your token, see SendSonar Readme'))
|
16
16
|
end
|
17
17
|
|
18
|
+
def publishable_key
|
19
|
+
@publishable_key || raise(SendSonar::ConfigurationError.new('You need to set your publishable key, see SendSonar Readme'))
|
20
|
+
end
|
21
|
+
|
18
22
|
def env=(env_sym)
|
19
23
|
if ALLOWED_ENVS.include?(env_sym.to_s)
|
20
24
|
@env = env_sym.to_s
|
@@ -1,15 +1,31 @@
|
|
1
1
|
local:
|
2
2
|
messages: http://localhost:3000/api/v1/messages
|
3
3
|
customers: http://localhost:3000/api/v1/customers
|
4
|
+
campaigns: http://localhost:3000/api/v1/campaigns
|
5
|
+
close_customer: http://localhost:3000/api/v1/customers/close
|
6
|
+
delete_customer_property: http://localhost:3000/api/v1/customers/properties
|
7
|
+
available_phone_number: http://localhost:3000/api/v1/phone_numbers/available
|
4
8
|
|
5
9
|
staging:
|
6
10
|
messages: https://staging.sendsonar.com/api/v1/messages
|
7
11
|
customers: https://staging.sendsonar.com/api/v1/customers
|
12
|
+
campaigns: https://staging.sendsonar.com/api/v1/campaigns
|
13
|
+
close_customer: https://staging.sendsonar.com/api/v1/customers/close
|
14
|
+
delete_customer_property: https://staging.sendsonar.com/api/v1/customers/properties
|
15
|
+
available_phone_number: https://staging.sendsonar.com/api/v1/phone_numbers/available
|
8
16
|
|
9
17
|
sandbox:
|
10
18
|
messages: https://sandbox.sendsonar.com/api/v1/messages
|
11
19
|
customers: https://sandbox.sendsonar.com/api/v1/customers
|
20
|
+
campaigns: https://sandbox.sendsonar.com/api/v1/campaigns
|
21
|
+
close_customer: https://sandbox.sendsonar.com/api/v1/customers/close
|
22
|
+
delete_customer_property: https://sandbox.sendsonar.com/api/v1/customers/properties
|
23
|
+
available_phone_number: https://sandbox.sendsonar.com/api/v1/phone_numbers/available
|
12
24
|
|
13
25
|
live:
|
14
26
|
messages: https://www.sendsonar.com/api/v1/messages
|
15
27
|
customers: https://www.sendsonar.com/api/v1/customers
|
28
|
+
campaigns: https://www.sendsonar.com/api/v1/campaigns
|
29
|
+
close_customer: https://www.sendsonar.com/api/v1/customers/close
|
30
|
+
delete_customer_property: https://www.sendsonar.com/api/v1/customers/properties
|
31
|
+
available_phone_number: https://www.sendsonar.com/api/v1/phone_numbers/available
|