Jump to content

[Bug] Unsubscribe links are all broken


Recommended Posts

Clicking on an unsubscribe link redirects the user to the homepage and does not unsubscribe.

This took me FOREVER to figure out, especially because the client who reported it was using SendGrid, which of course rewrites all the links. Until I got access to that and managed to see what was happening...

There is a conflict when IPS email tracking is enabled. Consider this unsubscribe link that is included in a bulk mail:

https://site.com/index.php?app=core&module=system&controller=redirect&url=https://site.com/unsubscribe/?email=esther@headstandconsulting.com%26key=1cd2e20f285199a4351e4037aa7c19b1&key=e6509624eb4aeb5a4a3e8c7e19497d69628204292b4a26d21ac49db305915cc3&email=1&type=bulk_mail&utm_source=connect&utm_medium=email&utm_campaign=website

Note that there are 2 query parameters for both "email" and "key".

\IPS\Email::_parseElementForClickTracking

$url = \IPS\Http\Url::internal( "app=core&module=system&controller=redirect", 'front' )->setQueryString( array(
				'url'		=> (string) $element->getAttribute('href'),
				'resource'	=> ( \IPS\Request::i()->resource ) ? 1 : NULL,
				'key'		=> hash_hmac( "sha256", (string) $element->getAttribute('href'), \IPS\Settings::i()->site_secret_key . 'r' ),
				'email'		=> 1,
				'type'		=> $templateKey
			) );

Adding the HTML click tracking sets the "email" query parameter to 1 and the "key" to a hash related to the link. These parameters are added to the unsubscribe link after  the unsubscribe link is built. The unsubscribe link itself contains an "email" query parameter (which is set to the recipient's email), as well as a "key" query parameter (which is a hash of the user's email and pass_hash). 

I would suggest that the click tracking piece be reviewed to avoid the duplicate parameters.

I imagine that this may be the root cause of other unsubscribe issues that have been reported in this forum.

Thanks.

 

Link to comment
Share on other sites

20 hours ago, HeadStand said:

Clicking on an unsubscribe link redirects the user to the homepage and does not unsubscribe.

This took me FOREVER to figure out, especially because the client who reported it was using SendGrid, which of course rewrites all the links. Until I got access to that and managed to see what was happening...

There is a conflict when IPS email tracking is enabled. Consider this unsubscribe link that is included in a bulk mail:

https://site.com/index.php?app=core&module=system&controller=redirect&url=https://site.com/unsubscribe/?email=esther@headstandconsulting.com%26key=1cd2e20f285199a4351e4037aa7c19b1&key=e6509624eb4aeb5a4a3e8c7e19497d69628204292b4a26d21ac49db305915cc3&email=1&type=bulk_mail&utm_source=connect&utm_medium=email&utm_campaign=website

Note that there are 2 query parameters for both "email" and "key".

\IPS\Email::_parseElementForClickTracking

$url = \IPS\Http\Url::internal( "app=core&module=system&controller=redirect", 'front' )->setQueryString( array(
				'url'		=> (string) $element->getAttribute('href'),
				'resource'	=> ( \IPS\Request::i()->resource ) ? 1 : NULL,
				'key'		=> hash_hmac( "sha256", (string) $element->getAttribute('href'), \IPS\Settings::i()->site_secret_key . 'r' ),
				'email'		=> 1,
				'type'		=> $templateKey
			) );

Adding the HTML click tracking sets the "email" query parameter to 1 and the "key" to a hash related to the link. These parameters are added to the unsubscribe link after  the unsubscribe link is built. The unsubscribe link itself contains an "email" query parameter (which is set to the recipient's email), as well as a "key" query parameter (which is a hash of the user's email and pass_hash). 

I would suggest that the click tracking piece be reviewed to avoid the duplicate parameters.

I imagine that this may be the root cause of other unsubscribe issues that have been reported in this forum.

Thanks.

 

I can't reproduce this.

The tracking URL results in a link which contains the encoded URL with the email and key parameter , so the email and key parameters which are added by the tracking code don't conflict with the one in the url parameter.

CleanShot 2022-01-14 at 14.45.17@2x.png

 

And I can also confirm that the unsubscribe link in the bulk email with enabled email tracking works correct and that I was redirected to the proper target once my clicks as logged.

Have you tried to debug the target URL inside the redirect controller? 

Link to comment
Share on other sites

