actionmailbox-imap 0.1.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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +82 -0
- data/Rakefile +27 -0
- data/lib/actionmailbox/imap.rb +29 -0
- data/lib/actionmailbox/imap/adapters/net_imap.rb +47 -0
- data/lib/actionmailbox/imap/mailbox.rb +21 -0
- data/lib/actionmailbox/imap/message.rb +28 -0
- data/lib/actionmailbox/imap/messages.rb +33 -0
- data/lib/actionmailbox/imap/railtie.rb +10 -0
- data/lib/actionmailbox/imap/version.rb +5 -0
- data/lib/generators/imap/install_generator.rb +7 -0
- data/lib/generators/imap/templates/config.yml +14 -0
- data/lib/tasks/actionmailbox/ingress.rake +39 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cce84e603505d4bdcb54d4935e5378acd69e3c0426dad9cbf3d3195801260862
|
4
|
+
data.tar.gz: f9a75e4fe6651894c49c3784f8a068ad015b3d54c1621bb33cbeb3887e03c1c4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e7d9ab1a7b2c4b8a16ffe2c0fd97f5b85885ad607160985ea77db290f1aa095db72ea64d81ff59d68e9271a58adc6fe7edced957aa6eba5ad0514017ceb3773f
|
7
|
+
data.tar.gz: 8fa950ea432d4ec17a5f32b3e0ac253dd16a7bae2d8ab34bcbb2b0c5fcbc7e6b7c1014eec4f0248bd5f0d32bf023a71dfacfd23a8d410c4ff4e94811bf489338
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2019 Ethan Knowlton
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# Actionmailbox::IMAP
|
2
|
+
[](https://circleci.com/gh/kimmelsg/actionmailbox-imap)
|
3
|
+
|
4
|
+
A IMAP relay for ActionMailbox.
|
5
|
+
|
6
|
+
This is a very simple gem that provides a rake task which will connect to an IMAP server, grab some (`take`) emails, attempt to relay them to ActionMailbox.
|
7
|
+
|
8
|
+
If the rake task successfully relays a message to ActionMailbox then it will flag the message as "Deleted" on the IMAP server, and continue to the next message.
|
9
|
+
|
10
|
+
If the rake task fails to relay a message to ActionMailbox then it will ignore it and move on to the next message leaving the message on the IMAP server.
|
11
|
+
|
12
|
+
### Why it was created
|
13
|
+
|
14
|
+
It seems that there is no plans to create some sort of IMAP implementation relay in ActionMailbox.
|
15
|
+
https://github.com/rails/actionmailbox/issues/14
|
16
|
+
|
17
|
+
There is probably a reason for this. We did not want to setup or maintain a mailserver which would probably be the route to go for a robust inboud email application.
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### Install ActionMailbox
|
22
|
+
|
23
|
+
Per [ActionMailbox documentation](https://edgeguides.rubyonrails.org/action_mailbox_basics.html)
|
24
|
+
|
25
|
+
```bash
|
26
|
+
$ rails action_mailbox:install
|
27
|
+
$ rails db:migrate
|
28
|
+
```
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
# config/environments/production.rb
|
32
|
+
config.action_mailbox.ingress = :relay
|
33
|
+
```
|
34
|
+
|
35
|
+
```bash
|
36
|
+
$ rails credentials:edit
|
37
|
+
```
|
38
|
+
|
39
|
+
```yaml
|
40
|
+
action_mailbox:
|
41
|
+
ingress_password: "YourIngressPassword"
|
42
|
+
```
|
43
|
+
|
44
|
+
|
45
|
+
### Install ActionMailbox::IMAP
|
46
|
+
|
47
|
+
```bash
|
48
|
+
$ rails g imap:install
|
49
|
+
```
|
50
|
+
|
51
|
+
Prepare your IMAP server and account by ensuring/creating the mailboxes for `ingress_mailbox`, ex: "INBOX".
|
52
|
+
|
53
|
+
Update the `config/imap.yml` that was generated to include server and credentials information, `ingress_mailbox` and an appropriate `take` amount ( the amount of emails to grab in a single run ).
|
54
|
+
|
55
|
+
Run or schedule `rails action_mailbox:ingress:imap URL="http://localhost/rails/action_mailbox/inbound_email" INGRESS_PASSWORD="YourIngressPassword"` to run at a selected interval.
|
56
|
+
|
57
|
+
The command behaves much like that of the other `action_mailbox:ingress:...` commands in that it relays the message the same way. Although messages should be piped to the other ingress commands and `rails action_mailbox:ingress:imap ...` needs to be scheduled appropriately.
|
58
|
+
|
59
|
+
## Installation
|
60
|
+
Add this line to your application's Gemfile:
|
61
|
+
( Gem is not published to rubygems.org currently, you can point to this github url though )
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
gem 'actionmailbox-imap'
|
65
|
+
```
|
66
|
+
|
67
|
+
And then execute:
|
68
|
+
```bash
|
69
|
+
$ bundle
|
70
|
+
```
|
71
|
+
|
72
|
+
Or install it yourself as:
|
73
|
+
```bash
|
74
|
+
$ gem install actionmailbox-imap
|
75
|
+
```
|
76
|
+
|
77
|
+
## Contributing
|
78
|
+
|
79
|
+
Want to contribute? Please do. PR's and passing tests (lint, test) will be required.
|
80
|
+
|
81
|
+
## License
|
82
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Actionmailbox::Imap'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'bundler/gem_tasks'
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
|
21
|
+
Rake::TestTask.new(:test) do |t|
|
22
|
+
t.libs << 'test'
|
23
|
+
t.pattern = 'test/**/*_test.rb'
|
24
|
+
t.verbose = false
|
25
|
+
end
|
26
|
+
|
27
|
+
task default: :test
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "actionmailbox/imap/railtie"
|
2
|
+
require "actionmailbox/imap/mailbox"
|
3
|
+
|
4
|
+
module ActionMailbox
|
5
|
+
module IMAP
|
6
|
+
class Base
|
7
|
+
def initialize(adapter:)
|
8
|
+
@adapter = adapter
|
9
|
+
end
|
10
|
+
|
11
|
+
def login(username:, password:)
|
12
|
+
adapter.login(username: username, password: password)
|
13
|
+
end
|
14
|
+
|
15
|
+
def select_mailbox(mailbox)
|
16
|
+
adapter.select_mailbox(mailbox)
|
17
|
+
Mailbox.new(adapter: adapter, mailbox: mailbox)
|
18
|
+
end
|
19
|
+
|
20
|
+
def disconnect
|
21
|
+
adapter.disconnect
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :adapter
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "net/imap"
|
2
|
+
|
3
|
+
module ActionMailbox
|
4
|
+
module IMAP
|
5
|
+
module Adapters
|
6
|
+
class NetImap
|
7
|
+
def initialize(server:, port: 993, usessl: true)
|
8
|
+
@imap = Net::IMAP.new(server, port, usessl)
|
9
|
+
end
|
10
|
+
|
11
|
+
def login(username:, password:)
|
12
|
+
imap.login(username, password)
|
13
|
+
end
|
14
|
+
|
15
|
+
def select_mailbox(mailbox)
|
16
|
+
imap.select(mailbox)
|
17
|
+
end
|
18
|
+
|
19
|
+
def disconnect
|
20
|
+
imap.expunge
|
21
|
+
imap.disconnect
|
22
|
+
end
|
23
|
+
|
24
|
+
def messages_not_deleted
|
25
|
+
imap.search(["NOT", "DELETED"])
|
26
|
+
end
|
27
|
+
|
28
|
+
def delete_message(id)
|
29
|
+
move_message_to(id, "TRASH")
|
30
|
+
end
|
31
|
+
|
32
|
+
def move_message_to(id, mailbox)
|
33
|
+
imap.copy(id, mailbox)
|
34
|
+
imap.store(id, "+FLAGS", [:Deleted])
|
35
|
+
end
|
36
|
+
|
37
|
+
def fetch_message_attr(id, attr)
|
38
|
+
imap.fetch(id, attr).first.attr[attr]
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
attr_reader :imap
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "actionmailbox/imap/messages"
|
2
|
+
|
3
|
+
module ActionMailbox
|
4
|
+
module IMAP
|
5
|
+
class Mailbox
|
6
|
+
def initialize(adapter:, mailbox:)
|
7
|
+
@adapter = adapter
|
8
|
+
@mailbox = mailbox
|
9
|
+
end
|
10
|
+
|
11
|
+
def not_deleted
|
12
|
+
result = adapter.messages_not_deleted
|
13
|
+
Messages.new(adapter: adapter, message_ids: result)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_reader :adapter, :mailbox
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ActionMailbox
|
2
|
+
module IMAP
|
3
|
+
class Message
|
4
|
+
RFC822 = "RFC822".freeze
|
5
|
+
|
6
|
+
def initialize(adapter:, id:)
|
7
|
+
@adapter = adapter
|
8
|
+
@id = id
|
9
|
+
end
|
10
|
+
|
11
|
+
def rfc822
|
12
|
+
adapter.fetch_message_attr(id, RFC822)
|
13
|
+
end
|
14
|
+
|
15
|
+
def delete
|
16
|
+
adapter.delete_message(id)
|
17
|
+
end
|
18
|
+
|
19
|
+
def move_to(mailbox)
|
20
|
+
adapter.move_message_to(id, mailbox)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :adapter, :id
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "actionmailbox/imap/message"
|
2
|
+
|
3
|
+
module ActionMailbox
|
4
|
+
module IMAP
|
5
|
+
class Messages
|
6
|
+
def initialize(adapter:, message_ids:)
|
7
|
+
@adapter = adapter
|
8
|
+
@message_ids = message_ids
|
9
|
+
end
|
10
|
+
|
11
|
+
def take(n)
|
12
|
+
taken_ids = message_ids.take(n)
|
13
|
+
Messages.new(adapter: adapter, message_ids: taken_ids)
|
14
|
+
end
|
15
|
+
|
16
|
+
def length
|
17
|
+
message_ids.length
|
18
|
+
end
|
19
|
+
|
20
|
+
def each
|
21
|
+
return unless block_given? # @TODO Need to test this branch
|
22
|
+
|
23
|
+
message_ids.each do |id|
|
24
|
+
yield Message.new(adapter: adapter, id: id)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :adapter, :message_ids
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
default: &default
|
2
|
+
server: <%= ENV.fetch("IMAP_SERVER") { "" } %>
|
3
|
+
port: <%= ENV.fetch("IMAP_PORT") { 993 } %>
|
4
|
+
usessl: <%= ENV.fetch("IMAP_USE_SSL") { true } %>
|
5
|
+
username: <%= ENV.fetch("IMAP_ACCOUNT_USERNAME") { "" } %>
|
6
|
+
password: <%= ENV.fetch("IMAP_ACCOUNT_PASSWORD") { "" } %>
|
7
|
+
ingress_mailbox: "INBOX"
|
8
|
+
take: <%= ENV.fetch("IMAP_TAKE") { 100 } %>
|
9
|
+
|
10
|
+
development:
|
11
|
+
<<: *default
|
12
|
+
|
13
|
+
production:
|
14
|
+
<<: *default
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "actionmailbox/imap/adapters/net_imap"
|
2
|
+
|
3
|
+
namespace :action_mailbox do
|
4
|
+
namespace :ingress do
|
5
|
+
task :environment do
|
6
|
+
require "active_support"
|
7
|
+
require "active_support/core_ext/object/blank"
|
8
|
+
require "action_mailbox/relayer"
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Relays inbound IMAP email to Action Mailbox (URL and INGRESS_PASSWORD required)"
|
12
|
+
task imap: "action_mailbox:ingress:environment" do
|
13
|
+
url, password = ENV.values_at("URL", "INGRESS_PASSWORD")
|
14
|
+
|
15
|
+
config = Rails.application.config_for(:actionmailbox_imap)
|
16
|
+
|
17
|
+
adapter = ActionMailbox::IMAP::Adapters::NetImap.new(
|
18
|
+
server: config[:server],
|
19
|
+
port: config[:port],
|
20
|
+
usessl: config[:usessl]
|
21
|
+
)
|
22
|
+
|
23
|
+
imap = ActionMailbox::IMAP::Base.new(adapter: adapter)
|
24
|
+
|
25
|
+
imap.login(username: config[:username], password: config[:password])
|
26
|
+
|
27
|
+
mailbox = imap.select_mailbox(config[:ingress_mailbox])
|
28
|
+
|
29
|
+
mailbox.not_deleted.take(config[:take]).each do |message|
|
30
|
+
ActionMailbox::Relayer.new(url: url, password: password).relay(message.rfc822).tap do |result|
|
31
|
+
message.delete if result.success?
|
32
|
+
message.move_to(config[:retry_mailbox]) unless result.success?
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
imap.disconnect
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: actionmailbox-imap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ethan Knowlton
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-08-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 6.0.0.rc2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 6.0.0.rc2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest-stub-const
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: standard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Relay IMAP messages to ActionMailbox
|
70
|
+
email:
|
71
|
+
- eknowlton@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- MIT-LICENSE
|
77
|
+
- README.md
|
78
|
+
- Rakefile
|
79
|
+
- lib/actionmailbox/imap.rb
|
80
|
+
- lib/actionmailbox/imap/adapters/net_imap.rb
|
81
|
+
- lib/actionmailbox/imap/mailbox.rb
|
82
|
+
- lib/actionmailbox/imap/message.rb
|
83
|
+
- lib/actionmailbox/imap/messages.rb
|
84
|
+
- lib/actionmailbox/imap/railtie.rb
|
85
|
+
- lib/actionmailbox/imap/version.rb
|
86
|
+
- lib/generators/imap/install_generator.rb
|
87
|
+
- lib/generators/imap/templates/config.yml
|
88
|
+
- lib/tasks/actionmailbox/ingress.rake
|
89
|
+
homepage: https://github.com/kimmelsg
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
metadata:
|
93
|
+
allowed_push_host: https://rubygems.org
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
requirements: []
|
109
|
+
rubygems_version: 3.0.1
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: Relay IMAP messages to ActionMailbox
|
113
|
+
test_files: []
|