Merge pull request #459 from foodcoop1040/smtp
Add SMTP server for handling reply emails
This commit is contained in:
commit
504c8b6192
4 changed files with 88 additions and 51 deletions
|
@ -17,7 +17,9 @@ PATH
|
||||||
foodsoft_messages (0.0.1)
|
foodsoft_messages (0.0.1)
|
||||||
base32
|
base32
|
||||||
deface (~> 1.0.0)
|
deface (~> 1.0.0)
|
||||||
|
gserver
|
||||||
mail
|
mail
|
||||||
|
mini-smtp-server
|
||||||
rails
|
rails
|
||||||
|
|
||||||
PATH
|
PATH
|
||||||
|
@ -162,6 +164,7 @@ GEM
|
||||||
git-version-bump (0.15.1)
|
git-version-bump (0.15.1)
|
||||||
globalid (0.3.6)
|
globalid (0.3.6)
|
||||||
activesupport (>= 4.1.0)
|
activesupport (>= 4.1.0)
|
||||||
|
gserver (0.0.1)
|
||||||
haml (4.0.7)
|
haml (4.0.7)
|
||||||
tilt
|
tilt
|
||||||
haml-rails (0.9.0)
|
haml-rails (0.9.0)
|
||||||
|
@ -230,6 +233,7 @@ GEM
|
||||||
mime-types (3.1)
|
mime-types (3.1)
|
||||||
mime-types-data (~> 3.2015)
|
mime-types-data (~> 3.2015)
|
||||||
mime-types-data (3.2016.0521)
|
mime-types-data (3.2016.0521)
|
||||||
|
mini-smtp-server (0.0.2)
|
||||||
mini_portile2 (2.1.0)
|
mini_portile2 (2.1.0)
|
||||||
minitest (5.9.0)
|
minitest (5.9.0)
|
||||||
mono_logger (1.1.0)
|
mono_logger (1.1.0)
|
||||||
|
|
|
@ -14,9 +14,14 @@ gem 'foodsoft_messages', path: 'lib/foodsoft_messages'
|
||||||
This plugin introduces the foodcoop config option `use_messages`, which can be
|
This plugin introduces the foodcoop config option `use_messages`, which can be
|
||||||
set to `false` to disable messages. May be useful in multicoop deployments.
|
set to `false` to disable messages. May be useful in multicoop deployments.
|
||||||
|
|
||||||
To allow members to respond to messages via email, see the config option
|
To allow members to respond to messages via email, you need the set the config
|
||||||
`reply_email_domain` and the rake task `foodsoft:parse_reply_email`. We need to
|
option `reply_email_domain` and handle incoming mails via one of the following
|
||||||
add some documentation on setting it up, though.
|
rake tasks. `foodsoft:reply_email_smtp_server` starts an SMTP server on the
|
||||||
|
port given via the environment variable `PORT` and listens until a shutdown
|
||||||
|
signal is received. If there is already a SMTP server for handling incoming
|
||||||
|
mails you can also feed every mail via a call to `foodsoft:parse_reply_email`
|
||||||
|
into foodsoft. It expects the address given in the `MAIL FROM` command via
|
||||||
|
SMTP in the environment variable `RECIPIENT` and the mail body as `STDIN`.
|
||||||
|
|
||||||
This plugin is part of the foodsoft package and uses the GPL-3 license (see
|
This plugin is part of the foodsoft package and uses the GPL-3 license (see
|
||||||
foodsoft's LICENSE for the full license text).
|
foodsoft's LICENSE for the full license text).
|
||||||
|
|
|
@ -20,6 +20,8 @@ Gem::Specification.new do |s|
|
||||||
s.add_dependency "base32"
|
s.add_dependency "base32"
|
||||||
s.add_dependency "deface", "~> 1.0.0"
|
s.add_dependency "deface", "~> 1.0.0"
|
||||||
s.add_dependency "mail"
|
s.add_dependency "mail"
|
||||||
|
s.add_dependency "mini-smtp-server"
|
||||||
|
s.add_dependency "gserver"
|
||||||
|
|
||||||
s.add_development_dependency "sqlite3"
|
s.add_development_dependency "sqlite3"
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,37 @@
|
||||||
require "mail"
|
require "mail"
|
||||||
|
require "mini-smtp-server"
|
||||||
|
|
||||||
|
class ReplyEmailSmtpServer < MiniSmtpServer
|
||||||
|
|
||||||
|
def new_message_event(message_hash)
|
||||||
|
m = /<(?<recipient>[^<>]+)>/.match(message_hash[:to])
|
||||||
|
raise "invalid format for RCPT TO" if m.nil?
|
||||||
|
hande_mail(m[:recipient], message_hash[:data])
|
||||||
|
rescue => error
|
||||||
|
rake_say error.message
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
namespace :foodsoft do
|
namespace :foodsoft do
|
||||||
desc "Parse incoming email on stdin (options: RECIPIENT=f.1.2.a1b2c3d3e5)"
|
desc "Parse incoming email on stdin (options: RECIPIENT=f.1.2.a1b2c3d3e5)"
|
||||||
task :parse_reply_email => :environment do
|
task :parse_reply_email => :environment do
|
||||||
m = /(?<foodcoop>[^@]*)\.(?<message_id>\d+)\.(?<user_id>\d+)\.(?<hash>\w+)(@(?<hostname>.*))?/.match(ENV['RECIPIENT'])
|
hande_mail(ENV['RECIPIENT'], STDIN.read)
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Start STMP server for incoming email (options: PORT=25, HOST=0.0.0.0)"
|
||||||
|
task :reply_email_smtp_server => :environment do
|
||||||
|
port = ENV['PORT'].to_i
|
||||||
|
host = ENV['HOST']
|
||||||
|
rake_say "Started SMTP server for incomming email on port #{port}."
|
||||||
|
server = ReplyEmailSmtpServer.new(port, host)
|
||||||
|
server.start
|
||||||
|
server.join
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def hande_mail(recipient, received_email)
|
||||||
|
m = /(?<foodcoop>[^@]*)\.(?<message_id>\d+)\.(?<user_id>\d+)\.(?<hash>\w+)(@(?<hostname>.*))?/.match(recipient)
|
||||||
|
|
||||||
raise "RECIPIENT is missing or has an invalid format" if m.nil?
|
raise "RECIPIENT is missing or has an invalid format" if m.nil?
|
||||||
raise "Foodcoop '#{m[:foodcoop]}' could not be found" unless FoodsoftConfig.foodcoops.include? m[:foodcoop]
|
raise "Foodcoop '#{m[:foodcoop]}' could not be found" unless FoodsoftConfig.foodcoops.include? m[:foodcoop]
|
||||||
|
@ -18,7 +46,6 @@ namespace :foodsoft do
|
||||||
hash = original_message.mail_hash_for_user user
|
hash = original_message.mail_hash_for_user user
|
||||||
raise "Hash does not match expectations" unless hash.casecmp(m[:hash]) == 0
|
raise "Hash does not match expectations" unless hash.casecmp(m[:hash]) == 0
|
||||||
|
|
||||||
received_email = STDIN.read
|
|
||||||
mail = Mail.new received_email
|
mail = Mail.new received_email
|
||||||
|
|
||||||
mail_part = nil
|
mail_part = nil
|
||||||
|
@ -51,7 +78,6 @@ namespace :foodsoft do
|
||||||
message.save!
|
message.save!
|
||||||
Resque.enqueue(MessageNotifier, FoodsoftConfig.scope, "message_deliver", message.id)
|
Resque.enqueue(MessageNotifier, FoodsoftConfig.scope, "message_deliver", message.id)
|
||||||
rake_say "Handled reply email from #{user.display}."
|
rake_say "Handled reply email from #{user.display}."
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Helper
|
# Helper
|
||||||
|
|
Loading…
Reference in a new issue