3 hours ago, Daniel F said:

Have you tried to debug the target URL inside the redirect controller? 

Yes, I can see where I'm directed to when I click the unsubscribe link.

Perhaps it's a conflict with Sendgrid itself? The way that Sendgrid rewrites the URLs? I would bet that sendgrid just decodes the URL in full.....

Link to comment
Share on other sites

31 minutes ago, HeadStand said:

Yes, I can see where I'm directed to when I click the unsubscribe link.

Perhaps it's a conflict with Sendgrid itself? The way that Sendgrid rewrites the URLs? I would bet that sendgrid just decodes the URL in full.....

SendGrid's URL decryption has caused some issues in the past so I would not be surprised. Of course, can confirm this by doing some tests with another SMTP provider.

Link to comment
Share on other sites

52 minutes ago, Jim M said:

SendGrid's URL decryption has caused some issues in the past so I would not be surprised. Of course, can confirm this by doing some tests with another SMTP provider.

Sendgrid is not the only platform that rewrites URLs. Most of these platforms do. I realize that IPS doesn't support other email services out of the box, but there are plenty of services that will rewrite the URLs even if you send the email through their SMTP.

Link to comment
Share on other sites

  • 2 months later...

Reviving this thread because I figured out the actual problem and it's a fun one. I can't even figure out how to work around it. 😞 

Unsubscribe works just fine for any outgoing email provider that doesn't use a bulk feature. For example, SMTP and PHP basically just send out each email one at a time. However, providers like SendGrid use an API call that allows you to send the content and replacement variables.

This causes a problem here:

<a href="http://localhost/toke/index.php?app=core&amp;module=system&amp;controller=redirect&amp;url=http://localhost/toke/index.php?/unsubscribe/%26email=*|member_email|*%26key=*|unsubscribe_key|*&amp;key=bd193a982da6f0499469b704762626d6720084d9d052e03039eb9ff7424db222&amp;email=1&amp;type=bulk_mail" style="color: #4a8aca; text-decoration: none; display: inline-block">Unsubscribe here</a>.

The URL that is used for tracking includes parameter values of *|member_email|* and *|unsubscribe_key|*. Now... while these values do get properly replaced when the email goes out, the issue is with the key parameter that is passed to the redirect controller.

The key is generated by a hash of the URL... which has *|member_email|* and *|unsubscribe_key|* instead of the actual email and unsubscribe key. So when the end user clicks the unsubscribe link, the URL no longer matches the hash.

The only solution I can think of is to replace the entire tracked link with a replacement variable. So something like

<a href="*|unsubscribe_url|*" style="color: #4a8aca; text-decoration: none; display: inline-block">Unsubscribe here</a>.

I don't think this is fixable by plugin, which is going to drive me bananas.

Link to comment
Share on other sites

1 hour ago, HeadStand said:

Reviving this thread because I figured out the actual problem and it's a fun one. I can't even figure out how to work around it. 😞 

Unsubscribe works just fine for any outgoing email provider that doesn't use a bulk feature. For example, SMTP and PHP basically just send out each email one at a time. However, providers like SendGrid use an API call that allows you to send the content and replacement variables.

This causes a problem here:

<a href="http://localhost/toke/index.php?app=core&amp;module=system&amp;controller=redirect&amp;url=http://localhost/toke/index.php?/unsubscribe/%26email=*|member_email|*%26key=*|unsubscribe_key|*&amp;key=bd193a982da6f0499469b704762626d6720084d9d052e03039eb9ff7424db222&amp;email=1&amp;type=bulk_mail" style="color: #4a8aca; text-decoration: none; display: inline-block">Unsubscribe here</a>.

The URL that is used for tracking includes parameter values of *|member_email|* and *|unsubscribe_key|*. Now... while these values do get properly replaced when the email goes out, the issue is with the key parameter that is passed to the redirect controller.

The key is generated by a hash of the URL... which has *|member_email|* and *|unsubscribe_key|* instead of the actual email and unsubscribe key. So when the end user clicks the unsubscribe link, the URL no longer matches the hash.

The only solution I can think of is to replace the entire tracked link with a replacement variable. So something like

<a href="*|unsubscribe_url|*" style="color: #4a8aca; text-decoration: none; display: inline-block">Unsubscribe here</a>.

I don't think this is fixable by plugin, which is going to drive me bananas.

I did fix it by plugin, but yuck.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...