refactor: replace click tracker with direct spawn
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
require "user_agent_parser"
|
||||
|
||||
UserAgent.load_regexes(File.read("data/uap_core_regexes.yaml"))
|
||||
IpLookup.load_mmdb("data/GeoLite2-Country.mmdb")
|
||||
|
||||
module App::Controllers
|
||||
class ClickController
|
||||
include App::Models
|
||||
include App::Lib
|
||||
include App::Services
|
||||
|
||||
def initialize(@env : HTTP::Server::Context); end
|
||||
|
||||
def redirect
|
||||
slug = @env.params.url["slug"]
|
||||
|
||||
link_data = nil
|
||||
Database.raw_query("SELECT id, url FROM links WHERE slug = (?) LIMIT 1", slug) do |result|
|
||||
if result.move_next
|
||||
link_data = {result.read(Int64), result.read(String)}
|
||||
end
|
||||
end
|
||||
raise App::NotFoundException.new(@env) unless link_data
|
||||
|
||||
link_id, url = link_data
|
||||
client_ip = IpLookup.ip_from_address(@env.request.headers["Cf-Connecting-Ip"]? || @env.request.remote_address.to_s)
|
||||
|
||||
@env.response.status_code = 301
|
||||
@env.response.headers["Location"] = url
|
||||
@env.response.headers["X-Forwarded-For"] = client_ip.to_s
|
||||
@env.response.headers["Connection"] = "close"
|
||||
|
||||
@env.response.flush
|
||||
|
||||
spawn do
|
||||
begin
|
||||
user_agent_str = @env.request.headers["User-Agent"]?
|
||||
referer = @env.request.headers["Referer"]?.try { |r| URI.parse(r).host rescue r } || @env.params.query["utm_source"]? || "Direct"
|
||||
|
||||
ua_parser = user_agent_str ? UserAgent.new(user_agent_str) : nil
|
||||
|
||||
click = App::Models::Click.new
|
||||
click.link_id = link_id
|
||||
click.country = client_ip ? IpLookup.new(client_ip).try(&.country.try(&.code)) : nil
|
||||
click.user_agent = ua_parser.to_s
|
||||
click.browser = ua_parser.try(&.family)
|
||||
click.os = ua_parser.try(&.os.try(&.family))
|
||||
click.referer = referer
|
||||
|
||||
Database.insert(click)
|
||||
rescue ex
|
||||
Log.error { "Click tracking error: #{ex.message}" }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -5,7 +5,6 @@ module App::Controllers
|
||||
include App::Services
|
||||
|
||||
def initialize(@env : HTTP::Server::Context)
|
||||
ClickTracker.init
|
||||
super(@env)
|
||||
end
|
||||
|
||||
@@ -34,33 +33,6 @@ module App::Controllers
|
||||
render_json({"data" => App::Serializers::Link.new(inserted_link)}, 201)
|
||||
end
|
||||
|
||||
def redirect
|
||||
slug = @env.params.url["slug"]
|
||||
|
||||
link_data = nil
|
||||
# LIMIT 1 degrades performance on unique field searches
|
||||
# slug autoindex has better perormance than the covering index
|
||||
Database.raw_query("SELECT id, url FROM links WHERE slug = (?)", slug) do |result|
|
||||
if result.move_next
|
||||
link_data = {result.read(Int64), result.read(String)}
|
||||
end
|
||||
end
|
||||
raise App::NotFoundException.new(@env) unless link_data
|
||||
|
||||
remote_address = @env.request.headers["Cf-Connecting-Ip"]?.try(&.presence) || @env.request.remote_address.try &.to_s
|
||||
user_agent_str = @env.request.headers["User-Agent"]? || "Unknown"
|
||||
client_ip = IpLookup.extract_ip(remote_address) || "Unknown"
|
||||
|
||||
@env.response.status_code = 301
|
||||
@env.response.headers["Connection"] = "close"
|
||||
|
||||
@env.response.headers["Location"] = link_data[1]
|
||||
@env.response.headers["X-Forwarded-For"] = client_ip
|
||||
@env.response.headers["User-Agent"] = user_agent_str
|
||||
|
||||
spawn track_click(link_data[0], client_ip, user_agent_str)
|
||||
end
|
||||
|
||||
def list_all
|
||||
limit, cursor = pagination_params
|
||||
|
||||
@@ -158,19 +130,6 @@ module App::Controllers
|
||||
current_user.id.as(Int64)
|
||||
end
|
||||
|
||||
private def track_click(link_id, client_ip, user_agent_str)
|
||||
source = @env.params.query["utm_source"]? || "Direct"
|
||||
referer = @env.request.headers["Referer"]?.try { |r| begin URI.parse(r).host rescue r end } || source
|
||||
|
||||
ClickTracker.track(
|
||||
link_id: link_id,
|
||||
client_ip: client_ip,
|
||||
user_agent: user_agent_str,
|
||||
source: source,
|
||||
referer: referer
|
||||
)
|
||||
end
|
||||
|
||||
private def pagination_params
|
||||
limit = (@env.params.query["limit"]? || "100").to_i32
|
||||
cursor = @env.params.query["cursor"]?
|
||||
|
||||
Reference in New Issue
Block a user