Skip to content
Merged
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
71 changes: 61 additions & 10 deletions app/services/url_shortener_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ def self.shorten(long_url)
return nil if long_url.blank?
return long_url unless valid_url?(long_url)

short_url = shorten_with_isgd(long_url)
return short_url if short_url.present?

short_url = shorten_with_tinyurl(long_url)
return short_url if short_url.present?

# Return original URL if shortening fails
long_url
end

private

def self.shorten_with_isgd(long_url)
begin
uri = URI("https://is.gd/create.php")
params = { format: "json", url: long_url }
Expand All @@ -24,26 +37,64 @@ def self.shorten(long_url)
response = http.request(request)

if response.is_a?(Net::HTTPSuccess)
data = JSON.parse(response.body)
if data["shorturl"].present?
puts "Successfully shortened: #{long_url} -> #{data['shorturl']}" if Rails.env.development?
return data["shorturl"]
elsif data["errormessage"]
Rails.logger.error("URL shortening error: #{data['errormessage']}")
body = response.body.to_s

begin
data = JSON.parse(body)
if data["shorturl"].present?
puts "Successfully shortened: #{long_url} -> #{data['shorturl']}" if Rails.env.development?
return data["shorturl"]
elsif data["errormessage"]
Rails.logger.error("URL shortening error: #{data['errormessage']}")
else
Rails.logger.error("URL shortening unexpected response: #{body.first(300)}")
end
rescue JSON::ParserError
Rails.logger.error("URL shortening non-JSON response: #{body.first(300)}")
end
else
Rails.logger.error("URL shortening HTTP error: #{response.code} - #{response.body}")
end
rescue => e
Rails.logger.error("URL shortening failed: #{e.class} - #{e.message}")
Rails.logger.error("URL shortening failed (is.gd): #{e.class} - #{e.message}")
puts "Error shortening URL: #{e.message}" if Rails.env.development?
end

# Return original URL if shortening fails
long_url
nil
end

private
def self.shorten_with_tinyurl(long_url)
begin
uri = URI("https://tinyurl.com/api-create.php")
uri.query = URI.encode_www_form({ url: long_url })

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.open_timeout = 5
http.read_timeout = 5
http.ca_file = "/etc/ssl/cert.pem" if File.exist?("/etc/ssl/cert.pem")

request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)

if response.is_a?(Net::HTTPSuccess)
body = response.body.to_s.strip
if valid_url?(body)
puts "Successfully shortened with TinyURL: #{long_url} -> #{body}" if Rails.env.development?
return body
end

Rails.logger.error("TinyURL unexpected response: #{body.first(300)}")
else
Rails.logger.error("TinyURL HTTP error: #{response.code} - #{response.body}")
end
rescue => e
Rails.logger.error("URL shortening failed (TinyURL): #{e.class} - #{e.message}")
puts "Error shortening URL via TinyURL: #{e.message}" if Rails.env.development?
end

nil
end

def self.valid_url?(url)
uri = URI.parse(url)
Expand Down
Loading