URL links in email - resolve correct url? - email

Before i start thinking about this programatically, does anyone know if it is possible to actually extract the correct url from an email link that is basically a tracking module?
Our work email system auto blocks tracking based urls from email, so i am thinking of writing something to extract the correct url so people can copy and paste the tracking link into a program and it will provide the correct url.
Is this even possible with the way that email tracking works?
Here is an example of a url in an email that i recently received:
http://t.dripemail2.com/c/eyJhY2NvdW50X2lkIjoiNTE0MTQ4NSIsImRlbGl2ZXJ5X2lkIjoiOTI0NzI2MTU0IiwidXJsIjoiaHR0cHM6Ly93d3cuYXhzaWVkLmNvbS9nY3NlLWNvbXB1dGVyLXNjaWVuY2Uvb2NyLW5lYS1ndWlkZS8_X19zPXphb2txcDVpaWN4NGkxZndtYmNnIn0
Our system blocks these. It eventually resolves to:
https://www.axsied.com/gcse-computer-science/ocr-nea-guide/?__s=zaokqp5iicx4i1fwmbcg
(got our network admin to check it for me)
I want a system that gets the right url from the ugly mess that is blocked so we can actually view links from emails.
Thanks in advance for any help.

The data in tracking URLs are typically a unique ID pointing to some entry in a database, or are encrypted with a private key, so there's no way to obtain any meaningful information from them. (see answers to this related question: Generate unique link for each website visitor)
More naive approaches will simply encode the data, in which case you may be able to extract useful information from them. Funnily enough, your example URL is a base 64 encoded JSON object containing the link itself:
{
"account_id": "5141485",
"delivery_id": "924726154",
"url": "https://www.axsied.com/gcse-computer-science/ocr-nea-guide/?__s=zaokqp5iicx4i1fwmbcg"
}
In this case you could actually resolve the URL on your own, but this type of approach is uncommon for that very reason.

Related

Custom tags in Jira email handler

