require "net/smtp" require "uri" require "time" require "net/http" require "json" class Notification def initialize(email: nil, slack: nil, discord: nil) @list = [] @list << Email.new(email) if email @list << Slack.new(slack) if slack @list << Discord.new(discord) if discord end def publish(*args) # FIXME @list.each { |t| t.publish(*args) } end class Email def initialize(smtp_server:, from:, to:) @smtp_server = URI.parse(smtp_server) @from = from @to = to end def finish(subject, body, id) Net::SMTP.start(@smtp_server.host, @smtp_server.port) { |smtp| smtp.send_message(<<~EOF, @from, @to) From: nyaci <#{@from}> To: #{@to} Date: #{Time.now.rfc2822} Subject: #{subject.delete("\r\n")} Message-Id: #{body.gsub(/(? #{result} " \ "in #{elapsed} seconds."] if failed != 0 ary << "failed builds:" results.select { |id, r| !r }.map { |id, r| id }.sort.each { |i| link = NyaConfig.webroot + "/" + project + "/" + jobid + "/" + i ary << "- <#{link}|#{i}>" } end payload = JSON.generate(attachments: [{ color: failed == 0 ? "good" : "danger", text: ary.join("\n"), }]) uri = URI.parse(@webhook) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = uri.scheme == "https" body = http.start { res = http.post(uri.path, payload, "Content-Type" => "application/json") res.body } raise "failed to post to Slack: #{body}" if body != "ok" end end class Discord def initialize(webhook:) @webhook = webhook end def publish(project, jobid, results, elapsed) failed = results.count { |id, result| !result } link = NyaConfig.webroot + "/" + project + "/" + jobid ary = [] if failed != 0 ary << "failed builds:" results.select { |id, r| !r }.map { |id, r| id }.sort.each { |i| alink = NyaConfig.webroot + "/" + project + "/" + jobid + "/" + i ai = i.gsub(/[_~*|`]/, "\\\\\\0") ary << "- [#{ai}](#{alink})" } end payload = JSON.generate(embeds: [{ color: failed == 0 ? 1673044 : 14431557, title: "nyaci #{failed == 0 ? "passed" : "failed"} - #{project}/#{jobid}", url: link, description: ary.join("\n"), footer: { text: "#{project} • Finished in #{elapsed} seconds", }, timestamp: Time.now.iso8601, }]) uri = URI.parse(@webhook) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = uri.scheme == "https" body = http.start { res = http.post(uri.path, payload, "Content-Type" => "application/json") res.body } raise "failed to post to Discord: #{body}" if body != "ok" end end end