avarteq-email2sms 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|