Is there a way to make a Jire email handler ignore the From field in an email and go for a custom tag instead? I know I could work with the API instead but that's in the pipe. this is a temporary solution that will be used until a more robust system is built.
To clarify what we have today:
Email is sent to inbox, (hr#company.com)
Jira picks is up and creates an issue.
Jira looks at the From field and creates a uses if none exist.
What we're trying to achieve:
Form is filled out, and an area is chosen (hr, facilities etc.).
Form is posted to an API that creates an email (basically a no-reply adress over SMTP) and sends it to the appropriate inbox (for example hr#company.com).
Email lands in the inbox and Jira looks in it and creates an issue in project or label 'HR'.
Jira now looks in the email and finds custom tags named [user] and [user-email] (or something) and creates a user from the tag.
Example email
From: no-reply#company.com
To: hr#company.com
Subject: Some problem
Body: Explanation of problem
Have a good day!
/Mike
[user:"Michael Smith"]
[userEmail:"michael.smith#company.com"]
If we were to implement this system now, we would loose the possibility to create new users because all emails would come from the same "no-reply" adress.
I have searched in the Atlassian forums and such, but with no luck. Have not found anything in the official documentation, but I fear that I might be looking in the wrong place.
I hope that I'm being clear, and that someone has any idea if it is possible.
Thank you!
You need to write your own plugin and create your own Mailhandler.
For example you can use a regex which looks for the tag
[userEmail:"michael.smith#company.com"] and retrieve the emailadress from the string. Do the same for the [user]-tag, if the user doesn't exist.
Here is a tutorial that shows how to create and setup custom Message Handlers:
https://developer.atlassian.com/jiradev/jira-platform/guides/email/tutorial-custom-message-mail-handler-for-jira#Tutorial-Custommessage(mail)handlerforJIRA-Step7:Implementarealmessagehandlerback-end
The rest should be easy from here.

Acessing calendar of user email address using Java

I have a requirement. I need to access a user's email that is on company specific domain. I need to get the calendar of that user and publish it to web application. I am exhausted finding any API that can help me to do that. The email client used by company is Thunder Bird, So , in specific, I need to access calender's from Thunder Bird for that particular user. Can any one tell me some suggestions for this.
Kumar
Your question is very unprecise (what kind of is the server providing the emails/calendars? Is there a LDAP Domain? And so on). I suppose you are talking about an old Exchange Server because of some Domain and WebDAV and problems while searching? But I maybe can give you at least a bit of help, that may lead you to already trodden paths of other coders, so that you may find a simple and fast solution.
Today I finished a M$ Exchange 2003 Connector as a proof-of-concept. And I tell you, that it was really hard for me as a student while an Internship. Nonetheless, I researched and searched and queried and annoyed other to get hints for a useful API, but none fulfilled my purposes.
One small framework I found which is nice to use is called Sardine WebDAV Client for Java. The project is very light-weighted, though it was helpful to get an idea how WebDAV works, even due to sources you can always look at.
All other solutions aimed at a lot of different MAPI CC++ Libs for Linux. That was no option for me.
So, what options did I have? No direct access to the customers Exchange 2k3 Server, but one email account. So you all may forgive me, but I found it much easier to make a POST request to the E2k3 Server via OWA, because it was activated than trying some heavy lib supported ways of accessing.
Maybe this comes to your avail- Get the form-field information from the OWA form and build a connection string you Post to the server. Perhaps this is a string that might give you an idea. So you need to call a DLL like this:
HttpPost httpPost = new HttpPost("https://" + getUrl()
+ "/exchweb/bin/auth/owaauth.dll");
httpPost.setEntity(new StringEntity("destination=https%3A%2F%2F"
+ getUrl() + "%2Fexchange%2F&flags=0&username=" + getUser()
+ "&password=" + getPassword()
+ "&SubmitCreds=Log+On&trusted=4&flags=4", "UTF-8"));
The information how to make a form based authentication came from here: Exchange 2003 Forms-Based Authentication. As you can see I grabbed from the browser the Link, which is used to communicate with the E2k. The next step is simple - send the request and wait for...
HttpResponse response = httpclient.execute(httpPost);
If you get a good response in return, then you can filter out the Session ID. The next step after a successful login is to search for appointments. Therefore you should find a appropriate method to work with on an established WebDAV connection by asking M$ for some Information: SEARCH Method
Then, you read what it can do. I went on with a well-known Find-Machine and queried for Searching Calendar Folders with WebDAV.
After that you can create a POST request like this:
HttpPost hp = new HttpPost(
"https://owa.SERVER.de/exchange/USER/Calendar") {
#Override
public String getMethod() {
return "SEARCH";
}
};
Now you can make use of the SEARCH method. That is good, because your program is ready to send the request.
hp.setEntity(new StringEntity(QUERY, ContentType.TEXT_XML));
HttpResponse response = httpclient2.execute(hp);
I know it is no perfect solution. Because there were two circumstances which made me wonder. Firstly: I retrieved a Session ID, but I wasn't in need to re-use it anywhere, as long as I kept it in a field. And secondly: I needed to call for another HttpClient. I cannot explain right now. If I used the same HttpClient I used for logon, then all request were in vain. That is why I had to call another HttpClient.
The last and most difficult step was to get behind the query, because the only debugging help I had were HTTP Error Numbers and the bad descriptions in the MSDN. Sorry for that. Well, this is what really worked fine. I got behind it with Trial and Error.
private final static String QUERY = "<?xml version=\"1.0\"?><g:searchrequest
xmlns:g=\"DAV:\"><g:sql> Select \"DAV:href\", \"urn:schemas:calendar:dtstart\",
\"urn:schemas:calendar:dtend\", \"urn:schemas:mailheader:subject\",
\"urn:schemas:calendar:duration\" FROM Scope('SHALLOW TRAVERSAL OF
\"/exchange/USER/Calendar\"')</g:sql></g:searchrequest>";
This is no particular query. I just alternated it from another Document and removed all stuff I didnt't need.
I hope this helps you a bit. About providing Thunderbird Appointment/Calendar dates I can't tell anything because this is yet beyond my knowledge.
Best regards and good night,
Semo

How to pass long URL in plain text emails?

I have this account creation email that is sent out to anyone who is trying to create an account as I need to authenticate that they are who they say they are.
However, my issue here is that the URL where they need to click when they receive my email is too long and some email clients do not handle that very well and sometimes truncates the URL thus making the URL invalid when clicked.
Because the URL contains the domain name, the hashed email and a long activation code. It looks something like this.
http://domain.com/activation?email=75a5867d3df134bededbaf24ff17624d&key=8fecb20817b3847419bb3de39a609afe
While some email clients are ok with this but some are not...And I don't want to use HTML email and rather stick with plain/text email. Also I heard horrible stories using URL shorteners so I am not sure if I should use them...
Any insights in this area is appreciated!
I would definitely agree with Jason: shorten your url.
Think of what you really need.
Most likely the email address is in the database already, so you can refer to if with a short ID (let's say 7 numbers max). Your signature can be something very simple as substring (base64_url(md5(email+salt)), 0, 5). 5 base64 characters are 64^5=about 1 billion possibilities. This is probably secure enough (and what would the real damage be if someone registered with a wrong email address). So your url would be http://domain.com/activation?email=1234&key=aD5Y_, http://domain.com/activation?e=1234&k=aD5Y_ or even http://domain.com/activation?e=1234aD5Y_ . In the last format you know the last 5 characters are the key, so the rest is the id. Note that the code example assumes md5 to return in an 8-bit string format (and not hex string format), and base64_url uses a url safe base64 method. Also, some background info on a salt.
If your email address has a long id or needs to be encoded in the url as well, or the above is not short enough yet, consider an even shorter form. Basically this will result in making your own url shortener. Just before you insert the link into the email, generate some random 5 character string. Insert this string as key into memcached (or the database), with as value the original url. Then your url could be http://domain.com/redirect?key=rT-tW . When you see this in your app, just retrieve the original url from the database/memcached and redirect there.
Do make sure that your system is robust against the following:
Someone enters an email address (their real email), you send the link
That person changes their email address into something fake on the website before clicking the link, you send a new email to the new (fake) email address
They now click the link from the first email and your website confirms their email address in the second (fake) form.
One way to do this is make sure to use the email address itself (and not for instance just the user id) in the key generation, as suggested above.

Alternative to emailing long URLs?

I have a web application which uses URLs that look like this:
http://library.example.com/Register.aspx?query=academic&key=586c70bb-5683-419c-aae9-e596af9ab66a
(The GUID is used instead of a plain int to discourage guessing, which is all we need for now.)
The problem: that long URL frequently breaks when sent via email. It's humans sending the emails, so I can't control the formatting. Sometimes it's the sending email program at fault, sometimes the receiving, but regardless I'm spending too much time on talking people through fixing problems.
Everything has to be from this domain, so I can't use a third-party shortener. I could host my own, but that seems like a kludge.
Any suggestions?
Edits
#Sunny: Thanks for elaborating, but my situation differs from what you assume. A corporate customer (of mine) passes this URL to its employees, and they use it to get to a branded Registration page. They need to give a working email as part of registration, and that gets forwarded to the corporate supervisor.
Registration gets them access to a database, but what they see is not specific to the corporate customer. So the occasional interloper is not a big deal; when they get weeded out by the corporate supervisor, we invite them to subscribe.
#Everybody: the email breakage is not on the punctuation (?&=), but at some predetermined line-length. Surprised me, too. Note that the domain name is long, as is the path to the virtual directory, which is a part of the problem.
After reading the responses, I'm going to use base64 as a pseudo-shortener, something like:
http://a.MyLongDomainName.com/?q=a&key=base64_encoded_GUID
...and see if that survives. Thanks to all.
You can at least shorten it a bit. Right now, you're send a GUID, which is a 128-bit number, in a format that is essentially hexadecimal with extra dashes. If you view the GUID as a byte array and convert it to Base64, you can cut things down a bit. Likewise, "query=academic" could be "q=a".
The GUID is currently taking up 36 characters. Converting to Base-64 cuts this down to 22, saving 14 chars. Replacing "query=academic&key=" with "q=a&k=" shaves off another 13. Cutting a total of 27 characters may well keep your URL short enough not to wrap, despite the presence of ampersands and equal signs.
One more detail: the Base-64 text is going to end with an "=", which will then be hex-encoded into "%3D". The solution is to cut that character off, because it's just padding.
With credit to the original posters, it looks like the best bet is a combination of things:
Compact GUID with base-64.
Shorten key names and, if possible, values.
Wrap URL in angle-braces to encourage client to parse it properly.
If possible, replace key names with URL-rewriting, so that it looks like a path.
If you can't use a third-party URL shortener, then your only option (besides changing the URL structure, as Sunny suggested) is to surround your URL with angle brackets, like this:
<http://library.YourDomainNameHere.com/Register.aspx?query=academic&key=586c70bb-5683-419c-aae9-e596af9ab66a>
Any email client that follows the guidelines found in the Uniform Resource Identifiers (URI): Generic Syntax document should display a clickable link. This is not a fool-proof solution, however, and you'll likely end up resorting to a URL shortening service or restructuring your URLs.
The only alternative to installing your own shortener service (which would be the ideal solution IMO), may be base64 encoding of the whole URL (and using a shorter key). But that would increase string length by 33% (very likely to break in E-Mail clients as well), and look ugly.
I would go with building a URL shortener service that shortens URLs on demand to something like this:
http://library.example.com/go/586c70bb-5683-419c-aae9-e596af9ab66a
There are some prepackaged URL Shorteners that you could host on your own. Here's a codeplex search
http://www.codeplex.com/site/search?query=url%20shortener
This will give you the ability to keep your short url's in house
Alternatively you could some how implement a RESTFul URL that would be a lot harder to screw up
http://library.example.com/Register/Academic/586c70bb-5683-419c-aae9-e596af9ab66a
This solution should work better than the querystring simply because what usually breaks in the email clients is the ?, the =, and the &
I personally think a RESTFul solution is best as it creates the cleanest urls that still make "some" sense.
How about replacing the GUIDS with YouTube style keys
e.g. http://library.example.com/Register.aspx?q=academic&k=jkGlkNu8
By using base-64 strings (instead of Guids which are base-16) and dropping those pesky dashes, you can pack a decent range of unique keys into a small amount of characters.
What about a combination of the methods described here?
Combining shorter URLs with Base64 encoding of the key would turn
http://library.example.com/Register.aspx?query=academic&key=586c70bb-5683-419c-aae9-e596af9ab66a
into
http://l.example.com/register/ac/WGxwu1aDQZyq6eWWr5q2ag
Much more readable, IMO. And lack of chars like ? and & reduces the risk of cut'n'paste errors.
REST-ful url like:
http://www.yourdomainhere.com/register/academic/{userName_here}
might help IMO.
If the user is not registered, this will do it & return a message confirming the fact
If the user has already been registered, there will be no action & perhaps a notification that the user has been registered can be shown.
The routing of the URL and/or validating the request etc. can be implementation detail best left to a module looking at the request pipeline...
HTH.
EDIT:
As pointed out by #Steven below, there is an addition step involved in this solution:
When the user clicks on the REST URL, launch the confirmation/login screen with the user name pre-filled. The user can login to the account & this is confirmation that the user is valid. Till he does the first login, the status of the account can be "not confirmed" & at his first login, it can be "confirmed" without bothering if the click/request has come from the email sent and/or via a request in a web browser.
This will also ensure that it will work for authentic email account since till the user actually does a valid login, the account will not be in "confirmed" status...

Embed indentifier within an Email

I am trying to embed an ID into an email so that when a recipient replies to an email that my system sends out, my system can pick it up and match the two together.
I have tried appending a custom header, however this is stripped out when the user replies.
I have tried embedding an HTML comment within the email, but outlook does not seem to keep comments when a reply email is created.
Worst case scenario, I can manually try and match the sent and received emails by time span or have a visible tag within the message body.
Does anyone know of a more elegant solution?
Thanks in advance
Email messages already contain such an identifiers, called Message-ID. And there's even a way to send which message you're replying to by sending that ID in a header called In-Reply-To. That's done by pretty much all email clients, that's how they usually do their threading.
It's defined in RFC 822 (yep that's pretty old) and probably re-defined and refined in more modern versions of that.
I have seen a method that includes a one byte image with a unique name that's linked to the user. When they view the email and download the images, your HTTP server will record a hit for that unique image. Of course the user needs to display images, but you can include a message in the body asking them to display the images. We actually include content in an image so they need to show images.
If your incoming e-mail can handle +foo or -foo suffixes, use that.
Many e-mail systems can route user+foo#example.com or user-foo#example.com
to user#example.com. You can replace foo with some kind of identifier.
Several mailing list servers use this for tracking bounces.
While I can't say for certain, my investigation in that sort of matter some time ago yielded the following "conclusion":
Headers are transformed a lot
Message bodies are transformed a lot
This is partly because, I suspect, of:
Need to protect users from malicious intentions
Need to perform "targeted marketing"
I have seen "unique codes" flying around in clear text in the email body but I would suggest having a unique identifier embedded in the return address instead.
The usual approach is to place the id in the subject line and/or somewhere visible in the message text and informing the recipient that he should not modify the subject or quote the original mail when responding.