examples/metric_filtering.rb
# frozen_string_literal: true
# Copyright (C) 2019 Twitter, Inc.
require 'twitter-ads'
require 'yaml'
module TwitterAds
# Example of filtering metrics by line-item details.
#
# Usage Example:
# http://showterm.io/f242a11450bcfc4740fdd
#
class Metrics
METRIC_FAMILIES = {
engagement: %w(
billed_engagements
billed_follows
promoted_account_follows
promoted_tweet_profile_card_engagements
promoted_tweet_profile_clicks
promoted_tweet_profile_engagements
promoted_tweet_profile_favorites
promoted_tweet_profile_follows
promoted_tweet_profile_replies
promoted_tweet_profile_retweets
promoted_tweet_profile_url_clicks
promoted_tweet_search_card_engagements
promoted_tweet_search_clicks
promoted_tweet_search_engagements
promoted_tweet_search_favorites
promoted_tweet_search_follows
promoted_tweet_search_replies
promoted_tweet_search_retweets
promoted_tweet_search_url_clicks
promoted_tweet_timeline_card_engagements
promoted_tweet_timeline_clicks
promoted_tweet_timeline_engagements
promoted_tweet_timeline_favorites
promoted_tweet_timeline_follows
promoted_tweet_timeline_replies
promoted_tweet_timeline_retweets
promoted_tweet_timeline_url_clicks
),
conversion: %w(
conversion_custom
conversion_downloads
conversion_order_quantity
conversion_purchases
conversion_sale_amount
conversion_sign_ups
conversion_site_visits
),
media: %w(
promoted_tweet_profile_media_views
promoted_tweet_search_media_views
promoted_tweet_timeline_media_views
promoted_tweet_tpn_media_views
),
mobile_lifetime_value: %w(
mobile_lifetime_value_conversion_breakdown
mobile_lifetime_value_conversion_sale_amount_local_micro_breakdown
mobile_lifetime_value_conversion_order_quantity_breakdown
),
mobile_app_promotion: %w(
mobile_conversion_achievement_unlocked
mobile_conversion_achievement_unlocked_breakdown
mobile_conversion_add_to_cart
mobile_conversion_add_to_cart_breakdown
mobile_conversion_add_to_wishlist
mobile_conversion_add_to_wishlist_breakdown
mobile_conversion_added_payment_infos
mobile_conversion_added_payment_infos_breakdown
mobile_conversion_checkout_initiated
mobile_conversion_checkout_initiated_breakdown
mobile_conversion_content_views
mobile_conversion_content_views_breakdown
mobile_conversion_installs
mobile_conversion_installs_breakdown
mobile_conversion_invites
mobile_conversion_invites_breakdown
mobile_conversion_level_achieved
mobile_conversion_level_achieved_breakdown
mobile_conversion_logins
mobile_conversion_logins_breakdown
mobile_conversion_order_quantity
mobile_conversion_purchases
mobile_conversion_purchases_breakdown
mobile_conversion_rated
mobile_conversion_rated_breakdown
mobile_conversion_re_engages
mobile_conversion_re_engages_breakdown
mobile_conversion_reservations
mobile_conversion_reservations_breakdown
mobile_conversion_sale_amount_local_micro
mobile_conversion_searches
mobile_conversion_searches_breakdown
mobile_conversion_shares
mobile_conversion_shares_breakdown
mobile_conversion_sign_ups
mobile_conversion_sign_ups_breakdown
mobile_conversion_spent_credits
mobile_conversion_spent_credits_breakdown
mobile_conversion_tutorial_completes
mobile_conversion_tutorial_completes_breakdown
mobile_conversion_updates
mobile_conversion_updates_breakdown
promoted_tweet_app_install_attempts
promoted_tweet_app_open_attempts
),
spend: %w(
billed_charge_local_micro
),
twitter_audience_platform: %w(
promoted_tweet_tpn_card_engagements
promoted_tweet_tpn_engagement_rate
promoted_tweet_tpn_engagements
promoted_tweet_tpn_clicks
promoted_tweet_tpn_favorites
promoted_tweet_tpn_follows
promoted_tweet_tpn_impressions
promoted_tweet_tpn_replies
promoted_tweet_tpn_retweets
promoted_tweet_tpn_url_clicks
),
video: %w(
promoted_video_cta_clicks
promoted_video_replays
promoted_video_total_views
promoted_video_views_100
promoted_video_views_25
promoted_video_views_50
promoted_video_views_75
),
other: %w(
promoted_account_follow_rate
promoted_account_impressions
promoted_account_profile_visits
promoted_tweet_profile_impressions
promoted_tweet_search_engagement_rate
promoted_tweet_search_impressions
promoted_tweet_timeline_engagement_rate
promoted_tweet_timeline_impressions
)
}.freeze
OBJECTIVES = {
app_engagements: [
:engagement,
:mobile_app_promotion,
:spend,
:twitter_audience_platform,
:video,
:other
],
app_installs: [
:engagement,
:mobile_app_promotion,
:mobile_lifetime_value,
:other,
:spend,
:twitter_audience_platform,
:video
],
brand_engagements: [
:conversion,
:engagement,
:media,
:spend,
:twitter_audience_platform,
:video,
:other
],
custom: [
:conversion,
:engagement,
:media,
:mobile_app_promotion,
:mobile_lifetime_value,
:spend,
:twitter_audience_platform,
:video,
:other
],
followers: [
:conversion,
:engagement,
:media,
:mobile_app_promotion,
:spend,
:twitter_audience_platform,
:video,
:other
],
preroll_views: [
:engagement,
:media,
:mobile_app_promotion,
:spend,
:twitter_audience_platform,
:video,
:other
],
engagements: [
:conversion,
:engagement,
:media,
:spend,
:video,
:other
],
video_views: [
:engagement,
:spend,
:twitter_audience_platform,
:video,
:other
],
website_clicks: [
:conversion,
:engagement,
:media,
:spend,
:twitter_audience_platform,
:other
],
website_conversions: [
:conversion,
:engagement,
:media,
:spend,
:twitter_audience_platform,
:other
]
}.freeze
# Sets up the object with the correct account and client information.
#
# @example
# metric_filter = TwitterAds::Metric.new('xyz1')
#
# @param account_id [String] The ID for the account to be used.
# @param client [Client] Optional client instance to be used. Will default to ~/.twurlrc info.
# @param mact_enabled [Boolean] Indicates the account has a MACT partner setup (default: false).
#
# @return [self] The configured object instance.
def initialize(account_id, client = nil, mact_enabled = false)
@client = client || create_client
@account = @client.accounts(account_id)
@mact_enabled = !!mact_enabled
raise ArgumentError.new("Error! Account (#{account_id}) not found.") unless @account
self
end
# Determines relevant metrics from a list of line item IDs.
#
# @example
# metric_filter.filter(line_item_ids)
#
# @param line_items [String/Array] A list of one or more line item IDs.
#
# @return [Hash] A hash with relevant metrics for each line item.
def filter(*line_items)
result = {}
params = { line_item_ids: line_items.join(','), with_deleted: true }
@account.line_items(nil, params).each do |line_item|
# filter by objective
objective = line_item.objective.downcase.to_sym
metrics = OBJECTIVES[objective].map { |family| METRIC_FAMILIES[family] }.flatten
# filter by placements
placements = line_item.placements.map { |p| p.downcase.to_sym }
filter_placements(metrics, placements)
# filter by product
product = line_item.product_type.downcase.to_sym
filter_product(metrics, product)
# filter LTV metrics unless account has a MACT partner setup
metrics.reject! { |m| m.include?('mobile_lifetime_value_') } unless @mact_enabled
result[line_item.id] = metrics
end
result
end
private
def filter_placements(metrics, placements)
# return, nothing to exclude
return if placements.include?(:all_on_twitter) && placements.include?(:publisher_network)
# remove all TAP-related metrics unless publisher_network
metrics.reject! { |m| m.include?('_tpn_') } unless placements.include?(:publisher_network)
# remove all timeline-related metrics unless twitter_timeline
metrics.reject! { |m| m.include?('_timeline_') } unless placements.include?(:twitter_timeline)
# remove all search-related metrics unless twitter_search
metrics.reject! { |m| m.include?('_search_') } unless placements.include?(:twitter_search)
# remove all profile-related metrics unless twitter_profile
metrics.reject! { |m| m.include?('_profile_') } unless placements.include?(:twitter_profile)
end
def filter_product(metrics, product)
metrics.reject! { |m| m.include?('promoted_tweet_') } unless product == :promoted_tweets
unless product == :promoted_account
metrics.reject! { |m| m.include?('promoted_account_') || m == 'billed_follows' }
end
end
def create_client
if File.exist?(File.expand_path('~/.twurlrc'))
twurl_config = YAML.safe_load(File.read(File.expand_path('~/.twurlrc')))
profile_name = twurl_config['configuration']['default_profile'][0]
profile_key = twurl_config['configuration']['default_profile'][1]
default_profile = twurl_config['profiles'][profile_name][profile_key]
TwitterAds::Client.new(
default_profile['consumer_key'],
default_profile['consumer_secret'],
default_profile['token'],
default_profile['secret']
)
else
raise ArgumentError.new('Error! No client specified and no ~/.twurlrc found.')
end
end
end
end