174 lines
5.4 KiB
Ruby
174 lines
5.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class E621Webhook < ApplicationRecord
|
|
validate :validate_max_per_channel, on: :create
|
|
validate :validate_max_per_guild, on: :create
|
|
after_create do
|
|
send_creation_message
|
|
send_update(E621Status.current)
|
|
end
|
|
after_destroy do
|
|
webhook&.delete unless skip_delete_webhook
|
|
send_deletion_message
|
|
end
|
|
attr_reader :skip_delete_webhook
|
|
|
|
MAX_PER_CHANNEL = 1
|
|
MAX_PER_GUILD = 5
|
|
SUCCESS_COLOR = 0x008000
|
|
WARNING_COLOR = 0xFFA500
|
|
ERROR_COLOR = 0xFF0000
|
|
E621_COLOR = 0x012E57
|
|
|
|
def self.from_struct(data, creator_id = nil)
|
|
hook = create(
|
|
webhook_id: data.id,
|
|
webhook_token: data.token,
|
|
channel_id: data.channel_id,
|
|
creator_id: creator_id,
|
|
guild_id: data.guild_id,
|
|
)
|
|
|
|
if hook.errors[:channel_id].include?("has too many webhooks")
|
|
hook.send_too_many_channel_message
|
|
hook.destroy
|
|
return :too_many_channel
|
|
end
|
|
|
|
if hook.errors[:guild_id].include?("has too many webhooks")
|
|
hook.send_too_many_guild_message
|
|
hook.destroy
|
|
return :too_many_guild
|
|
end
|
|
hook
|
|
end
|
|
|
|
def validate_max_per_channel
|
|
return if channel_id.blank?
|
|
return if E621Webhook.for_channel(channel_id).count < MAX_PER_CHANNEL
|
|
errors.add(:channel_id, "has too many webhooks")
|
|
end
|
|
|
|
def validate_max_per_guild
|
|
return if guild_id.blank?
|
|
return if E621Webhook.for_guild(guild_id).count < MAX_PER_GUILD
|
|
errors.add(:guild_id, "has too many webhooks")
|
|
end
|
|
|
|
module WebhookMethods
|
|
def webhook
|
|
return nil unless webhook_id && webhook_token
|
|
Requests::DiscordWebhook.new(id: webhook_id, token: webhook_token)
|
|
end
|
|
|
|
def add_defaults(embed)
|
|
embed.thumbnail = Discordrb::Webhooks::EmbedThumbnail.new(url: "https://status.e621.ws/icon.png")
|
|
embed.url = "https://status.e621.ws"
|
|
embed.timestamp = Time.now
|
|
embed.color = E621_COLOR
|
|
end
|
|
|
|
def notification_webhook
|
|
Websites.config.e621_status_check_logs_webhook
|
|
end
|
|
|
|
def send_creation_message
|
|
execute do |builder|
|
|
builder.add_embed do |embed|
|
|
add_defaults(embed)
|
|
embed.title = "E621 Status Check"
|
|
embed.description = "This webhook has been setup to receive status updates for e621's api#{creator_id.present? ? " by <@#{creator_id}>" : ''}."
|
|
end
|
|
end
|
|
|
|
notification_webhook.execute do |builder|
|
|
builder.add_embed do |embed|
|
|
add_defaults(embed)
|
|
embed.title = "Status Check Webhook Added"
|
|
embed.description = "A status check has been added in the channel **#{channel_id}** of the guild **#{guild_id}**#{creator_id.present? ? " by <@#{creator_id}>" : ''}."
|
|
embed.color = SUCCESS_COLOR
|
|
end
|
|
end
|
|
end
|
|
|
|
def send_deletion_message
|
|
notification_webhook.execute do |builder|
|
|
builder.add_embed do |embed|
|
|
add_defaults(embed)
|
|
embed.title = "Status Check Webhook Removed"
|
|
embed.description = "A status check has been removed in the channel **#{channel_id}** of the guild **#{guild_id}**#{creator_id.present? ? " by <@#{creator_id}>" : ''}."
|
|
embed.color = ERROR_COLOR
|
|
end
|
|
end
|
|
end
|
|
|
|
def send_too_many_guild_message
|
|
execute do |builder|
|
|
builder.add_embed do |embed|
|
|
add_defaults(embed)
|
|
embed.title = "E621 Status Check"
|
|
embed.description = "You've already enabled #{MAX_PER_GUILD} status checks in this server. Please delete the other webhooks before adding a new check. This webhook will be automatically deleted."
|
|
embed.color = ERROR_COLOR
|
|
end
|
|
end
|
|
end
|
|
|
|
def send_too_many_channel_message
|
|
execute do |builder|
|
|
builder.add_embed do |embed|
|
|
add_defaults(embed)
|
|
embed.title = "E621 Status Check"
|
|
embed.description = "You've already enabled #{MAX_PER_CHANNEL} status checks in this channel. Please delete the other webhooks before adding a new check. This webhook will be automatically deleted."
|
|
embed.color = ERROR_COLOR
|
|
end
|
|
end
|
|
end
|
|
|
|
def send_update(status)
|
|
status_text = E621Status::STATUS_MESSAGES[status.status]
|
|
execute do |builder|
|
|
builder.add_embed do |embed|
|
|
add_defaults(embed)
|
|
embed.title = "E621 Status Update"
|
|
embed.description = "E621's api is **#{status.available ? 'available' : 'unavailable'}**."
|
|
embed.color = status.available ? SUCCESS_COLOR : status.status == 403 ? WARNING_COLOR : ERROR_COLOR
|
|
embed.timestamp = status.created_at
|
|
embed.footer = Discordrb::Webhooks::EmbedFooter.new(text: "Since")
|
|
embed.add_field(name: "Status", value: "#{status.status} #{status_text.present? ? "(#{status_text})" : ''}", inline: true)
|
|
embed.add_field(name: "State", value: E621Status::STATES[status.state] || (status.available ? "up" : "down"), inline: true)
|
|
embed.add_field(name: "Note", value: status.note, inline: false) if status.note.present?
|
|
end
|
|
end
|
|
end
|
|
|
|
def execute(...)
|
|
if webhook.nil?
|
|
@skip_delete_webhook = true
|
|
destroy
|
|
return nil
|
|
end
|
|
|
|
begin
|
|
webhook.execute(...)
|
|
rescue RestClient::NotFound
|
|
@skip_delete_webhook = true
|
|
destroy
|
|
nil
|
|
end
|
|
end
|
|
end
|
|
|
|
module SearchMethods
|
|
def for_guild(id)
|
|
where(guild_id: id)
|
|
end
|
|
|
|
def for_channel(id)
|
|
where(channel_id: id)
|
|
end
|
|
end
|
|
|
|
include WebhookMethods
|
|
extend SearchMethods
|
|
end
|