dripemail / drip-ruby Goto Github PK
View Code? Open in Web Editor NEWA Ruby gem for interacting with Drip's REST API v2.0
License: MIT License
A Ruby gem for interacting with Drip's REST API v2.0
License: MIT License
Now that the Drip API has OAuth, we need to handle OAuth tokens. Currently, this library only supports Basic
auth tokens.
Currently i'm experiencing the lifetime value that resets when we update the order status.
To update our order we use this:
response = client.create_order_activity_event(provider: "ktm", email: @order.user.email, order_id: @order.id.to_s, action: "paid", items: order_items)
The information stored in order_items:
order_items = []
@order.order_items.each do |item|
# Change codes to option code if product is option
item_variant_code = ""
item_product_name = item.product.name
if item.option_id
item_variant_code = item.option.code
item_product_name = "#{item.product.name} #{item.option.name}"
end
#calculate taxes
tax_total = 0.00
if !item.product.tax.blank?
tax_total = item.total.to_f * item.product.tax.amount / 100
tax_total = tax_total.round(2)
end
if item.product.proefpakket
item_info = {
product_id: item.product.code, # use .code for segmentation
product_variant_id: item_variant_code,
name: item_product_name,
# brand: "Koffie 't Molentje",
categories: [
item.product.category.name
],
price: item.unit_price.to_f,
# sale_price: 10.16,
quantity: item.quantity,
taxes: tax_total.to_f,
total: item.total.to_f,
product_url: show_product_path(item.product.category, item.product),
image_url: item.product.image.url,
product_tag: "Proefpakket"
}
else
item_info = {
product_id: item.product.code, # use .code for segmentation
product_variant_id: item_variant_code,
name: item_product_name,
# brand: "Koffie 't Molentje",
categories: [
item.product.category.name
],
price: item.unit_price.to_f,
# sale_price: 10.16,
quantity: item.quantity,
taxes: tax_total.to_f,
total: item.total.to_f,
product_url: show_product_path(item.product.category, item.product),
image_url: item.product.image.url
}
end
order_items.push(item_info)
end
However see this screenshot for what this gives us:
Is there anything i'm doing wrong?
I'm just starting with Drip, and it's my first time to integrate email, so very new at this.
I'm trying to make a simple opt-in that sends out an email campaign but the Drip::Client doesn't seem to be recognized.
The error i'm getting is this:
NameError (uninitialized constant MailController::Drip):
and this is my code for now:
In gemfile:
gem 'drip-ruby', require: 'drip'
In mailcontroller:
class MailController < ApplicationController
def send_pro_bundle
# Connect to API
client = Drip::Client.new do |config|
config.api_key = Rails.application.secrets.drip_api_key
config.account_id = Rails.application.secrets.drip_account_key
end
# Fetch & setup variables
email = params[:email]
fname = params[:fname]
lname = params[:lname]
options = {
time_zone: Time.zone.name,
custom_fields: {
first_name: fname,
last_name: lname
}
}
# Create or update contact
response = client.create_or_update_subscriber(email, options)
if response.success?
puts response.body["subscribers"]
end
# Send email
end
end
What am i doing wrong? (And my apologies in advance for this newbie question.)
Following gem conventions, let's move Drip::Client
into lib/drip/client.rb
and require
it in lib/drip.rb
Currently, there is no Ruby support for this endpoint: https://developer.drip.com/?ruby#users
Is there a plan to implement it in the future?
Ruby 2.7 emits warnings for using the last argument of a method call implicitly as keyword arguments. It appears that Drip::Client
does this on line 66 when initializing an instance of Configuration
causing a deprecation warning output to the standard error stream.
Deprecation Warnings Emitted
drip-ruby-3.4.0/lib/drip/client.rb:66: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
drip-ruby-3.4.0/lib/drip/client/configuration.rb:13: warning: The called method `initialize' is defined here
The fix for this occurrence would be to simply prefix the argument with **
though there may be other cases where this is a problem in the library that I have not encountered yet.
This JUST started happening tonight. When I run something like this:
3.0.0 :001 > DRIP_CLIENT.track_event("[email protected]","testing events")
D, [2021-04-06T20:57:49.744130 #49165] DEBUG -- : [httplog] Connecting: api.getdrip.com:443
D, [2021-04-06T20:57:49.955952 #49165] DEBUG -- : [httplog] Sending: POST http://api.getdrip.com:443/v2/3812252/events
D, [2021-04-06T20:57:49.956296 #49165] DEBUG -- : [httplog] Data: {"events":[{"email":"[email protected]","action":"testing events","properties":{}}]}
D, [2021-04-06T20:57:49.956541 #49165] DEBUG -- : [httplog] Status: 204
D, [2021-04-06T20:57:49.956792 #49165] DEBUG -- : [httplog] Benchmark: 0.093263 seconds
Traceback (most recent call last):
1: from (irb):1:in `<main>'
FrozenError (can't modify frozen String: "")
I get the FrozenError (can't modify frozen String: "")
error BUT the event GOES through.
I'm running Ruby 3.0.0 with Rails 6.1.3 and the latest version of this gem.
Since a few weeks Drip is no longer updating somehow and this is the error i am receiving, can you help me out how to fix this?
2021-01-26T09:23:25.527213+00:00 app[web.1]: Failed to add/update order to Drip. 2021-01-26T09:23:25.527235+00:00 app[web.1]: {"validation_errors"=>[{"keyword"=>"format", "dataPath"=>".items[0].product_url", "schemaPath"=>"order_item.json/properties/product_url/format", "params"=>{"format"=>"uri"}, "message"=>"should match format \"uri\""}]}
When trying to add a timezone to a subscriber, it needs to be in Olson format.
Is there any way to easily transform the current timezone in rails to this format?
I did quite some research but can't find anything, and this is quite important when working with subscribers from multiple countries/timezones.
Could you release a new version of the gem that includes #19? The current version is locked on an old version of json
(< v2.0). Thanks!
Trying to run a method we've run 1000 times:
response = DRIP_CLIENT.create_or_update_subscriber(subscriber_email, options)
but are now getting this odd error:
#<Drip::Response:0x00007fa0bb3d6540 @status=422, @body={"errors"=>[{"code"=>"uniqueness_error", "attribute"=>"user_id", "message"=>"User is already being used"}]}, @links=nil, @meta=nil, @members={"errors"=>[{"code"=>"uniqueness_error", "attribute"=>"user_id", "message"=>"User is already being used"}]}>
Is the API having issues?
Is it me or is the drip gem a different thing: https://rubygems.org/gems/drip
Hi!
I'm trying to implement drip-ruby
and I'm running into an issue when submitting data to the Shopper Activity cart endpoint but I assume the issue will exist with other endpoints.
The request is coming back with an error but the message is unclear as to what exactly is wrong.
Here is the data I am sending:
{:provider=>"solidus",
:email=>"[email protected]",
:action=>"updated",
:cart_id=>"7",
:cart_public_id=>"R317521528",
:grand_total=>285.48,
:total_discounts=>0.0,
:currency=>"USD",
:cart_url=>"http://localhost:3000/cart",
:items=>
[{:product_id=>"2",
:product_variant_id=>"2",
:sku=>"ROR-00012",
:name=>"Ruby on Rails Bag",
:categories=>["Bags", "Rails"],
:price=>22.99,
:quantity=>10,
:discounts=>0.0,
:total=>241.4,
:product_url=>"http://localhost:3000/products/ruby-on-rails-bag",
:image_url=>"/spree/products/23/cart/ror_bag.jpeg?1560433522"}],
:occurred_at=>"2019-10-28T17:05:48-07:00"}
and the response.body
is
{"error"=>
{"message"=>
"[instance type (string) does not match any allowed primitive type (allowed: [\"integer\",\"number\"])]"}}
The problem is which instance type is wrong? Everything seems to be the same types listed in the API docs https://developer.drip.com/?ruby#cart-activity.
I guess what I'm hoping is that the error returned in the response could be more specific as to which field is actually causing the issue.
When I run the rails console after including the drip gem like this:
gem "drip", git: "[email protected]:DripEmail/drip-ruby.git"
I get this error:
$ rails c
/Users/pupeno/.rvm/gems/ruby-2.1.2@watu/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `require': cannot load such file -- faraday_middleware (LoadError)
from /Users/pupeno/.rvm/gems/ruby-2.1.2@watu/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `block in require'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@watu/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:236:in `load_dependency'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@watu/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `require'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@watu/bundler/gems/drip-ruby-ef82fdb9a332/lib/drip/client.rb:2:in `<top (required)>'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@watu/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `require'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@watu/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `block in require'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@watu/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:236:in `load_dependency'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@watu/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `require'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@watu/bundler/gems/drip-ruby-ef82fdb9a332/lib/drip.rb:2:in `<top (required)>'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:76:in `require'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:76:in `block (2 levels) in require'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:72:in `each'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:72:in `block in require'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:61:in `each'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:61:in `require'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@global/gems/bundler-1.6.2/lib/bundler.rb:132:in `require'
from /Users/pupeno/Projects/watu/config/application.rb:9:in `<top (required)>'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@watu/gems/railties-3.2.19/lib/rails/commands.rb:39:in `require'
from /Users/pupeno/.rvm/gems/ruby-2.1.2@watu/gems/railties-3.2.19/lib/rails/commands.rb:39:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
And delete it from the source tree:
$ git rm --cached .DS_Store
The new APIs here:
https://headwayapp.co/drip-ecrm-release-notes/drip-s-new-shopper-activity-api-is-here!-92779
Are not included in the Drip Ruby gem.
When using the create_cart_activity_event
or create_order_activity_event
and passing an array of items, which is basically an array of ruby hashes, as per the API documents to drip, they are not stored as an object and, as such, we can't properly use them in our emails. When I try to use them in an abandon template, for example, all the wrong data is pulled.
How do we pass an item array to CORRECTLY store in Drip? Here is an example of how the data is recorded and you can clearly see that the Items field is simply a dump of the Ruby Hash, not a reusuable object. I also tried passing an array of JSON objects but the response said that it was expecting an object to be passed, which doesn't make a lot of sense.
Seems like a good idea to return a Drip::Response
object from all API methods, that includes:
links
data (if present)meta
data (if present)So the flow could look something like this:
resp = client.list_campaigns(...)
#=> <Drip::Response ...>
resp.campaigns
#=> [<Drip::Campaign ...>]
resp.campaigns.first.name
#=> "Email Course"
resp.links
#=> <Drip::Links ...>
resp.meta
#=> <Drip::Meta ...>
resp.meta.page
#=> 1
I had an error when I try to do a request to get custom_fields
from my Drip account.
This is the code line: client.get("#{client.account_id}/custom_field_identifiers", {})
, "OtherField" is one of my custom fields
Use this instead:
"Drip Ruby v#{Drip::VERSION}"
To start, we need these objects:
Drip::Subscriber
Drip::Campaign
Drip::Account
I'm not opposed to using the virtus gem to declare the expected attributes and handle type coercions (e.g. created_at should be coerced into a time object)
When the rate limit is exceeded, the drip API server responds with this content:
{"message":"API rate limit exceeded. Please try again in an hour."}
When the client library tries to create a resource from the response, it causes a NoMethodError:
NoMethodError: undefined method `keys' for "API rate limit exceeded. Please try again in an hour.":String
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/resource.rb" line 32 in block in process
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/resource.rb" line 31 in tap
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/resource.rb" line 31 in process
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/resource.rb" line 9 in initialize
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/response.rb" line 56 in new
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/response.rb" line 56 in block (2 levels) in parse_members
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/response.rb" line 49 in each
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/response.rb" line 49 in block in parse_members
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/response.rb" line 47 in tap
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/response.rb" line 47 in parse_members
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/response.rb" line 13 in initialize
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/client.rb" line 70 in new
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/client.rb" line 70 in build_response
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/client.rb" line 55 in make_request
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/client.rb" line 43 in post
File "/app/vendor/bundle/ruby/2.3.0/gems/drip-ruby-0.0.10/lib/drip/client/subscribers.rb" line 69 in create_or_update_subscribers
@ "/app/vendor/bundle/ruby/2.5.0/gems/drip-ruby-3.2.0/lib/drip/resource.rb" line 32 in block in process
This is a follow up from #33 (comment) as requested.
The issue is still not fixed. Here's the stacktrace:
NoMethodError · undefined method `keys' for "Endpoint request timed out":String
gems/drip-ruby-3.2.0/lib/drip/resource.rb:32:in `block in process': undefined method `keys' for "Endpoint request timed out":String (NoMethodError)
from gems/drip-ruby-3.2.0/lib/drip/resource.rb:31:in `tap'
from gems/drip-ruby-3.2.0/lib/drip/resource.rb:31:in `process'
from gems/drip-ruby-3.2.0/lib/drip/resource.rb:9:in `initialize'
from gems/drip-ruby-3.2.0/lib/drip/response.rb:59:in `new'
from gems/drip-ruby-3.2.0/lib/drip/response.rb:59:in `block (2 levels) in parse_members'
from gems/drip-ruby-3.2.0/lib/drip/response.rb:52:in `each'
from gems/drip-ruby-3.2.0/lib/drip/response.rb:52:in `block in parse_members'
from gems/drip-ruby-3.2.0/lib/drip/response.rb:50:in `tap'
from gems/drip-ruby-3.2.0/lib/drip/response.rb:50:in `parse_members'
from gems/drip-ruby-3.2.0/lib/drip/response.rb:13:in `initialize'
from gems/drip-ruby-3.2.0/lib/drip/client.rb:119:in `new'
from gems/drip-ruby-3.2.0/lib/drip/client.rb:119:in `build_response'
from gems/drip-ruby-3.2.0/lib/drip/client.rb:85:in `make_request'
from gems/drip-ruby-3.2.0/lib/drip/client.rb:65:in `post'
from gems/drip-ruby-3.2.0/lib/drip/client/subscribers.rb:54:in `create_or_update_subscriber'
It looks like your API are returning data in a format your client is unable to process.
I was attempting to utilize this gem to unsubscribe individuals directly from my ruby app. After a few attempts it seems that the endpoint POST /:account_id/subscribers/:id_or_email/unsubscribe
returns a successful response but does not actually complete the unsubscribe.
According to the documentation https://www.getdrip.com/docs/rest-api#unsubscribe, that endpoint has been moved to POST /:account_id/subscribers/:id_or_email/remove
or POST /:account_id/subscribers/:id_or_email/unsubscribe_all
. I'm assuming the /unsubscribe endpoint was originally kept in place for backwards compatibility but perhaps it no longer completes the action? If that's the case, it sounds like the gem should be updated.
I'm happy to submit a PR but thought I'd confirm my suspicions first.
drip-ruby/lib/drip/client/subscribers.rb
Line 82 in 97f6d3d
Is there an example for using the order functions? It seems there isn't any currently in the documentation.
Not sure what's going on in my case, could be related to the API itself not the gem.
I'm trying to migrate all orders (custom platform) over but they never get created.
It seems to work when I send order one-by-one.
upstream_id
per account when orders are deleted? It seems, that when I delete all subscribers and send again, orders don't get created
upstream_id
) to 2 different subscribers. "This order already exists under a different subscriber".I'm willing to share my account id for troubleshooting as I keep getting 202
success code but orders do not appear.
Here is the code I use in a rake task to backfill my account.
def tag_client_order(order)
order_hash = {
provider: 'my_provider',
upstream_id: order.id,
identifier: order.code,
amount: (order.amount * 100).to_i,
currency_code: 'CAD',
occured_at: order.completed_at.to_s,
financial_state: 'paid',
fulfillment_state: 'fulfilled'
}
client.create_or_update_order(order.client.email, order_hash)
...
end
Can't figure out whether this is an issue with our code, or the gem code. Hoping someone can shed some light on what might be going on here.
TypeError: can't dup Fixnum
app/services/drip_service.rb:10:in `create_or_update_contact'
@client.create_or_update_subscriber(contact.email,
app/models/newsletter_contact.rb:50:in `sync'
DripService.new.create_or_update_contact(self, tags, remove_tags, merged_custom_fields)
app/models/newsletter_contact.rb:37:in `sync_contact'
sync
app/models/newsletter_contact.rb:28:in `update_contact'
contact.sync_contact
app/models/subscription_box_count_history.rb:48:in `tag_contact'
NewsletterContact.update_contact tags: ["customer"], remove_tags: ["cancelled_customer"], user: user
class DripService
def initialize
@client = Drip::Client.new do |c|
c.api_key = ENV["DRIP_KEY"]
c.account_id = ENV["DRIP_ACCOUNT_ID"]
end
end
def create_or_update_contact(contact, tags=[], remove_tags=[], custom_fields={})
@client.create_or_update_subscriber(contact.email,
tags: include_env_tag(tags),
remove_tags: remove_tags,
custom_fields: custom_fields)
end
end
class NewsletterContact
include ActiveModel::Model
include Virtus.model
attribute :id, Integer
attribute :first_name, String
attribute :last_name, String
attribute :email, String
attribute :tags, Array
attribute :remove_tags, Array
attribute :reward_code, String
attribute :referred_friend_name, String
attribute :ticked_subscribe_to_newsletter_at_signup, Boolean
attribute :custom_fields, Hash
validates :email, presence: true
validates_format_of :email, :with => Devise::email_regexp
def self.update_contact(tags:[], remove_tags:[], user:, custom_fields: {})
begin
contact = NewsletterContact.new
contact.id = user.id
contact.first_name = user.first_name if user.first_name
contact.email = user.email
contact.tags = tags
contact.remove_tags = remove_tags
contact.custom_fields = custom_fields
contact.sync_contact
rescue InvalidContactError => e
Raven.capture_exception(e)
end
end
def sync_contact
if valid?
sync
true
else
raise InvalidContactError.new(errors.full_messages)
false
end
end
private
def sync
DripService.new.create_or_update_contact(self, tags, remove_tags, merged_custom_fields)
end
def merged_custom_fields
default_fields = {}
default_fields[:first_name] = self.first_name.titleize if self.first_name
default_fields[:last_name] = self.last_name.titleize if self.last_name
default_fields[:user_id] = self.id if self.id
default_fields[:reward_code] = self.reward_code.upcase if self.reward_code
default_fields[:referred_friend_name] = self.referred_friend_name.titleize if self.referred_friend_name
default_fields[:ticked_subscribe_to_newsletter_at_signup] = self.ticked_subscribe_to_newsletter_at_signup if self.ticked_subscribe_to_newsletter_at_signup
default_fields.merge(custom_fields)
end
end
NewsletterContact.update_contact tags: ["customer"], remove_tags: ["cancelled_customer"], user: user
This error has cropped up 3 times in the last 24 hours. Code has not been modified and I've never seen the error before. Can't see how a Fixnum
could feasibly be passed into drip-ruby
. 🤔
I am currently debugging a case of
gems/drip-ruby-0.0.12/lib/drip/resource.rb:32:in `block in process': undefined method `keys' for 500:Integer (NoMethodError)
I assume the API is returning an unexpected value. But in order to prove this, I needed request/response logging. For now, I helped myself with
Drip::Client.new do |c|
c.api_key = @api_key
c.account_id = @account_id
c.connection.response(:logger, Rails.logger, headers: true, bodies: true)
end
This is not an ideal solution and it would be great to have this gem to support a more specific logging.
Full trace:
gems/drip-ruby-0.0.12/lib/drip/resource.rb:32:in `block in process': undefined method `keys' for 500:Integer (NoMethodError)
from gems/drip-ruby-0.0.12/lib/drip/resource.rb:31:in `tap'
from gems/drip-ruby-0.0.12/lib/drip/resource.rb:31:in `process'
from gems/drip-ruby-0.0.12/lib/drip/resource.rb:9:in `initialize'
from gems/drip-ruby-0.0.12/lib/drip/response.rb:59:in `new'
from gems/drip-ruby-0.0.12/lib/drip/response.rb:59:in `block (2 levels) in parse_members'
from gems/drip-ruby-0.0.12/lib/drip/response.rb:52:in `each'
from gems/drip-ruby-0.0.12/lib/drip/response.rb:52:in `block in parse_members'
from gems/drip-ruby-0.0.12/lib/drip/response.rb:50:in `tap'
from gems/drip-ruby-0.0.12/lib/drip/response.rb:50:in `parse_members'
from gems/drip-ruby-0.0.12/lib/drip/response.rb:13:in `initialize'
from gems/drip-ruby-0.0.12/lib/drip/client.rb:70:in `new'
from gems/drip-ruby-0.0.12/lib/drip/client.rb:70:in `build_response'
from gems/drip-ruby-0.0.12/lib/drip/client.rb:55:in `make_request'
from gems/drip-ruby-0.0.12/lib/drip/client.rb:43:in `post'
from gems/drip-ruby-0.0.12/lib/drip/client/subscribers.rb:49:in `create_or_update_subscriber'
Upgrade to 3.x
@last_response = client.subscriber(user.email)
return false unless @last_response.success?
subscriber = @last_response.subscribers.first
Hi @djreimer,
I have a few questions about the client#subscribe
method:
This will automatically create the subscriber as well - right?
custom_fields
will be passed to the subscriber object as well? e.g. if I pass {first_name: 'John Doe'}
I can then use {{subscriber.first_name}}
in the campaign emails - right?
Could use some refactoring:
if occurred_at.nil?
body = { :events => [{ :email => email, :action => action, :properties => properties }] }.to_json
else
{ :events => [{ :email => email, :action => action, :properties => properties, :occurred_at => occurred_at }] }.to_json
end
Something like:
event_data = { :email => email, :action => action, :properties => properties }
event_data[:occurred_at] = occurred_at if occurred_at
body = { :events => [event_data] }.to_json
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.