This repository has been archived on 2022-05-30. You can view files and clone it, but cannot push or open issues or pull requests.
autonomic.discourse-email/files/receive-mail

76 lines
1.9 KiB
Ruby

#!/usr/bin/env ruby
ENV_FILE = "/etc/postfix/mail-receiver-environment.json"
EX_TEMPFAIL = 75
EX_SUCCESS = 0
require 'syslog'
require 'json'
require "uri"
require "net/http"
def logger
@logger ||= Syslog.open("receive-mail", Syslog::LOG_PID, Syslog::LOG_MAIL)
end
def fatal(*args)
logger.crit *args
exit EX_TEMPFAIL
end
def main
unless File.exists?(ENV_FILE)
fatal "Config file %s does not exist. Aborting.", ENV_FILE
end
real_env = JSON.parse(File.read(ENV_FILE))
%w{DISCOURSE_BASE_URL DISCOURSE_API_KEY DISCOURSE_API_USERNAME}.each do |kw|
fatal "env var %s is required", kw unless real_env[kw]
end
recipient = ARGV.first
mail = $stdin.read
logger.debug "Recipient: #{recipient}"
fatal "No recipient passed on command line." unless recipient
fatal "No message passed on stdin." if mail.nil? || mail.empty?
post_email(recipient, mail, real_env)
rescue StandardError => ex
logger.err "Unexpected error while invoking mail processor: %s (%s)", ex.message, ex.class
logger.err ex.backtrace.map { |l| " #{l}" }.join("\n")
exit EX_TEMPFAIL
end
def post_email(_recipient, mail, env)
endpoint = "#{env['DISCOURSE_BASE_URL']}/admin/email/handle_mail"
key = env["DISCOURSE_API_KEY"]
username = env["DISCOURSE_API_USERNAME"]
uri = URI.parse(endpoint)
begin
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"
post = Net::HTTP::Post.new(uri.request_uri,"api-key" => "#{key}", "api-username" => "#{username}")
post.set_form_data(email: mail)
response = http.request(post)
rescue StandardError => ex
logger.err "Failed to POST the e-mail to %s: %s (%s)", endpoint, ex.message, ex.class
logger.err ex.backtrace.map { |l| " #{l}" }.join("\n")
exit EX_TEMPFAIL
ensure
http.finish if http && http.started?
end
exit EX_SUCCESS if Net::HTTPSuccess === response
logger.err "Failed to POST the e-mail to %s: %s", endpoint, response.code
exit EX_TEMPFAIL
end
main if __FILE__ == $0