76 lines
1.9 KiB
Plaintext
76 lines
1.9 KiB
Plaintext
|
#!/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
|