Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow customer_id to be specified in identify URL #111

Merged
merged 6 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.markdown
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## Customerio 5.3.0 - December 8, 2023
### Changed
- The `identify` method has been updated to allow the customer ID to be specified separately from the attributes, using the `customer_id` attribute. This allows a person to be updated by identifying them by e.g.: their email address. Thanks to trwalzer, jrbeck and jeremyw for the original changes that this is based on.
- It is no longer possible to set the `customer_id` attribute on a person. This is a side-effect of the changes to the `identify` method.

## Customerio 5.2.0 - December 8, 2023
### Changed
- The `identify` method will now automatically use the `cio_id` attribute as the customer ID when calling the track service. This allows a customer to be updated using `identify` to modify the `id` and `email` attributes.
Expand Down
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ $customerio.identify(
)
```

### Updating customers
### Updating customers: Changing identifiers

You can use the identify operation to update customers.
If you need to change the `id` or `email` identifiers for a customer,
Expand All @@ -113,6 +113,35 @@ $customerio.identify(
)
```

This method requires either the `id` or `cio_id` for the person. It does not work with email addresses.

You can also use this method to make other updates to the person using the `cio_id`.

### Updating customers: Using email address

If you need to identify a person using their email address, then you can do so
by passing in a customer ID to the `identify` method. This allows you to specify
a customer ID that is different than the one used in the `id` attribute. E.g.:

```ruby
# Arguments
# customer_id (required) - the customer ID to use for this customer, may be an id, email address, or the cio_id.
# This will be used to construct the URL but not sent in the body attributes.
# attributes (required) - a hash of information about the customer. You can pass any
# information that would be useful in your triggers. You
# must at least pass in an id, email, and created_at timestamp.

$customerio.identify(
:customer_id => "bob@example.com",
:location => "Australia"
)
```

Note:

* If you want to use the `cio_id` in the `customer_id` field of `identify_customer_id`, you will need to prefix it with `"cio_"`. E.g.: `"cio_f000000d"` for a `cio_id` of `f000000d`.
* The `identify` method can identify the person using one of `customer_id`, `cio_id` or `id`. The order of precedence is `customer_id` > `cio_id` > `id`.

### Deleting customers

Deleting a customer will remove them, and all their information from
Expand Down
19 changes: 18 additions & 1 deletion lib/customerio/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,16 +151,33 @@ def merge_customers_path

def create_or_update(attributes = {})
attributes = Hash[attributes.map { |(k,v)| [ k.to_sym, v ] }]
if is_empty?(attributes[:id]) && is_empty?(attributes[:cio_id])
if is_empty?(attributes[:id]) && is_empty?(attributes[:cio_id]) && is_empty?(attributes[:customer_id])
raise MissingIdAttributeError.new("Must provide a customer id")
end

# Use cio_id as the identifier, if present,
# to allow the id and email identifiers to be updated.
# The person is identified by a customer ID, which is included
# in the path to the Track v1 API. Choose the ID in this order
# from highest to lowest precedence:
#
# 1. customer_id: "id", an email address, or "cio_id" value.
# Any "cio_id" values need to be prefixed "cio_"
# so that the Track v1 API knows it's a cio_id.
#
# 2. cio_id: The cio_id value (no prefix required).
#
# 3. id: The id value.
customer_id = attributes[:id]
if !is_empty?(attributes[:cio_id])
customer_id = "cio_" + attributes[:cio_id]
end
if !is_empty?(attributes[:customer_id])
customer_id = attributes[:customer_id]
end
# customer_id is not an attribute, so remove it.
attributes.delete(:customer_id)

url = customer_path(customer_id)
@client.request_and_verify_response(:put, url, attributes)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/customerio/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Customerio
VERSION = "5.2.0"
VERSION = "5.3.0"
end
36 changes: 35 additions & 1 deletion spec/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ def json(data)
lambda { client.identify(email: "customer@example.com") }.should raise_error(Customerio::Client::MissingIdAttributeError)
lambda { client.identify(id: "") }.should raise_error(Customerio::Client::MissingIdAttributeError)
lambda { client.identify(cio_id: "") }.should raise_error(Customerio::Client::MissingIdAttributeError)
lambda { client.identify(customer_id: "") }.should raise_error(Customerio::Client::MissingIdAttributeError)
end

it 'should not raise errors when attribute keys are strings' do
Expand Down Expand Up @@ -223,6 +224,39 @@ def json(data)
location: "here"
})
end

it "uses provided id rather than id" do
stub_request(:put, api_uri('/api/v1/customers/1234')).
with(body: json(id: "5")).
to_return(status: 200, body: "", headers: {})

client.identify(
customer_id: "1234",
id: "5"
)
end

it "uses provided cio_id rather than id" do
stub_request(:put, api_uri('/api/v1/customers/cio_5')).
with(body: json(id: "5")).
to_return(status: 200, body: "", headers: {})

client.identify(
customer_id: "cio_5",
id: "5"
)
end

it "uses provided email rather than id" do
stub_request(:put, api_uri('/api/v1/customers/customer@example.com')).
with(body: json(id: "5")).
to_return(status: 200, body: "", headers: {})

client.identify(
customer_id: "customer@example.com",
id: "5"
)
end
end

describe "#delete" do
Expand Down Expand Up @@ -650,7 +684,7 @@ def json(data)
}.to raise_error(Customerio::Client::ParamError, 'timestamp must be a valid timestamp')
end
end

describe "#merge_customers" do
before(:each) do
@client = Customerio::Client.new("SITE_ID", "API_KEY", :json => true)
Expand Down
Loading