Skip to content

Commit

Permalink
Add support for turning off clicks/opens independently of one another
Browse files Browse the repository at this point in the history
Add support for turning off clicks/opens independently of one another
  • Loading branch information
jmduke authored Jan 5, 2025
2 parents 75fbc04 + 6cadede commit 3ccc762
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 11 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,17 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v2
- uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- run: docker-compose pull
- run: docker compose pull
env:
POSTAL_IMAGE: ghcr.io/buttondown/postal:ci-${{ github.sha }}
- run: docker-compose run postal sh -c 'bundle exec rspec'
- run: docker compose run postal sh -c 'bundle exec rspec'
env:
POSTAL_IMAGE: ghcr.io/buttondown/postal:ci-${{ github.sha }}

Expand Down
8 changes: 4 additions & 4 deletions config/examples/test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This is an example Postal configuration file for use in
# This is an example Postal configuration file for use in
# test environments. For a production example, see
# the https://github.com/postalserver/install repository.

Expand All @@ -7,14 +7,14 @@ version: 2
main_db:
host: 127.0.0.1
username: root
password:
password:
database: postal-test

message_db:
host: 127.0.0.1
username: root
password:
prefix: postal-test
password:
prefix: postal

logging:
enabled: false
Expand Down
13 changes: 10 additions & 3 deletions lib/postal/message_db/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def html_body
end

#
# Return the HTML body with any tracking links
# Return the HTML body with the tracking image removed.
#
def html_body_without_tracking_image
html_body.gsub(/<p class=['"]ampimg['"].*?<\/p>/, "")
Expand Down Expand Up @@ -573,8 +573,15 @@ def parsed?
# Should this message be parsed?
#
def should_parse?
# Header values are always arrays, so we check for `['skip']` instead of `'skip'`
parsed? == false && headers["x-amp"] != ["skip"]
parsed? == false
end

def track_clicks?
headers["x-track-clicks"] != ["no"]
end

def track_loads?
headers["x-track-opens"] != ["no"]
end

private
Expand Down
4 changes: 2 additions & 2 deletions lib/postal/message_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ def parse_parts(parts)
end

def parse(part, type = nil)
if @domain.track_clicks?
if @domain.track_clicks? && @message.track_clicks?
part = insert_links(part, type)
end

if @domain.track_loads? && type == :html
if @domain.track_loads? && @message.track_loads? && type == :html
part = insert_tracking_image(part)
end

Expand Down
9 changes: 9 additions & 0 deletions spec/helpers/general_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,13 @@ def create_plain_text_message(server, text, to = "test@example.com", override_at
server.message_db.message(result[:id])
end

def create_html_message(server, html, to = "test@example.com", override_attributes = {})
domain = create(:domain, owner: server)
attributes = { from: "test@#{domain.name}", subject: "Test HTML Message" }.merge(override_attributes)
attributes[:to] = to
attributes[:html_body] = html
message = OutgoingMessagePrototype.new(server, "127.0.0.1", "testsuite", attributes)
result = message.create_message(to)
server.message_db.message(result[:id])
end
end
27 changes: 27 additions & 0 deletions spec/lib/postal/message_parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,31 @@
expect(parser.new_body).to match(/^Hello world! https:\/\/click\.#{message.domain.name}/)
expect(parser.tracked_links).to eq 1
end

it "should not replace links in messages if the header is set to no" do
message = create_plain_text_message(server, "Hello world! http://github.com/atech/postal", "test@example.com", { custom_headers: { "x-track-clicks" => "no" } })
create(:track_domain, server: server, domain: message.domain)
parser = Postal::MessageParser.new(message)
expect(parser.actioned?).to be false
expect(parser.new_body).to include("Hello world! http://github.com/atech/postal")
expect(parser.tracked_links).to eq 0
end

it "should insert tracking pixels in messages" do
message = create_html_message(server, "<p>Hello world! <a href='http://github.com/atech/postal'>Github</a></p>", "test@example.com")
create(:track_domain, server: server, domain: message.domain)
parser = Postal::MessageParser.new(message)
expect(parser.actioned?).to be true
expect(parser.new_body).to match(/<p class='ampimg' style='display:none;visibility:none;margin:0;padding:0;line-height:0;'><img src='https:\/\/click\.#{message.domain.name}/)
expect(parser.tracked_images).to eq 1
end

it "should not insert tracking pixels in messages if the header is set to no" do
message = create_html_message(server, "<p>Hello world! <a href='http://github.com/atech/postal'>Github</a></p>", "test@example.com", { custom_headers: { "x-track-opens" => "no" } })
create(:track_domain, server: server, domain: message.domain)
parser = Postal::MessageParser.new(message)
expect(parser.actioned?).to be true
expect(parser.new_body).to_not include("<p class='ampimg' style='display:none;visibility:none;margin:0;padding:0;line-height:0;'><img src='https:\/\/click\.#{message.domain.name}")
expect(parser.tracked_images).to eq 0
end
end

0 comments on commit 3ccc762

Please sign in to comment.