# frozen_string_literal: true class ShortUrl < ApplicationRecord belongs_to_creator belongs_to :api_key, optional: true validates :code, format: { with: /\A[A-Za-z_\-\d]+\z/ }, length: { maximum: 50 }, presence: true, uniqueness: true validates :creator_name, length: { maximum: 50 } validates :url, format: { with: /\A#{URI::DEFAULT_PARSER.make_regexp(%w[http https])}\z/ }, length: { maximum: 2048 }, presence: true before_validation :set_creator_name_if_blank before_create do self.code ||= SecureRandom.alphanumeric(8) self.url = url.strip end attr_accessor :no_webhook_messages, :skip_validations after_create :send_created, unless: :no_webhook_messages after_update :send_updated, unless: :no_webhook_messages after_destroy :send_deleted, unless: :no_webhook_messages def self.override(code, url) prev = find_by(code: code) return prev if prev&.url == url && prev&.management_code.nil? CurrentUser.as_system do prev&.update!(code: "#{code}_#{prev.id}") create!( code: code, creator_name: "YiffyAPI", creator_ua: "YiffyAPI", url: url, no_webhook_messages: true, ) end end def shorturl "https://yiff.rocks/#{code}" end def credit=(value) self.creator_name = value end def set_creator_name_if_blank self.creator_name = creator.name if creator_name.blank? end def serializable_hash(*) { code: code, createdAt: created_at, modifiedAt: updated_at, url: url, pos: id, credit: creator_name || creator&.name, fullURL: shorturl, } end module WebhookMethods GREEN = 0x008000 YELLOW = 0xFFA500 RED = 0xFF0000 def execute(content) Websites.config.yiffyapi_apikey_shortener_webhook.execute({ embeds: [content], }) end def send_created execute({ title: "Short URL Created", description: <<~DESC, ID: **#{id}** Code: **#{code}** URL: #{url} IP: **#{creator_ip_addr}** User-Agent: **#{creator_ua}** Blame: #{blame} DESC color: GREEN, timestamp: Time.now.iso8601, }) end def send_deleted execute({ title: "Short URL Deleted", description: <<~DESC, ID: **#{id}** Code: **#{code}** URL: #{url} Blame: #{blame} DESC color: RED, timestamp: Time.now.iso8601, }) end def check_change(attr, changes) changes << "#{attr.to_s.titleize}: **#{send("#{attr}_before_last_save")}** -> **#{send(attr)}**" if send("saved_change_to_#{attr}?") end def send_updated changes = [] check_change(:url, changes) check_change(:creator_name, changes) return if changes.empty? changes << "Blame: #{blame}" execute({ title: "Short URL Updated", description: changes.join("\n"), color: YELLOW, timestamp: Time.now.iso8601, }) end def blame if CurrentUser.user.present? "<@#{CurrentUser.id}> (`#{CurrentUser.name}`)" elsif Rails.const_defined?("Console") "**Console**" elsif CurrentUser.ip_addr "**#{CurrentUser.ip_addr}" else "**Unknown**" end end end include WebhookMethods end