Skip to content

Commit

Permalink
Allow customer_id to be specified in identify URL (#111)
Browse files Browse the repository at this point in the history
* Allow customer_id to be specified in identify URL (based on work by jrbeck)

* Bump for release 5.3.0

* Re-order the code docs and clarify usage of cio_id

* Move the support for :customer_id into the base identify method

* Update changelog

* Note that customer_id attribute can't be set anymore
  • Loading branch information
richdawe-cio authored Dec 11, 2023
1 parent da7c1f5 commit c29ac0b
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 4 deletions.
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 => "[email protected]",
: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: "[email protected]") }.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/[email protected]')).
with(body: json(id: "5")).
to_return(status: 200, body: "", headers: {})

client.identify(
customer_id: "[email protected]",
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

0 comments on commit c29ac0b

Please sign in to comment.