talktome 0.2.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.md +17 -19
- data/README.md +132 -1
- data/lib/talktome.rb +39 -16
- data/lib/talktome/app.rb +61 -0
- data/lib/talktome/error.rb +1 -0
- data/lib/talktome/strategy/email.rb +16 -7
- data/lib/talktome/version.rb +3 -3
- data/spec/app/test_app.rb +90 -0
- data/spec/client/test_local.rb +33 -80
- data/spec/spec_helper.rb +2 -0
- metadata +73 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6ec4ba471da7a770b79a04a0f30cd58514f0d43b72d66b15074f2fa984887bd
|
4
|
+
data.tar.gz: 8a58f1a1e7af3440a8066e11b2fa44e4aa606c595c5b9d9e6952dd0b22d6fb97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7340d04e04977b3d1a4a5def53d02b141a108e67514886f57d0d22dc87dfe340fe3a52d8f4552e7bd074229ba841256bb8006bfc900485b48cd8f0aa86522b39
|
7
|
+
data.tar.gz: 961f6e4931782c5b0f0e732c9ab3a5ea0578efe76e0346bbd8782f3b21a3a8ecd58731b51e3d3dd2e32ccb0c2d9ef48f3081f1e2f810722fbb6320348deef796
|
data/LICENSE.md
CHANGED
@@ -1,22 +1,20 @@
|
|
1
|
-
|
1
|
+
Copyright (c) 2017-2021 - Enspirit SPRL (Bernard Lambeau)
|
2
2
|
|
3
|
-
|
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:
|
4
10
|
|
5
|
-
|
6
|
-
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
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
CHANGED
@@ -1,3 +1,134 @@
|
|
1
1
|
# Talktome - Talk to users easily
|
2
2
|
|
3
|
-
|
3
|
+
[![Build Status](https://travis-ci.com/enspirit/talktome.svg?branch=master)](https://travis-ci.com/enspirit/talktome)
|
4
|
+
|
5
|
+
Talktome helps talking to users (by email for now, but later we aim to add support
|
6
|
+
for various notification systems) easily. As a ruby gem to be used programmatically,
|
7
|
+
or as a docker container exposing web services (different use cases, see below).
|
8
|
+
|
9
|
+
## Using Talktome programmatically
|
10
|
+
|
11
|
+
Using Talktome programmatically is useful to send transactional emails to users.
|
12
|
+
|
13
|
+
```
|
14
|
+
require 'talktome'
|
15
|
+
CLIENT = Talktome::Client::Local.new(path_to_templates)
|
16
|
+
|
17
|
+
# later on
|
18
|
+
CLIENT.talktome(template_name, user, template_info, strategies)
|
19
|
+
|
20
|
+
# typically, the will send an email to foo@bar.com instantiating
|
21
|
+
# the email found in path_to_templates/hello/email.md and
|
22
|
+
# instantiated using mustache and markdown
|
23
|
+
CLIENT.talktome("hello", {email: 'foo@bar.com'}, {}, [:email])
|
24
|
+
```
|
25
|
+
|
26
|
+
## Using Talktome using the docker image
|
27
|
+
|
28
|
+
The docker image aims at supporting another category of use cases, such as providing
|
29
|
+
a reusable backend for contact forms.
|
30
|
+
|
31
|
+
```
|
32
|
+
docker run \
|
33
|
+
-p4567:4567 \
|
34
|
+
-e TALKTOME_EMAIL_DEFAULT_FROM=info@mydomain.com
|
35
|
+
-e TALKTOME_EMAIL_DEFAULT_TO=support@mydomain.com
|
36
|
+
enspirit/talktome
|
37
|
+
```
|
38
|
+
|
39
|
+
Send an contact-us email through the web api using curl, as follows:
|
40
|
+
|
41
|
+
```
|
42
|
+
curl -XPOST \
|
43
|
+
-H'Content-Type: application/json' \
|
44
|
+
-d'{"reply_to": "someone@foo.bar", "message": "Hello"}' \
|
45
|
+
http://127.0.0.1:4567/contact-us/
|
46
|
+
```
|
47
|
+
|
48
|
+
This web API does not allow specifying `from` and `to` as input data to avoid
|
49
|
+
exposing a way to send SPAM easily.
|
50
|
+
|
51
|
+
### Overriding templates (and having more than one endpoint)
|
52
|
+
|
53
|
+
The default image comes with a single contact-us email template used by Enspirit.
|
54
|
+
Feel free to override it by providing one or more email templates.
|
55
|
+
|
56
|
+
You can mount a volume with email templates into `/app/templates/`, which will
|
57
|
+
be used for the available endpoints. For instance, the following `templates/`
|
58
|
+
folder will expose two endpoints with possibly different behaviors (according
|
59
|
+
to the templates themselves):
|
60
|
+
|
61
|
+
```
|
62
|
+
templates/
|
63
|
+
contact-us/
|
64
|
+
email.md
|
65
|
+
report-issue/
|
66
|
+
email.md
|
67
|
+
```
|
68
|
+
|
69
|
+
Two usual ways to do so in docker: commandline or Dockerfile. On commandline,
|
70
|
+
use the following option:
|
71
|
+
|
72
|
+
```
|
73
|
+
-v ${PWD}/my-templates:/app/templates
|
74
|
+
```
|
75
|
+
|
76
|
+
In a Dockerfile, add your templates:
|
77
|
+
|
78
|
+
```
|
79
|
+
FROM enspirit/talktome
|
80
|
+
|
81
|
+
COPY ./templates /app/templates
|
82
|
+
```
|
83
|
+
|
84
|
+
## Configuring Talktome
|
85
|
+
|
86
|
+
The easiest way to configure Talktome is through environment variables. The following
|
87
|
+
ones are supported:
|
88
|
+
|
89
|
+
```
|
90
|
+
TALKTOME_DEBUG when set enables the dumping of sent messages to ./tmp folder
|
91
|
+
|
92
|
+
TALKTOME_EMAIL_DELIVERY smtp, file or test (see ruby Mail library)
|
93
|
+
TALKTOME_EMAIL_DEFAULT_FROM default From: to use for email sending
|
94
|
+
TALKTOME_EMAIL_DEFAULT_REPLYTO default Reply-To: to use for email sending
|
95
|
+
TALKTOME_EMAIL_DEFAULT_TO default To: to use for email sending
|
96
|
+
|
97
|
+
TALKTOME_SMTP_ADDRESS host address for smtp sending
|
98
|
+
TALKTOME_SMTP_PORT port of smtp server to use
|
99
|
+
TALKTOME_SMTP_DOMAIN sending domain
|
100
|
+
TALKTOME_SMTP_USER user for smtp authentication
|
101
|
+
TALKTOME_SMTP_PASSWORD password for smtp authentication
|
102
|
+
TALKTOME_SMTP_STARTTLS_AUTO true or false (see ruby Mail library)
|
103
|
+
```
|
104
|
+
|
105
|
+
## Hacking Talktome
|
106
|
+
|
107
|
+
In pure Ruby:
|
108
|
+
|
109
|
+
```
|
110
|
+
bundle install
|
111
|
+
bundle exec rake test
|
112
|
+
```
|
113
|
+
|
114
|
+
Or using docker, please then use the `make` targets initially cooked for Jenkins:
|
115
|
+
|
116
|
+
```
|
117
|
+
make image
|
118
|
+
make test
|
119
|
+
```
|
120
|
+
|
121
|
+
## Contributing
|
122
|
+
|
123
|
+
Please use github issues for questions and bugs, and pull requests for
|
124
|
+
submitting improvement proposals and new features.
|
125
|
+
|
126
|
+
## Contributors
|
127
|
+
|
128
|
+
Enspirit (https://enspirit.be) and Klaro App (https://klaro.cards) are
|
129
|
+
both actively using, contributing and funding work on this library.
|
130
|
+
Please contact Bernard Lambeau for any question.
|
131
|
+
|
132
|
+
## Licence
|
133
|
+
|
134
|
+
Webspicy is distributed under a MIT Licence, by Enspirit SRL.
|
data/lib/talktome.rb
CHANGED
@@ -4,25 +4,39 @@ require 'mustache'
|
|
4
4
|
require 'redcarpet'
|
5
5
|
module Talktome
|
6
6
|
|
7
|
+
# Root folder of the project structure
|
8
|
+
ROOT_FOLDER = Path.backfind('.[Gemfile]') or raise("Missing Gemfile")
|
9
|
+
|
10
|
+
def env(which, default = nil)
|
11
|
+
if ENV.has_key?(which)
|
12
|
+
got = ENV[which].to_s.strip
|
13
|
+
return got unless got.empty?
|
14
|
+
end
|
15
|
+
default
|
16
|
+
end
|
17
|
+
module_function :env
|
18
|
+
|
19
|
+
def with_env(which, &bl)
|
20
|
+
env(which).tap{|x|
|
21
|
+
bl.call(x) unless x.nil?
|
22
|
+
}
|
23
|
+
end
|
24
|
+
module_function :with_env
|
25
|
+
|
26
|
+
def set_env(which, value, &bl)
|
27
|
+
old, ENV[which] = ENV[which], value
|
28
|
+
bl.call.tap{
|
29
|
+
ENV[which] = old unless old.nil?
|
30
|
+
}
|
31
|
+
end
|
32
|
+
module_function :set_env
|
33
|
+
|
7
34
|
def redcarpet
|
8
35
|
@redcarpet ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML, extensions = {})
|
9
36
|
end
|
10
37
|
module_function :redcarpet
|
11
38
|
|
12
|
-
#
|
13
39
|
# Infer all client and strategy options from environment variables.
|
14
|
-
# The following ones are recognized:
|
15
|
-
#
|
16
|
-
# - TALKTOME_DEBUG: when set (to anything) enables the dumping of sent
|
17
|
-
# messages to the debug folder
|
18
|
-
# - TALKTOME_EMAIL_DELIVERY: "smtp", "file" or "test"
|
19
|
-
# - TALKTOME_EMAIL_DEFAULT_FROM: default from address to use for email sending
|
20
|
-
# - TALKTOME_SMTP_ADDRESS: host address for smtp sending
|
21
|
-
# - TALKTOME_SMTP_PORT: port of smtp server to use
|
22
|
-
# - TALKTOME_SMTP_DOMAIN: sending domain
|
23
|
-
# - TALKTOME_SMTP_USER: user for smtp authentication
|
24
|
-
# - TALKTOME_SMTP_PASSWORD: user for smtp authentication
|
25
|
-
#
|
26
40
|
def auto_options(folder)
|
27
41
|
options = {}
|
28
42
|
debug_folder = folder/"tmp"
|
@@ -40,10 +54,11 @@ module Talktome
|
|
40
54
|
|
41
55
|
email_config.merge!({
|
42
56
|
address: ENV['TALKTOME_SMTP_ADDRESS'],
|
43
|
-
port: ENV['TALKTOME_SMTP_PORT'],
|
57
|
+
port: ENV['TALKTOME_SMTP_PORT'].to_i,
|
44
58
|
domain: ENV['TALKTOME_SMTP_DOMAIN'],
|
45
59
|
user_name: ENV['TALKTOME_SMTP_USER'],
|
46
|
-
password: ENV['TALKTOME_SMTP_PASSWORD']
|
60
|
+
password: ENV['TALKTOME_SMTP_PASSWORD'],
|
61
|
+
enable_starttls_auto: (ENV['TALKTOME_SMTP_STARTTLS_AUTO'] != 'false')
|
47
62
|
}) if email_delivery == :smtp
|
48
63
|
|
49
64
|
email_config.merge!({
|
@@ -52,7 +67,15 @@ module Talktome
|
|
52
67
|
|
53
68
|
options[:strategies][:email] = ::Talktome::Strategy::Email.new{|email|
|
54
69
|
email.delivery_method(email_delivery, email_config)
|
55
|
-
|
70
|
+
with_env('TALKTOME_EMAIL_DEFAULT_FROM'){|default|
|
71
|
+
email.from(default)
|
72
|
+
}
|
73
|
+
with_env('TALKTOME_EMAIL_DEFAULT_TO'){|default|
|
74
|
+
email.to(default)
|
75
|
+
}
|
76
|
+
with_env('TALKTOME_EMAIL_DEFAULT_REPLYTO'){|default|
|
77
|
+
email.reply_to(default)
|
78
|
+
}
|
56
79
|
}
|
57
80
|
|
58
81
|
options
|
data/lib/talktome/app.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'finitio'
|
3
|
+
require 'rack/robustness'
|
4
|
+
module Talktome
|
5
|
+
class App < Sinatra::Application
|
6
|
+
|
7
|
+
use Rack::Robustness do |g|
|
8
|
+
g.catch_all
|
9
|
+
g.status 500
|
10
|
+
g.content_type 'text/plain'
|
11
|
+
g.body{ "An error occured." }
|
12
|
+
end
|
13
|
+
|
14
|
+
set :raise_errors, true
|
15
|
+
set :show_exceptions, false
|
16
|
+
|
17
|
+
VALIDATION_SCHEMA = ::Finitio.system(<<~FIO)
|
18
|
+
@import finitio/data
|
19
|
+
Email = String(s | s =~ /^[^@]+@[^@]+$/ )
|
20
|
+
{
|
21
|
+
reply_to :? Email
|
22
|
+
... : .Object
|
23
|
+
}
|
24
|
+
FIO
|
25
|
+
|
26
|
+
TALKTOME = Talktome::Client::Local.new(ROOT_FOLDER/'templates')
|
27
|
+
|
28
|
+
post %r{/([a-z-]+)/} do |action|
|
29
|
+
begin
|
30
|
+
TALKTOME.talktome(action, {}, info, [:email]){|email|
|
31
|
+
email.reply_to = info[:reply_to] if info.has_key?(:reply_to)
|
32
|
+
}
|
33
|
+
[ 200, { "Content-Type" => "text/plain"}, ["Ok"] ]
|
34
|
+
rescue JSON::ParserError
|
35
|
+
fail!("Invalid data")
|
36
|
+
rescue Finitio::Error => ex
|
37
|
+
fail!(ex.message)
|
38
|
+
rescue ::Talktome::InvalidEmailError => ex
|
39
|
+
fail!("Invalid email address")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def info
|
46
|
+
@info ||= VALIDATION_SCHEMA.dress(JSON.parse(request.body.read)).tap{|info|
|
47
|
+
not_a_robot!(info)
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def fail!(message)
|
52
|
+
[ 400, { "Content-Type" => "text/plain"}, [message] ]
|
53
|
+
end
|
54
|
+
|
55
|
+
def not_a_robot!(info)
|
56
|
+
# `reply_to_confirm` is a honeypot field, if it's filled it means it's a bot and an error is thrown
|
57
|
+
raise ::Talktome::InvalidEmailError if info[:reply_to_confirm] && info[:reply_to_confirm] =~ /^[^@]+@[^@]+$/
|
58
|
+
end
|
59
|
+
|
60
|
+
end # class App
|
61
|
+
end # module Talktome
|
data/lib/talktome/error.rb
CHANGED
@@ -9,10 +9,23 @@ module Talktome
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def send_message(message, user)
|
12
|
+
# Take a base email, with all info coming from the environment (if set)
|
12
13
|
mail = base_email
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
|
15
|
+
# Override environment defaults with template behavior, for flexibility
|
16
|
+
[
|
17
|
+
:to,
|
18
|
+
:reply_to,
|
19
|
+
:subject
|
20
|
+
].each do |which|
|
21
|
+
if arg = message.metadata[which.to_s]
|
22
|
+
mail.send(:"#{which}=", arg)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# If the user is actually known from source code behavior, override the
|
27
|
+
# `mail.to` to send the email to that particular person.
|
28
|
+
mail.to = user[:email] if user.has_key?(:email)
|
16
29
|
|
17
30
|
case message.extension
|
18
31
|
when 'md', 'html', 'htm'
|
@@ -37,10 +50,6 @@ module Talktome
|
|
37
50
|
|
38
51
|
private
|
39
52
|
|
40
|
-
def users(user)
|
41
|
-
user.is_a?(Array) ? user : [user]
|
42
|
-
end
|
43
|
-
|
44
53
|
def base_email
|
45
54
|
default_email = Mail.new
|
46
55
|
@defaulter.call(default_email) if @defaulter
|
data/lib/talktome/version.rb
CHANGED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Talktome
|
4
|
+
describe App do
|
5
|
+
include Rack::Test::Methods
|
6
|
+
|
7
|
+
let(:app) {
|
8
|
+
Talktome::App.new
|
9
|
+
}
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
ENV['TALKTOME_EMAIL_DEFAULT_TO'] = "to@talktome.com"
|
13
|
+
ENV['TALKTOME_EMAIL_DEFAULT_FROM'] = "from@talktome.com"
|
14
|
+
Mail::TestMailer.deliveries.clear
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'POST /contact-us/, the basic contract' do
|
18
|
+
|
19
|
+
it 'works' do
|
20
|
+
post "/contact-us/", {
|
21
|
+
reply_to: 'hello@visitor.com',
|
22
|
+
message: 'Hello from visitor'
|
23
|
+
}.to_json, { "CONTENT_TYPE" => "application/json" }
|
24
|
+
expect(last_response).to be_ok
|
25
|
+
expect(Mail::TestMailer.deliveries.length).to eql(1)
|
26
|
+
expect(Mail::TestMailer.deliveries.first.to).to eql(["to@talktome.com"])
|
27
|
+
expect(Mail::TestMailer.deliveries.first.from).to eql(["from@talktome.com"])
|
28
|
+
expect(Mail::TestMailer.deliveries.first.subject).to eql("Someone wants to reach you!")
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'detects invalid emails' do
|
32
|
+
post "/contact-us/", {
|
33
|
+
reply_to: 'helloatvisitor.com',
|
34
|
+
message: 'Hello from visitor'
|
35
|
+
}.to_json, { "CONTENT_TYPE" => "application/json" }
|
36
|
+
expect(last_response.status).to eql(400)
|
37
|
+
expect(Mail::TestMailer.deliveries.length).to eql(0)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "detects invalid bodies" do
|
41
|
+
post "/contact-us/", body: "foobar"
|
42
|
+
expect(last_response.status).to eql(400)
|
43
|
+
expect(Mail::TestMailer.deliveries.length).to eql(0)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "detects stupid bots at least" do
|
47
|
+
post "/contact-us/", {
|
48
|
+
reply_to: 'hello@visitor.com',
|
49
|
+
message: 'Hello from visitor',
|
50
|
+
reply_to_confirm: 'hello@visitor.com'
|
51
|
+
}.to_json, { "CONTENT_TYPE" => "application/json" }
|
52
|
+
expect(last_response.status).to eql(400)
|
53
|
+
expect(Mail::TestMailer.deliveries.length).to eql(0)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'POST /contact-us/, regarding the Reply-To' do
|
59
|
+
class ::Talktome::Message::Template
|
60
|
+
def raise_on_context_miss?
|
61
|
+
false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
around(:each) do |bl|
|
66
|
+
Talktome.set_env('TALKTOME_EMAIL_DEFAULT_REPLYTO', "replyto@talktome.com", &bl)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'takes the default value from environment if set' do
|
70
|
+
post "/contact-us/", {
|
71
|
+
message: 'Hello from visitor'
|
72
|
+
}.to_json, { "CONTENT_TYPE" => "application/json" }
|
73
|
+
expect(last_response).to be_ok
|
74
|
+
expect(Mail::TestMailer.deliveries.length).to eql(1)
|
75
|
+
expect(Mail::TestMailer.deliveries.first.reply_to).to eql(["replyto@talktome.com"])
|
76
|
+
end
|
77
|
+
|
78
|
+
it "lets override it by passing a replyTo field" do
|
79
|
+
post "/contact-us/", {
|
80
|
+
reply_to: 'hello@visitor.com',
|
81
|
+
message: 'Hello from visitor'
|
82
|
+
}.to_json, { "CONTENT_TYPE" => "application/json" }
|
83
|
+
expect(last_response).to be_ok
|
84
|
+
expect(Mail::TestMailer.deliveries.length).to eql(1)
|
85
|
+
expect(Mail::TestMailer.deliveries.first.reply_to).to eql(["hello@visitor.com"])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
data/spec/client/test_local.rb
CHANGED
@@ -3,16 +3,8 @@ module Talktome
|
|
3
3
|
class Client
|
4
4
|
describe Local do
|
5
5
|
|
6
|
-
let(:
|
7
|
-
|
8
|
-
}
|
9
|
-
|
10
|
-
let(:tpldata) {
|
11
|
-
{ who: "Test user" }
|
12
|
-
}
|
13
|
-
|
14
|
-
let(:folder) {
|
15
|
-
Path.dir/"../fixtures"
|
6
|
+
let(:strategy) {
|
7
|
+
Strategy::Debug.new
|
16
8
|
}
|
17
9
|
|
18
10
|
let(:client){
|
@@ -21,92 +13,53 @@ module Talktome
|
|
21
13
|
end
|
22
14
|
}
|
23
15
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
}
|
28
|
-
|
29
|
-
before(:each) {
|
30
|
-
strategy.clear!
|
31
|
-
}
|
32
|
-
|
33
|
-
context "without templates" do
|
34
|
-
let(:options) {
|
35
|
-
{}
|
36
|
-
}
|
16
|
+
let(:folder) {
|
17
|
+
Path.dir/"../fixtures"
|
18
|
+
}
|
37
19
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
expect(strategy.last.message.to_html).to eql("<h1>Hello Test user</h1>\n\n<p>Welcome to this email example!</p>\n\n<h3>Test user</h3>\n")
|
42
|
-
end
|
20
|
+
let(:user) {
|
21
|
+
{ email: "user@test.com" }
|
22
|
+
}
|
43
23
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
expect(strategy.last.message.to_html).to eql("<h1>Hello Test user</h1>\n\n<p>Welcome to this email example!</p>\n\n<h3>Test user</h3>\n")
|
48
|
-
end
|
49
|
-
end
|
24
|
+
let(:tpldata) {
|
25
|
+
{ who: "Test user" }
|
26
|
+
}
|
50
27
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
templates: Path.dir/"../fixtures/templates"
|
55
|
-
}
|
56
|
-
}
|
28
|
+
before(:each) {
|
29
|
+
strategy.clear!
|
30
|
+
}
|
57
31
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
32
|
+
context "without templates" do
|
33
|
+
let(:options) {
|
34
|
+
{}
|
35
|
+
}
|
63
36
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
}
|
69
|
-
expect(seen).not_to be_nil
|
70
|
-
end
|
37
|
+
it 'sends email when requested' do
|
38
|
+
client.talktome("welcome", user, tpldata, [:email])
|
39
|
+
expect(strategy.last.message).not_to be_nil
|
40
|
+
expect(strategy.last.message.to_html).to eql("<h1>Hello Test user</h1>\n\n<p>Welcome to this email example!</p>\n\n<h3>Test user</h3>\n")
|
71
41
|
end
|
72
42
|
end
|
73
43
|
|
74
|
-
context
|
75
|
-
before do
|
76
|
-
Mail.defaults do
|
77
|
-
delivery_method :test
|
78
|
-
end
|
79
|
-
Mail::TestMailer.deliveries = []
|
80
|
-
end
|
81
|
-
|
44
|
+
context "with templates" do
|
82
45
|
let(:options) {
|
83
|
-
{
|
84
|
-
|
85
|
-
|
86
|
-
let(:strategy) {
|
87
|
-
Strategy::Email.new({}){|m|
|
88
|
-
m.from "hello@test.com"
|
46
|
+
{
|
47
|
+
templates: Path.dir/"../fixtures/templates"
|
89
48
|
}
|
90
49
|
}
|
91
50
|
|
92
51
|
it 'sends email when requested' do
|
93
52
|
client.talktome("welcome", user, tpldata, [:email])
|
94
|
-
|
95
|
-
expect(
|
96
|
-
expect(mail.from).to eql(["hello@test.com"])
|
97
|
-
expect(mail.to).to eql(["user@test.com"])
|
53
|
+
expect(strategy.last.message).not_to be_nil
|
54
|
+
expect(strategy.last.message.to_html).to eql("<html><title>Hello Test user</title><body><h1>Hello Test user</h1>\n\n<p>Welcome to this email example!</p>\n\n<h3>Test user</h3>\n</body></html>\n")
|
98
55
|
end
|
99
56
|
|
100
|
-
it '
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
expect(
|
106
|
-
mail = Mail::TestMailer.deliveries.first
|
107
|
-
expect(mail).not_to be_nil
|
108
|
-
expect(mail.from).to eql(["hello@test.com"])
|
109
|
-
expect(mail.to).to eql(["user1@test.com", "user2@test.com"])
|
57
|
+
it 'yields the callback with the email' do
|
58
|
+
seen = nil
|
59
|
+
client.talktome("welcome", user, tpldata, [:email]){|m|
|
60
|
+
seen = m
|
61
|
+
}
|
62
|
+
expect(seen).not_to be_nil
|
110
63
|
end
|
111
64
|
end
|
112
65
|
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: talktome
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bernard Lambeau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -16,42 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '13'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '13'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '3.
|
33
|
+
version: '3.10'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '3.
|
40
|
+
version: '3.10'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rack-test
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.6.3
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.6.3
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: path
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - ">="
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
61
|
+
version: '2.0'
|
48
62
|
type: :runtime
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
68
|
+
version: '2.0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: mail
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,6 +114,54 @@ dependencies:
|
|
100
114
|
- - "~>"
|
101
115
|
- !ruby/object:Gem::Version
|
102
116
|
version: '3'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: sinatra
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '2.0'
|
124
|
+
- - "<"
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '3.0'
|
127
|
+
type: :runtime
|
128
|
+
prerelease: false
|
129
|
+
version_requirements: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '2.0'
|
134
|
+
- - "<"
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '3.0'
|
137
|
+
- !ruby/object:Gem::Dependency
|
138
|
+
name: finitio
|
139
|
+
requirement: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - "~>"
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: 0.8.0
|
144
|
+
type: :runtime
|
145
|
+
prerelease: false
|
146
|
+
version_requirements: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - "~>"
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: 0.8.0
|
151
|
+
- !ruby/object:Gem::Dependency
|
152
|
+
name: rack-robustness
|
153
|
+
requirement: !ruby/object:Gem::Requirement
|
154
|
+
requirements:
|
155
|
+
- - "~>"
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '1.1'
|
158
|
+
type: :runtime
|
159
|
+
prerelease: false
|
160
|
+
version_requirements: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - "~>"
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '1.1'
|
103
165
|
description: Talktome helps you talk to users by email, messaging, sms, etc. It abstracts
|
104
166
|
the messaging mechanisms and lets you manage message templates easily.
|
105
167
|
email: blambeau@gmail.com
|
@@ -112,6 +174,7 @@ files:
|
|
112
174
|
- README.md
|
113
175
|
- Rakefile
|
114
176
|
- lib/talktome.rb
|
177
|
+
- lib/talktome/app.rb
|
115
178
|
- lib/talktome/client.rb
|
116
179
|
- lib/talktome/client/local.rb
|
117
180
|
- lib/talktome/error.rb
|
@@ -120,6 +183,7 @@ files:
|
|
120
183
|
- lib/talktome/strategy/debug.rb
|
121
184
|
- lib/talktome/strategy/email.rb
|
122
185
|
- lib/talktome/version.rb
|
186
|
+
- spec/app/test_app.rb
|
123
187
|
- spec/client/test_local.rb
|
124
188
|
- spec/fixtures/templates/email.html
|
125
189
|
- spec/fixtures/welcome/email.md
|
@@ -150,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
214
|
- !ruby/object:Gem::Version
|
151
215
|
version: '0'
|
152
216
|
requirements: []
|
153
|
-
rubygems_version: 3.
|
217
|
+
rubygems_version: 3.0.8
|
154
218
|
signing_key:
|
155
219
|
specification_version: 4
|
156
220
|
summary: Talktome helps you talk to users by email, messaging, sms, etc.
|