avarteq-email2sms 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +13 -0
- data/README.textile +98 -0
- data/Rakefile +56 -0
- data/VERSION +1 -0
- data/bin/email2smsd +15 -0
- data/config/email2sms.yml +21 -0
- data/email2sms.gemspec +54 -0
- data/lib/config.rb +54 -0
- data/lib/email2sms_main.rb +37 -0
- data/lib/email_to_sms.rb +144 -0
- data/lib/filter/basic_filter.rb +10 -0
- data/lib/filter/filter_chain.rb +42 -0
- data/lib/filter/subject_filter.rb +24 -0
- data/lib/mail/imap_tools.rb +52 -0
- data/lib/mail/tmail_tools.rb +40 -0
- data/pkg/email2sms-0.2.0.gem +0 -0
- metadata +68 -0
data/.gitignore
ADDED
data/README.textile
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
h1. Email2sms
|
2
|
+
|
3
|
+
p>. !http://farm3.static.flickr.com/2545/3859077628_55156d5b3e_t.jpg(Avarteq GmbH)!:http://www.avarteq.de
|
4
|
+
|
5
|
+
Email2sms has been developed by "www.avarteq.de":http://www.avarteq.de.
|
6
|
+
|
7
|
+
Email2sms is a free and pure Ruby E-Mail to sms gateway including an extensible filterchain to filter and manipulate incoming emails before sending them as text messages.
|
8
|
+
|
9
|
+
h1. Requirements
|
10
|
+
|
11
|
+
In order to run Email2sms you will need the following.
|
12
|
+
|
13
|
+
* IMAP Mailbox
|
14
|
+
* DeveloperGarden Account with credits. Have a look at "developergarden.com":http://www.developergarden.com
|
15
|
+
|
16
|
+
h2. Required gems
|
17
|
+
|
18
|
+
* developergarden_sdk
|
19
|
+
* tmail
|
20
|
+
|
21
|
+
h1. Configuration
|
22
|
+
|
23
|
+
The first time you start email2smd it will create the following directory:
|
24
|
+
|
25
|
+
bc. ENV["HOME"]/.email2sms
|
26
|
+
|
27
|
+
Which basically means that it will create the hidden directory email2sms in your home directory (~/).
|
28
|
+
|
29
|
+
In addition to this it will create a configuration file template:
|
30
|
+
|
31
|
+
bc. ~/.email2sms/email2sms.yml
|
32
|
+
|
33
|
+
Now it's you turn:
|
34
|
+
|
35
|
+
Open the config file and adapt it to your needs.
|
36
|
+
|
37
|
+
h1. Usage
|
38
|
+
|
39
|
+
The basic usage of email2sms is straight forward. It's mainly about starting and stopping the daemon.
|
40
|
+
Type
|
41
|
+
|
42
|
+
bc. email2smsd -h
|
43
|
+
|
44
|
+
to get more information. This help is generated by the daemon gem so this message is not application specific but it will give you to get a short introduction about how to control the daemon.
|
45
|
+
|
46
|
+
h2. Start
|
47
|
+
|
48
|
+
bc. email2smd start
|
49
|
+
|
50
|
+
h2. Stop
|
51
|
+
|
52
|
+
bc. email2smsd stop
|
53
|
+
|
54
|
+
Watch output in
|
55
|
+
|
56
|
+
bc. email2sms_main.rb.output
|
57
|
+
|
58
|
+
and
|
59
|
+
|
60
|
+
bc. email2sms_main.rb.log
|
61
|
+
|
62
|
+
for detailed application state information and errors.
|
63
|
+
|
64
|
+
The files are located in the folder you have configured in your configuration file.
|
65
|
+
By default this is the directory from where you have started the daemon.
|
66
|
+
|
67
|
+
h2. Send e-mail
|
68
|
+
|
69
|
+
**Ok, now you are ready:**
|
70
|
+
|
71
|
+
In order to send an sms just send an email to the email adress configured in the email2sms.yml file.
|
72
|
+
If you use the subject filter then you will need to have the password in your subject line:
|
73
|
+
|
74
|
+
bc. Subject:
|
75
|
+
mypass +49177 12344567
|
76
|
+
Message body:
|
77
|
+
Whatever
|
78
|
+
|
79
|
+
**That's it. Have fun!**
|
80
|
+
|
81
|
+
h1. Contact
|
82
|
+
|
83
|
+
* You would like to have a customized version of email2sms for your project but don't want to do the dirty work?
|
84
|
+
* Do you like email2sms but want to have an hosted solution?
|
85
|
+
* Want to argue about the Ruby and the meaning of life?
|
86
|
+
|
87
|
+
Feel free to contact us:
|
88
|
+
|
89
|
+
Avarteq GmbH
|
90
|
+
Julian Fischer
|
91
|
+
email2sms@avarteq.de
|
92
|
+
"www.avarteq.de":http://www.avarteq.de
|
93
|
+
|
94
|
+
Also checkout our hosting services:
|
95
|
+
"www.railshoster.de":http://www.railshoster.de
|
96
|
+
and
|
97
|
+
"www.enterprise-rails.de":http://www.enterprise-rails.de
|
98
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "email2sms"
|
8
|
+
gem.summary = "Pure Ruby e-mail to sms gateway"
|
9
|
+
gem.description = "Free and pure Ruby E-Mail to sms gateway including an extensible filterchain to filter and manipulate incoming emails before sending them as text messages."
|
10
|
+
gem.email = "email2sms@avarteq.de"
|
11
|
+
gem.homepage = "http://github.com/avarteq/email2sms"
|
12
|
+
gem.authors = ["Julian Fischer"]
|
13
|
+
# gem.add_development_dependency "developergarden_sdk"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'rake/testtask'
|
21
|
+
Rake::TestTask.new(:test) do |test|
|
22
|
+
test.libs << 'lib' << 'test'
|
23
|
+
test.pattern = 'test/**/*_test.rb'
|
24
|
+
test.verbose = true
|
25
|
+
end
|
26
|
+
|
27
|
+
begin
|
28
|
+
require 'rcov/rcovtask'
|
29
|
+
Rcov::RcovTask.new do |test|
|
30
|
+
test.libs << 'test'
|
31
|
+
test.pattern = 'test/**/*_test.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
rescue LoadError
|
35
|
+
task :rcov do
|
36
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
task :test => :check_dependencies
|
41
|
+
|
42
|
+
task :default => :test
|
43
|
+
|
44
|
+
require 'rake/rdoctask'
|
45
|
+
Rake::RDocTask.new do |rdoc|
|
46
|
+
if File.exist?('VERSION')
|
47
|
+
version = File.read('VERSION')
|
48
|
+
else
|
49
|
+
version = ""
|
50
|
+
end
|
51
|
+
|
52
|
+
rdoc.rdoc_dir = 'rdoc'
|
53
|
+
rdoc.title = "email2sms #{version}"
|
54
|
+
rdoc.rdoc_files.include('README*')
|
55
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
56
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.4.0
|
data/bin/email2smsd
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
gem 'daemons'
|
5
|
+
require 'daemons'
|
6
|
+
require File.dirname(__FILE__) + '/../lib/' + 'config.rb'
|
7
|
+
|
8
|
+
daemon_options = {
|
9
|
+
:backtrace => true,
|
10
|
+
:log_output => true,
|
11
|
+
:dir_mode => :normal,
|
12
|
+
:dir => Config.logdir
|
13
|
+
}
|
14
|
+
|
15
|
+
Daemons.run(File.dirname(__FILE__) + '/../lib/' + 'email2sms_main.rb', daemon_options)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
general:
|
2
|
+
default_charset: "UTF-8"
|
3
|
+
dev_garden:
|
4
|
+
user: "yourdevguser@t-online.de"
|
5
|
+
pass: "yourdevgpass"
|
6
|
+
imap:
|
7
|
+
server_host: 'mail.yourmailserver.de'
|
8
|
+
user: 'yourimapuser@yourdomain.de'
|
9
|
+
pass: 'yourimappass'
|
10
|
+
poll_interval: 10
|
11
|
+
sms:
|
12
|
+
sender_name: "Email2Sms"
|
13
|
+
filter_chain:
|
14
|
+
subject_filter:
|
15
|
+
password: "Aihie4ca6a"
|
16
|
+
log:
|
17
|
+
# dir_mode = normal => dir will be interpreted as dir
|
18
|
+
# dir_mode = current => dir will be ignored. Logs will go to the folder from where
|
19
|
+
# the app has been started.
|
20
|
+
dir_mode: "normal"
|
21
|
+
dir: "default"
|
data/email2sms.gemspec
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{email2sms}
|
8
|
+
s.version = "0.4.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Julian Fischer"]
|
12
|
+
s.date = %q{2009-08-27}
|
13
|
+
s.default_executable = %q{email2smsd}
|
14
|
+
s.description = %q{Free and pure Ruby E-Mail to sms gateway including an extensible filterchain to filter and manipulate incoming emails before sending them as text messages.}
|
15
|
+
s.email = %q{email2sms@avarteq.de}
|
16
|
+
s.executables = ["email2smsd"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"README.textile"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
".gitignore",
|
22
|
+
"README.textile",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"bin/email2smsd",
|
26
|
+
"config/email2sms.yml",
|
27
|
+
"email2sms.gemspec",
|
28
|
+
"lib/config.rb",
|
29
|
+
"lib/email2sms_main.rb",
|
30
|
+
"lib/email_to_sms.rb",
|
31
|
+
"lib/filter/basic_filter.rb",
|
32
|
+
"lib/filter/filter_chain.rb",
|
33
|
+
"lib/filter/subject_filter.rb",
|
34
|
+
"lib/mail/imap_tools.rb",
|
35
|
+
"lib/mail/tmail_tools.rb",
|
36
|
+
"pkg/email2sms-0.2.0.gem"
|
37
|
+
]
|
38
|
+
s.has_rdoc = true
|
39
|
+
s.homepage = %q{http://github.com/avarteq/email2sms}
|
40
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
41
|
+
s.require_paths = ["lib"]
|
42
|
+
s.rubygems_version = %q{1.3.1}
|
43
|
+
s.summary = %q{Pure Ruby e-mail to sms gateway}
|
44
|
+
|
45
|
+
if s.respond_to? :specification_version then
|
46
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
47
|
+
s.specification_version = 2
|
48
|
+
|
49
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
50
|
+
else
|
51
|
+
end
|
52
|
+
else
|
53
|
+
end
|
54
|
+
end
|
data/lib/config.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
module Config
|
2
|
+
def self.load
|
3
|
+
config_filename = "email2sms.yml"
|
4
|
+
default_config = YAML.load_file(File.dirname(__FILE__) + "/../config/" + config_filename)
|
5
|
+
default_config_file_path = File.dirname(__FILE__) + "/../config/email2sms.yml"
|
6
|
+
|
7
|
+
config_dir = ENV["HOME"] + "/.email2sms"
|
8
|
+
config_file_path = config_dir + "/" + config_filename
|
9
|
+
|
10
|
+
# Check or create config dir
|
11
|
+
exists_or_create_dir(config_dir)
|
12
|
+
|
13
|
+
# Check or create config file
|
14
|
+
unless File.exists?(config_file_path) then
|
15
|
+
puts "\n\n-------------------------------------\n"
|
16
|
+
puts "Didn't find a configuration file in #{config_file_path}. First start?"
|
17
|
+
puts "I am going to create a configuration file template for you under #{config_file_path}."
|
18
|
+
puts "Please adapt it to your needs and start the daemon again."
|
19
|
+
puts "-------------------------------------\n\n"
|
20
|
+
config_file = File.new(config_file_path, "w+")
|
21
|
+
config_file.puts File.open(default_config_file_path).read
|
22
|
+
end
|
23
|
+
|
24
|
+
config = YAML.load_file(config_file_path)
|
25
|
+
config
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.logdir
|
29
|
+
mylogdir = ""
|
30
|
+
|
31
|
+
config = self.load
|
32
|
+
|
33
|
+
# If there is no configuration file, it will be generated but it wouldn't make
|
34
|
+
# sense to load it. The user has to customize it, first.
|
35
|
+
if config
|
36
|
+
if config["log"]["dir_mode"] == "current" then
|
37
|
+
mylogdir = Dir.pwd
|
38
|
+
elsif config["log"]["dir_mode"] == "normal" then
|
39
|
+
mylogdir = config["log"]["dir"]
|
40
|
+
exists_or_create_dir(mylogdir)
|
41
|
+
else
|
42
|
+
raise "Unknown log dir_mode #{config[:log][:dir_mode]}. Possible values are: 'current' and 'normal'."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
mylogdir || Dir.pwd
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
# Checks whether the given dir exists. Creates it if not.
|
51
|
+
def self.exists_or_create_dir(dir)
|
52
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
gem 'developergarden_sdk'
|
5
|
+
require 'sms_service/sms_service'
|
6
|
+
require 'quota_service/quota_service'
|
7
|
+
require 'tmail'
|
8
|
+
|
9
|
+
require File.dirname(__FILE__) + '/../lib/' + 'config.rb'
|
10
|
+
require File.dirname(__FILE__) + '/../lib/' + 'mail/tmail_tools'
|
11
|
+
require File.dirname(__FILE__) + '/../lib/' + 'mail/imap_tools'
|
12
|
+
require File.dirname(__FILE__) + '/../lib/' + 'email_to_sms'
|
13
|
+
require File.dirname(__FILE__) + '/../lib/' + 'filter/filter_chain'
|
14
|
+
require File.dirname(__FILE__) + '/../lib/' + 'filter/basic_filter'
|
15
|
+
require File.dirname(__FILE__) + '/../lib/' + 'filter/subject_filter'
|
16
|
+
|
17
|
+
# Catching the exit signal and
|
18
|
+
Signal.trap(0, proc do
|
19
|
+
puts "Stopping email2sms"
|
20
|
+
email2sms.close
|
21
|
+
end
|
22
|
+
)
|
23
|
+
|
24
|
+
Net::IMAP.debug = true if $DEBUG
|
25
|
+
|
26
|
+
CONFIG = Config.load
|
27
|
+
|
28
|
+
puts "Creating email2sms main class"
|
29
|
+
email2sms = EmailToSms.new( EmailToSms.ENVIRONMENT_PRODUCTION )
|
30
|
+
|
31
|
+
puts "Entering dispatch loop"
|
32
|
+
loop do
|
33
|
+
email2sms.dispatch
|
34
|
+
sleep CONFIG["imap"]["poll_interval"]
|
35
|
+
end
|
36
|
+
|
37
|
+
|
data/lib/email_to_sms.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'net/imap'
|
2
|
+
|
3
|
+
class EmailToSms
|
4
|
+
|
5
|
+
include Mail::ImapTools
|
6
|
+
include Mail::TmailTools
|
7
|
+
|
8
|
+
@@SENT_SMS_MAILBOX = "sent_sms"
|
9
|
+
@@ERROR_SMS_MAILBOX = "error"
|
10
|
+
@@FILTERED_MAILBOX = "filtered"
|
11
|
+
@@ENVIRONMENT_MOCK = 2
|
12
|
+
@@ENVIRONMENT_PRODUCTION = 1
|
13
|
+
@@CONFIG = Config.load
|
14
|
+
|
15
|
+
def initialize(environment = @@ENVIRONMENT_MOCK)
|
16
|
+
@charset = @@CONFIG["general"]["default_charset"]
|
17
|
+
@environment = environment
|
18
|
+
@filter_chain = FilterChain.build_simple_filter_chain(@@CONFIG, @charset)
|
19
|
+
dev_garden_user = @@CONFIG["dev_garden"]["user"]
|
20
|
+
dev_garden_pass = @@CONFIG["dev_garden"]["pass"]
|
21
|
+
@sms_service = SmsService::SmsService.new(dev_garden_user, dev_garden_pass)
|
22
|
+
@imap = Net::IMAP.new(@@CONFIG["imap"]["server_host"])
|
23
|
+
imap_user = @@CONFIG["imap"]["user"]
|
24
|
+
imap_pass = @@CONFIG["imap"]["pass"]
|
25
|
+
|
26
|
+
@imap.authenticate('LOGIN', imap_user, imap_pass)
|
27
|
+
status_or_create_mailboxes
|
28
|
+
end
|
29
|
+
|
30
|
+
# See which emails to send
|
31
|
+
def dispatch
|
32
|
+
@imap.select('INBOX')
|
33
|
+
puts "Checking mailbox..."
|
34
|
+
@imap.uid_search(["UNSEEN"]).each do |uid_unseen|
|
35
|
+
tmail_unseen = tmail_from_imap(uid_unseen)
|
36
|
+
|
37
|
+
# Only mails passing all filters will be delivered.
|
38
|
+
# Be aware that filters might modify the mail.
|
39
|
+
passed = @filter_chain.passed_filter?(tmail_unseen)
|
40
|
+
|
41
|
+
if not passed then
|
42
|
+
puts "E-mail has been filtered."
|
43
|
+
move_email(uid_unseen, @@FILTERED_MAILBOX)
|
44
|
+
else
|
45
|
+
puts "Sending E-mail as text message..."
|
46
|
+
send_email_as_sms(uid_unseen, tmail_unseen)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Close imap connection
|
52
|
+
def close
|
53
|
+
@imap.close
|
54
|
+
@imap.disconnect
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
def tmail_from_imap(uid)
|
60
|
+
# Get the email in rfc822 format
|
61
|
+
mail_rfc822 = @imap.uid_fetch(uid, 'RFC822')[0].attr['RFC822']
|
62
|
+
|
63
|
+
# A TMail object hides all the quoting and parsing stuff
|
64
|
+
tmail = TMail::Mail.parse( mail_rfc822 )
|
65
|
+
tmail
|
66
|
+
end
|
67
|
+
|
68
|
+
# Created needed imap folders
|
69
|
+
def status_or_create_mailboxes
|
70
|
+
[@@SENT_SMS_MAILBOX, @@FILTERED_MAILBOX, @@ERROR_SMS_MAILBOX].each do |mailbox|
|
71
|
+
status_or_create_mailbox(mailbox)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def send_email_as_sms(uid, tmail)
|
76
|
+
final_sms_message = sms_message_from(tmail)
|
77
|
+
receiver = get_receiver_from_subject(tmail)
|
78
|
+
sms_sender_name = @@CONFIG["sms"]["sender_name"]
|
79
|
+
|
80
|
+
if @environment == @@ENVIRONMENT_PRODUCTION then
|
81
|
+
send_email_as_sms_production(uid, receiver, final_sms_message, sms_sender_name)
|
82
|
+
else
|
83
|
+
send_email_as_sms_mock(uid, tmail, receiver, final_sms_message)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def send_email_as_sms_production(uid, receiver, final_sms_message, sms_sender_name)
|
88
|
+
rescue_send_sms_exceptions(uid) do |uid|
|
89
|
+
@sms_service.send_sms(receiver, final_sms_message, sms_sender_name, ServiceEnvironment.PRODUCTION)
|
90
|
+
puts "Text message has ben sent."
|
91
|
+
|
92
|
+
# Copy mail to sent_sms folder
|
93
|
+
move_email(uid, @@SENT_SMS_MAILBOX)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def send_email_as_sms_mock(uid, tmail, receiver, final_sms_message)
|
98
|
+
|
99
|
+
# MOCK environment so we don't send any sms just print it out
|
100
|
+
puts_tmail(tmail)
|
101
|
+
puts_sms(receiver, final_sms_message)
|
102
|
+
|
103
|
+
# Copy mail to sent_sms folder
|
104
|
+
move_email(uid, @@SENT_SMS_MAILBOX)
|
105
|
+
end
|
106
|
+
|
107
|
+
def rescue_send_sms_exceptions(uid, &block)
|
108
|
+
begin
|
109
|
+
yield(uid)
|
110
|
+
rescue ServiceException => e
|
111
|
+
r = e.response
|
112
|
+
puts "\tError while sending sms.\n\t\tError message: #{r.error_message}\n\t\tError code: #{r.error_code}"
|
113
|
+
|
114
|
+
# Copy mail to sent_sms folder
|
115
|
+
move_email(uid, @@ERROR_SMS_MAILBOX)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def sms_message_from(tmail)
|
120
|
+
final_sms_message = tmail_to_plaintext(tmail)
|
121
|
+
|
122
|
+
# Shorten message
|
123
|
+
final_sms_message = final_sms_message.strip![0, 150]
|
124
|
+
final_sms_message
|
125
|
+
end
|
126
|
+
|
127
|
+
# Print the given sms message to stdout
|
128
|
+
def puts_sms(receiver, final_sms_message)
|
129
|
+
puts "\n\n-----------------------"
|
130
|
+
puts "Text message to #{receiver}:"
|
131
|
+
puts final_sms_message
|
132
|
+
puts "-----------------------\n\n"
|
133
|
+
end
|
134
|
+
|
135
|
+
#### Public static methods
|
136
|
+
|
137
|
+
def self.ENVIRONMENT_MOCK
|
138
|
+
return @@ENVIRONMENT_MOCK
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.ENVIRONMENT_PRODUCTION
|
142
|
+
return @@ENVIRONMENT_PRODUCTION
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# The filter chain is responsible for deciding which mail to forward and which to drop.
|
2
|
+
# The filter chain can consist of one ore more filters each analysing and/or modifing the incoming
|
3
|
+
# mail.
|
4
|
+
class FilterChain
|
5
|
+
|
6
|
+
def initialize(config)
|
7
|
+
@filters = []
|
8
|
+
@config = config
|
9
|
+
end
|
10
|
+
|
11
|
+
def <<(filter)
|
12
|
+
@filters << filter
|
13
|
+
end
|
14
|
+
|
15
|
+
def add(filter)
|
16
|
+
@filters << filter
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete(filter)
|
20
|
+
@filters.delete(filter)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Execute each filter, stop of a filter rejects the mail
|
24
|
+
def passed_filter?(tmail)
|
25
|
+
ret = true
|
26
|
+
for filter in @filters do
|
27
|
+
if not filter.passed_filter?(tmail) then
|
28
|
+
ret = false
|
29
|
+
break
|
30
|
+
end
|
31
|
+
end
|
32
|
+
return ret
|
33
|
+
end
|
34
|
+
|
35
|
+
# Factory method to create a simple filter chaing using a SubjectFilter.
|
36
|
+
def self.build_simple_filter_chain(config, charset = "UTF-8")
|
37
|
+
filter_chain = self.new(config)
|
38
|
+
subject_filter_password = config["filter_chain"]["subject_filter"]["password"]
|
39
|
+
filter_chain << SubjectFilter.new(subject_filter_password, charset)
|
40
|
+
return filter_chain
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Checks the subject of the incomming message for a specific password and rejects the mail if the
|
2
|
+
# passwort is not present.
|
3
|
+
class SubjectFilter < BasicFilter
|
4
|
+
|
5
|
+
def initialize(password, charset = "UTF-8")
|
6
|
+
super(charset)
|
7
|
+
@password = password
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns true if password is present.
|
11
|
+
# Password will be removed from the subject.
|
12
|
+
def passed_filter?(tmail)
|
13
|
+
password_is_present = !tmail.subject.match(@password).nil?
|
14
|
+
|
15
|
+
password_matcher = Regexp.new("#{@password}\s+")
|
16
|
+
|
17
|
+
if password_is_present then
|
18
|
+
# Remove password from the subject
|
19
|
+
tmail.subject = tmail.subject(@charset).gsub(password_matcher, "")
|
20
|
+
end
|
21
|
+
|
22
|
+
return password_is_present
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# IMAP related methods
|
2
|
+
module Mail
|
3
|
+
module ImapTools
|
4
|
+
|
5
|
+
# Deletes the email with the given uid
|
6
|
+
def delete_email(uid)
|
7
|
+
@imap.uid_store(uid, "+FLAGS", [:Deleted])
|
8
|
+
@imap.expunge
|
9
|
+
end
|
10
|
+
|
11
|
+
# Move a mail from the current to the given mailbox.
|
12
|
+
def move_email(uid, mailbox)
|
13
|
+
|
14
|
+
# Copy mail to sent_sms folder
|
15
|
+
@imap.uid_copy(uid, mailbox)
|
16
|
+
delete_email(uid)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Checks whether the given mailbox exists and creates it if not.
|
20
|
+
# If it exists it will be selected.
|
21
|
+
#TODO check imap protocoll if there isn't a better way to do this.
|
22
|
+
# === Parameters
|
23
|
+
# <tt>mailbox</tt>:: Name of the mailbox (imap folder)
|
24
|
+
# <tt>raise_on_select</tt>:: Raise an exception if a select is not possible. This also skips creation of the mailbox. Used for internal purposes.
|
25
|
+
def status_or_create_mailbox(mailbox, raise_on_select = false)
|
26
|
+
ret = nil
|
27
|
+
|
28
|
+
begin
|
29
|
+
ret = @imap.status(mailbox, ["MESSAGES", "RECENT", "UNSEEN"])
|
30
|
+
# Mailbox already exists
|
31
|
+
rescue Net::IMAP::NoResponseError => e
|
32
|
+
|
33
|
+
# The mailbox does not exist (or is non-selectable for some reason)
|
34
|
+
unless raise_on_select
|
35
|
+
|
36
|
+
# So we create it
|
37
|
+
@imap.create(mailbox)
|
38
|
+
puts "Created mailbox #{mailbox}."
|
39
|
+
|
40
|
+
# And select it
|
41
|
+
status_or_create_mailbox(mailbox, true)
|
42
|
+
else
|
43
|
+
|
44
|
+
# For some reasons the creation/selection of the mailbox failed.
|
45
|
+
# In order to avoid an infinte loop we give up after trying to create and select the mailbox once.
|
46
|
+
raise e
|
47
|
+
end
|
48
|
+
end
|
49
|
+
return ret
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Mail
|
2
|
+
module TmailTools
|
3
|
+
|
4
|
+
# Prints the given tmail object to stdout
|
5
|
+
def puts_tmail(tmail)
|
6
|
+
puts "\n\n-----------------------"
|
7
|
+
puts "E-Mail message:"
|
8
|
+
puts tmail.subject
|
9
|
+
puts tmail_to_plaintext(tmail)
|
10
|
+
puts "-----------------------\n\n"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Extracts the receiver's number from the email subject
|
14
|
+
def get_receiver_from_subject(tmail)
|
15
|
+
return tmail.subject(@charset).strip
|
16
|
+
end
|
17
|
+
|
18
|
+
# If it is a multipart email with a plain text part
|
19
|
+
# it searches for the text/plain part of the mail and returns it.
|
20
|
+
def tmail_to_plaintext(tmail)
|
21
|
+
ret = nil
|
22
|
+
if tmail.multipart? then
|
23
|
+
plain_text_body_from_multipart(tmail)
|
24
|
+
else
|
25
|
+
ret = tmail.body(@charset)
|
26
|
+
end
|
27
|
+
ret
|
28
|
+
end
|
29
|
+
|
30
|
+
# Extraxt the plain text body from a multipart email
|
31
|
+
def plain_text_body_from_multipart(tmail)
|
32
|
+
ret = nil
|
33
|
+
tmail.parts.each do |part|
|
34
|
+
ret = part.body(@charset) if part.content_type == 'text/plain'
|
35
|
+
break
|
36
|
+
end
|
37
|
+
ret
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: avarteq-email2sms
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Julian Fischer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-27 00:00:00 -07:00
|
13
|
+
default_executable: email2smsd
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Free and pure Ruby E-Mail to sms gateway including an extensible filterchain to filter and manipulate incoming emails before sending them as text messages.
|
17
|
+
email: email2sms@avarteq.de
|
18
|
+
executables:
|
19
|
+
- email2smsd
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.textile
|
24
|
+
files:
|
25
|
+
- .gitignore
|
26
|
+
- README.textile
|
27
|
+
- Rakefile
|
28
|
+
- VERSION
|
29
|
+
- bin/email2smsd
|
30
|
+
- config/email2sms.yml
|
31
|
+
- email2sms.gemspec
|
32
|
+
- lib/config.rb
|
33
|
+
- lib/email2sms_main.rb
|
34
|
+
- lib/email_to_sms.rb
|
35
|
+
- lib/filter/basic_filter.rb
|
36
|
+
- lib/filter/filter_chain.rb
|
37
|
+
- lib/filter/subject_filter.rb
|
38
|
+
- lib/mail/imap_tools.rb
|
39
|
+
- lib/mail/tmail_tools.rb
|
40
|
+
- pkg/email2sms-0.2.0.gem
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://github.com/avarteq/email2sms
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options:
|
45
|
+
- --charset=UTF-8
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 1.2.0
|
64
|
+
signing_key:
|
65
|
+
specification_version: 2
|
66
|
+
summary: Pure Ruby e-mail to sms gateway
|
67
|
+
test_files: []
|
68
|
+
|