mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-09-11 15:14:31 +08:00
fix(read-receipts): Remove tracking pixels when composing drafts
This commit is contained in:
parent
7907b8fdd1
commit
05be74ec04
7 changed files with 236 additions and 163 deletions
|
@ -2445,7 +2445,6 @@
|
|||
9847458: internal_packages/message-list/lib/plugins/autolinker-extension.js
|
||||
9849560: internal_packages/message-list/node_modules/autolinker/package.json
|
||||
9852413: internal_packages/message-list/node_modules/autolinker/dist/Autolinker.js
|
||||
9972803: internal_packages/message-list/lib/plugins/tracking-pixels-extension.js
|
||||
3810966: static/variables/ui-variables.less
|
||||
9977447: internal_packages/message-view-on-github/lib/main.js
|
||||
9983560: internal_packages/message-view-on-github/lib/view-on-github-button.js
|
||||
|
|
|
@ -8,8 +8,6 @@ MessageListHiddenMessagesToggle = require './message-list-hidden-messages-toggle
|
|||
SidebarPluginContainer = require "./sidebar-plugin-container"
|
||||
SidebarParticipantPicker = require './sidebar-participant-picker'
|
||||
|
||||
TrackingPixelsExtension = require './plugins/tracking-pixels-extension'
|
||||
|
||||
module.exports =
|
||||
activate: ->
|
||||
# Register Message List Actions we provide globally
|
||||
|
@ -25,10 +23,7 @@ module.exports =
|
|||
ComponentRegistry.register MessageListHiddenMessagesToggle,
|
||||
role: 'MessageListHeaders'
|
||||
|
||||
ExtensionRegistry.MessageView.register TrackingPixelsExtension
|
||||
|
||||
deactivate: ->
|
||||
ComponentRegistry.unregister MessageList
|
||||
ComponentRegistry.unregister SidebarPluginContainer
|
||||
ComponentRegistry.unregister SidebarParticipantPicker
|
||||
ExtensionRegistry.MessageView.unregister TrackingPixelsExtension
|
||||
|
|
|
@ -1,126 +0,0 @@
|
|||
{MessageViewExtension, RegExpUtils} = require 'nylas-exports'
|
||||
|
||||
TrackingBlacklist = [{
|
||||
name: 'Sidekick',
|
||||
pattern: 't.signaux',
|
||||
homepage: 'http://getsidekick.com'
|
||||
}, {
|
||||
name: 'Sidekick',
|
||||
pattern: 't.senal',
|
||||
homepage: 'http://getsidekick.com'
|
||||
}, {
|
||||
name: 'Sidekick',
|
||||
pattern: 't.sidekickopen',
|
||||
homepage: 'http://getsidekick.com'
|
||||
}, {
|
||||
name: 'Sidekick',
|
||||
pattern: 't.sigopn',
|
||||
homepage: 'http://getsidekick.com'
|
||||
}, {
|
||||
name: 'Banana Tag',
|
||||
pattern: 'bl-1.com',
|
||||
homepage: 'http://bananatag.com'
|
||||
}, {
|
||||
name: 'Boomerang',
|
||||
pattern: 'mailstat.us/tr',
|
||||
homepage: 'http://boomeranggmail.com'
|
||||
}, {
|
||||
name: 'Cirrus Inisght',
|
||||
pattern: 'tracking.cirrusinsight.com',
|
||||
homepage: 'http://cirrusinsight.com'
|
||||
}, {
|
||||
name: 'Yesware',
|
||||
pattern: 'app.yesware.com',
|
||||
homepage: 'http://yesware.com'
|
||||
}, {
|
||||
name: 'Yesware',
|
||||
pattern: 't.yesware.com',
|
||||
homepage: 'http://yesware.com'
|
||||
}, {
|
||||
name: 'Streak',
|
||||
pattern: 'mailfoogae.appspot.com',
|
||||
homepage: 'http://streak.com'
|
||||
}, {
|
||||
name: 'LaunchBit',
|
||||
pattern: 'launchbit.com/taz-pixel',
|
||||
homepage: 'http://launchbit.com'
|
||||
}, {
|
||||
name: 'MailChimp',
|
||||
pattern: 'list-manage.com/track',
|
||||
homepage: 'http://mailchimp.com'
|
||||
}, {
|
||||
name: 'Postmark',
|
||||
pattern: 'cmail1.com/t',
|
||||
homepage: 'http://postmarkapp.com'
|
||||
}, {
|
||||
name: 'iContact',
|
||||
pattern: 'click.icptrack.com/icp/',
|
||||
homepage: 'http://icontact.com'
|
||||
}, {
|
||||
name: 'Infusionsoft',
|
||||
pattern: 'infusionsoft.com/app/emailOpened',
|
||||
homepage: 'http://infusionsoft.com'
|
||||
}, {
|
||||
name: 'Intercom',
|
||||
pattern: 'via.intercom.io/o',
|
||||
homepage: 'http://intercom.io'
|
||||
}, {
|
||||
name: 'Mandrill',
|
||||
pattern: 'mandrillapp.com/track',
|
||||
homepage: 'http://mandrillapp.com'
|
||||
}, {
|
||||
name: 'Hubspot',
|
||||
pattern: 't.hsms06.com',
|
||||
homepage: 'http://hubspot.com'
|
||||
}, {
|
||||
name: 'RelateIQ',
|
||||
pattern: 'app.relateiq.com/t.png',
|
||||
homepage: 'http://relateiq.com'
|
||||
}, {
|
||||
name: 'RJ Metrics',
|
||||
pattern: 'go.rjmetrics.com',
|
||||
homepage: 'http://rjmetrics.com'
|
||||
}, {
|
||||
name: 'Mixpanel',
|
||||
pattern: 'api.mixpanel.com/track',
|
||||
homepage: 'http://mixpanel.com'
|
||||
}, {
|
||||
name: 'Front App',
|
||||
pattern: 'web.frontapp.com/api',
|
||||
homepage: 'http://frontapp.com'
|
||||
}, {
|
||||
name: 'Mailtrack.io',
|
||||
pattern: 'mailtrack.io/trace',
|
||||
homepage: 'http://mailtrack.io'
|
||||
}, {
|
||||
name: 'Salesloft',
|
||||
pattern: 'sdr.salesloft.com/email_trackers',
|
||||
homepage: 'http://salesloft.com'
|
||||
}, {
|
||||
name: 'Nylas',
|
||||
pattern: 'nylas.com/open',
|
||||
homepage: 'http://nylas.com/N1'
|
||||
}]
|
||||
|
||||
class TrackingPixelsExtension extends MessageViewExtension
|
||||
|
||||
@formatMessageBody: ({message}) ->
|
||||
return unless message.isFromMe()
|
||||
|
||||
regex = RegExpUtils.imageTagRegex()
|
||||
body = message.body
|
||||
spliceRegions = []
|
||||
|
||||
# Identify img tags that should be cut out
|
||||
while (result = regex.exec(body)) isnt null
|
||||
for item in TrackingBlacklist
|
||||
if result[1].indexOf(item.pattern) > 0
|
||||
spliceRegions.push(start: result.index, end: result.index + result[0].length)
|
||||
continue
|
||||
|
||||
# Remove them all, from the end of the string to the start
|
||||
spliceRegions.reverse().forEach ({start, end}) ->
|
||||
body = body.substr(0, start) + body.substr(end)
|
||||
message.body = body
|
||||
|
||||
module.exports = TrackingPixelsExtension
|
|
@ -1,31 +0,0 @@
|
|||
TrackingPixelsExtension = require '../lib/plugins/tracking-pixels-extension'
|
||||
{Message} = require 'nylas-exports'
|
||||
|
||||
testBody = """
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><p>Hey Ben,</p><p>
|
||||
I've noticed that we don't yet have an SLA in place with Nylas. Are you the right
|
||||
person to be speaking with to make sure everything is set up on that end? If not,
|
||||
could you please put me in touch with them, so that we can get you guys set up
|
||||
correctly as soon as possible?</p><p>Thanks!</p><p>Gleb Polyakov</p><p>Head of
|
||||
Business Development and Growth</p><img src="https://sdr.salesloft.com/email_trackers/8c8bea88-af43-4f66-bf78-a97ad73d7aec/open.gif" alt="" width="1" height="1">After Pixel
|
||||
"""
|
||||
testBodyProcessed = """
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><p>Hey Ben,</p><p>
|
||||
I've noticed that we don't yet have an SLA in place with Nylas. Are you the right
|
||||
person to be speaking with to make sure everything is set up on that end? If not,
|
||||
could you please put me in touch with them, so that we can get you guys set up
|
||||
correctly as soon as possible?</p><p>Thanks!</p><p>Gleb Polyakov</p><p>Head of
|
||||
Business Development and Growth</p>After Pixel
|
||||
"""
|
||||
|
||||
describe "TrackingPixelsExtension", ->
|
||||
it "should splice tracking pixels and only run on messages by the current user", ->
|
||||
message = new Message(body: testBody)
|
||||
spyOn(message, 'isFromMe').andCallFake -> false
|
||||
TrackingPixelsExtension.formatMessageBody({message})
|
||||
expect(message.body).toEqual(testBody)
|
||||
|
||||
message = new Message(body: testBody)
|
||||
spyOn(message, 'isFromMe').andCallFake -> true
|
||||
TrackingPixelsExtension.formatMessageBody({message})
|
||||
expect(message.body).toEqual(testBodyProcessed)
|
158
internal_packages/remove-tracking-pixels/lib/main.es6
Normal file
158
internal_packages/remove-tracking-pixels/lib/main.es6
Normal file
|
@ -0,0 +1,158 @@
|
|||
/* eslint no-cond-assign: 0 */
|
||||
|
||||
import {
|
||||
ExtensionRegistry,
|
||||
MessageViewExtension,
|
||||
ComposerExtension,
|
||||
RegExpUtils,
|
||||
} from 'nylas-exports';
|
||||
|
||||
const TrackingBlacklist = [{
|
||||
name: 'Sidekick',
|
||||
pattern: 't.signaux',
|
||||
homepage: 'http://getsidekick.com',
|
||||
}, {
|
||||
name: 'Sidekick',
|
||||
pattern: 't.senal',
|
||||
homepage: 'http://getsidekick.com',
|
||||
}, {
|
||||
name: 'Sidekick',
|
||||
pattern: 't.sidekickopen',
|
||||
homepage: 'http://getsidekick.com',
|
||||
}, {
|
||||
name: 'Sidekick',
|
||||
pattern: 't.sigopn',
|
||||
homepage: 'http://getsidekick.com',
|
||||
}, {
|
||||
name: 'Banana Tag',
|
||||
pattern: 'bl-1.com',
|
||||
homepage: 'http://bananatag.com',
|
||||
}, {
|
||||
name: 'Boomerang',
|
||||
pattern: 'mailstat.us/tr',
|
||||
homepage: 'http://boomeranggmail.com',
|
||||
}, {
|
||||
name: 'Cirrus Inisght',
|
||||
pattern: 'tracking.cirrusinsight.com',
|
||||
homepage: 'http://cirrusinsight.com',
|
||||
}, {
|
||||
name: 'Yesware',
|
||||
pattern: 'app.yesware.com',
|
||||
homepage: 'http://yesware.com',
|
||||
}, {
|
||||
name: 'Yesware',
|
||||
pattern: 't.yesware.com',
|
||||
homepage: 'http://yesware.com',
|
||||
}, {
|
||||
name: 'Streak',
|
||||
pattern: 'mailfoogae.appspot.com',
|
||||
homepage: 'http://streak.com',
|
||||
}, {
|
||||
name: 'LaunchBit',
|
||||
pattern: 'launchbit.com/taz-pixel',
|
||||
homepage: 'http://launchbit.com',
|
||||
}, {
|
||||
name: 'MailChimp',
|
||||
pattern: 'list-manage.com/track',
|
||||
homepage: 'http://mailchimp.com',
|
||||
}, {
|
||||
name: 'Postmark',
|
||||
pattern: 'cmail1.com/t',
|
||||
homepage: 'http://postmarkapp.com',
|
||||
}, {
|
||||
name: 'iContact',
|
||||
pattern: 'click.icptrack.com/icp/',
|
||||
homepage: 'http://icontact.com',
|
||||
}, {
|
||||
name: 'Infusionsoft',
|
||||
pattern: 'infusionsoft.com/app/emailOpened',
|
||||
homepage: 'http://infusionsoft.com',
|
||||
}, {
|
||||
name: 'Intercom',
|
||||
pattern: 'via.intercom.io/o',
|
||||
homepage: 'http://intercom.io',
|
||||
}, {
|
||||
name: 'Mandrill',
|
||||
pattern: 'mandrillapp.com/track',
|
||||
homepage: 'http://mandrillapp.com',
|
||||
}, {
|
||||
name: 'Hubspot',
|
||||
pattern: 't.hsms06.com',
|
||||
homepage: 'http://hubspot.com',
|
||||
}, {
|
||||
name: 'RelateIQ',
|
||||
pattern: 'app.relateiq.com/t.png',
|
||||
homepage: 'http://relateiq.com',
|
||||
}, {
|
||||
name: 'RJ Metrics',
|
||||
pattern: 'go.rjmetrics.com',
|
||||
homepage: 'http://rjmetrics.com',
|
||||
}, {
|
||||
name: 'Mixpanel',
|
||||
pattern: 'api.mixpanel.com/track',
|
||||
homepage: 'http://mixpanel.com',
|
||||
}, {
|
||||
name: 'Front App',
|
||||
pattern: 'web.frontapp.com/api',
|
||||
homepage: 'http://frontapp.com',
|
||||
}, {
|
||||
name: 'Mailtrack.io',
|
||||
pattern: 'mailtrack.io/trace',
|
||||
homepage: 'http://mailtrack.io',
|
||||
}, {
|
||||
name: 'Salesloft',
|
||||
pattern: 'sdr.salesloft.com/email_trackers',
|
||||
homepage: 'http://salesloft.com',
|
||||
}, {
|
||||
name: 'Nylas',
|
||||
pattern: 'nylas.com/open',
|
||||
homepage: 'http://nylas.com/N1',
|
||||
}]
|
||||
|
||||
export function removeTrackingImagesFromBody(body) {
|
||||
const spliceRegions = [];
|
||||
const regex = RegExpUtils.imageTagRegex();
|
||||
|
||||
// Identify img tags that should be cut
|
||||
let result = null;
|
||||
while ((result = regex.exec(body)) !== null) {
|
||||
for (const item of TrackingBlacklist) {
|
||||
if (result[1].indexOf(item.pattern) > 0) {
|
||||
spliceRegions.push({start: result.index, end: result.index + result[0].length})
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Remove them all, from the end of the string to the start
|
||||
let updated = body;
|
||||
spliceRegions.reverse().forEach(({start, end}) => {
|
||||
updated = updated.substr(0, start) + updated.substr(end);
|
||||
});
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
class TrackingPixelsMessageExtension extends MessageViewExtension {
|
||||
formatMessageBody({message}) {
|
||||
if (message.isFromMe()) {
|
||||
message.body = removeTrackingImagesFromBody(message.body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TrackingPixelsComposerExtension extends ComposerExtension {
|
||||
static prepareNewDraft = ({draft}) => {
|
||||
draft.body = removeTrackingImagesFromBody(draft.body);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function activate() {
|
||||
ExtensionRegistry.MessageView.register(TrackingPixelsMessageExtension);
|
||||
ExtensionRegistry.Composer.register(TrackingPixelsComposerExtension);
|
||||
}
|
||||
|
||||
export function deactivate() {
|
||||
ExtensionRegistry.MessageView.unregister(TrackingPixelsMessageExtension);
|
||||
ExtensionRegistry.Composer.unregister(TrackingPixelsComposerExtension);
|
||||
}
|
9
internal_packages/remove-tracking-pixels/package.json
Normal file
9
internal_packages/remove-tracking-pixels/package.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "remove-tracking-pixels",
|
||||
"version": "0.1.0",
|
||||
"main": "./lib/main",
|
||||
"license": "GPL-3.0",
|
||||
"engines": {
|
||||
"nylas": ">=0.3.0 <0.5.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/* eslint no-irregular-whitespace: 0 */
|
||||
import {removeTrackingImagesFromBody} from '../lib/main';
|
||||
|
||||
const testBody = `
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><p>Hey Ben,</p><p>
|
||||
I've noticed that we don't yet have an SLA in place with Nylas. Are you the right
|
||||
person to be speaking with to make sure everything is set up on that end? If not,
|
||||
could you please put me in touch with them, so that we can get you guys set up
|
||||
correctly as soon as possible?</p><p>Thanks!</p><p>Gleb Polyakov</p><p>Head of
|
||||
Business Development and Growth</p><img src="https://sdr.salesloft.com/email_trackers/8c8bea88-af43-4f66-bf78-a97ad73d7aec/open.gif" alt="" width="1" height="1">After Pixel
|
||||
|
||||
<br><br><signature>Sent from <a href="https://nylas.com/n1?ref=n1">Nylas N1</a>, the extensible, open source mail client.<br/></signature><div class="gmail_quote">
|
||||
On Apr 28 2016, at 2:14 pm, Ben Gotow (Careless) <careless@foundry376.com> wrote:
|
||||
<br>
|
||||
<blockquote class="gmail_quote"
|
||||
style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
|
||||
<body>nother mailA<br /><br />Sent from <a href="https://link.nylas.com/link/b5djvgcuhj6i3x8nm53d0vnjm/local-a84ad76e-006b/0?redirect=https%3A%2F%2Fnylas.com%2Fn1%3Fref%3Dn1">Nylas N1</a>, the extensible, open source mail client.<br /><img width="0" height="0" style="border:0; width:0; height:0;" src="https://link.nylas.com/open/b5djvgcuhj6i3x8nm53d0vnjm/local-a84ad76e-006b" /><div>
|
||||
On Apr 28 2016, at 1:46 pm, Ben Gotow (Careless) <careless@foundry376.com> wrote:
|
||||
<br />
|
||||
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
|
||||
Hi Ben this is just a test.<br /><br />Sent from <a href="https://link.nylas.com/link/b5djvgcuhj6i3x8nm53d0vnjm/local-aa39d95b-b883/0?redirect=https%3A%2F%2Fnylas.com%2Fn1%3Fref%3Dn1">Nylas N1</a>, the extensible, open source mail client.<br /><img width="0" height="0" style="border:0; width:0; height:0;" src="https://link.nylas.com/open/b5djvgcuhj6i3x8nm53d0vnjm/local-aa39d95b-b883" /><div>
|
||||
On Apr 26 2016, at 6:03 pm, Ben Gotow <bengotow@gmail.com> wrote:
|
||||
<br />
|
||||
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
|
||||
<p>To test this, send https://www.google.com/search?q=test@example.com to yourself from a client that allows plaintext or html editing.</p>
|
||||
<p><br />Ben Gotow<br />-----------------------------------<br /><a href="http://www.foundry376.com/">http://www.foundry376.com/</a><br />bengotow@gmail.com<br />540-250-2334</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
</blockquote>
|
||||
</div></body>
|
||||
</blockquote>
|
||||
</div>
|
||||
`
|
||||
const testBodyProcessed = `
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><p>Hey Ben,</p><p>
|
||||
I've noticed that we don't yet have an SLA in place with Nylas. Are you the right
|
||||
person to be speaking with to make sure everything is set up on that end? If not,
|
||||
could you please put me in touch with them, so that we can get you guys set up
|
||||
correctly as soon as possible?</p><p>Thanks!</p><p>Gleb Polyakov</p><p>Head of
|
||||
Business Development and Growth</p>After Pixel
|
||||
|
||||
<br><br><signature>Sent from <a href="https://nylas.com/n1?ref=n1">Nylas N1</a>, the extensible, open source mail client.<br/></signature><div class="gmail_quote">
|
||||
On Apr 28 2016, at 2:14 pm, Ben Gotow (Careless) <careless@foundry376.com> wrote:
|
||||
<br>
|
||||
<blockquote class="gmail_quote"
|
||||
style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
|
||||
<body>nother mailA<br /><br />Sent from <a href="https://link.nylas.com/link/b5djvgcuhj6i3x8nm53d0vnjm/local-a84ad76e-006b/0?redirect=https%3A%2F%2Fnylas.com%2Fn1%3Fref%3Dn1">Nylas N1</a>, the extensible, open source mail client.<br /><div>
|
||||
On Apr 28 2016, at 1:46 pm, Ben Gotow (Careless) <careless@foundry376.com> wrote:
|
||||
<br />
|
||||
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
|
||||
Hi Ben this is just a test.<br /><br />Sent from <a href="https://link.nylas.com/link/b5djvgcuhj6i3x8nm53d0vnjm/local-aa39d95b-b883/0?redirect=https%3A%2F%2Fnylas.com%2Fn1%3Fref%3Dn1">Nylas N1</a>, the extensible, open source mail client.<br /><div>
|
||||
On Apr 26 2016, at 6:03 pm, Ben Gotow <bengotow@gmail.com> wrote:
|
||||
<br />
|
||||
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
|
||||
<p>To test this, send https://www.google.com/search?q=test@example.com to yourself from a client that allows plaintext or html editing.</p>
|
||||
<p><br />Ben Gotow<br />-----------------------------------<br /><a href="http://www.foundry376.com/">http://www.foundry376.com/</a><br />bengotow@gmail.com<br />540-250-2334</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
</blockquote>
|
||||
</div></body>
|
||||
</blockquote>
|
||||
</div>
|
||||
`
|
||||
|
||||
describe("TrackingPixelsExtension", () => {
|
||||
it("should splice tracking pixels", () => {
|
||||
expect(removeTrackingImagesFromBody(testBody)).toEqual(testBodyProcessed);
|
||||
});
|
||||
});
|
Loading…
Add table
Reference in a new issue