Back to blog

Delphi and Saf.li – Easy URL Shortening

PROGRAMMING

3 min read
Delphi and Saf.li – Easy URL Shortening

URL shortening has become a thing since the invasion of Twitter and Twitter-like microblogging platforms, since they are pretty harsh with length. If you’re following me on Twitter, you probably know that I’m a big fan of Saf.li, BitDefender‘s URL shortening service with a twist.

I have already created a WordPress plugin to automatically twitt my blog posts which relies on Saf.li for permalink URL shortening, and the job seems to be pretty straightforward if you’re using PHP. However, if you’re planning to create a desktop application that, say, processes batches of URLs and transforms them in their diminutive version, there may be implementation issues.

UPDATE: Saf.li has been discontinued. This product doesn’t work anymore, but information in this post will still be available to serve as proof-of-concept.

Start by creating a new project, and don’t forget to add WinInet to your Uses clause, as shown below:

uses WinInet;

Then let’s proceed further with creating the following function. This will be called with the URL we would like to shorten and will return a string with the shortened URL, as delivered by saf.li.

function GetShortURL(URL: string): string;
var
    NetHandle: HINTERNET;
    UrlHandle: HINTERNET;
    Buffer: array[0..1024] of Char;
    BytesRead: dWord;
begin
    Result := '';
    
    // Prepend the saf.li link generation location to the URL
    URL := 'http://saf.li/create?ws=1&url=' + URL;
    
    NetHandle := InternetOpen('Delphi 5.x', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
    
    if Assigned(NetHandle) then
    begin
        UrlHandle := InternetOpenUrl(NetHandle, PChar(URL), nil, 0, INTERNET_FLAG_RELOAD, 0);
        
        if Assigned(UrlHandle) then
        begin
            // UrlHandle seems to be valid, let's fetch the output (what saf.li responds, that is)
            FillChar(Buffer, SizeOf(Buffer), 0);
            
            repeat
                Result := Result + Buffer;
                FillChar(Buffer, SizeOf(Buffer), 0);
                InternetReadFile(UrlHandle, @Buffer, SizeOf(Buffer), BytesRead);
            until BytesRead = 0;
            
            InternetCloseHandle(UrlHandle);
        end
        else
        begin
            // UrlHandle is invalid, prompt the user about that 
            raise Exception.CreateFmt('Your URL %s is inaccessible. Please try again', [URL]);
        end;
        
        InternetCloseHandle(NetHandle);
    end
    else
    begin
        // NetHandle is invalid, prompt the user about that
        raise Exception.Create('There is an error with WinInet. Whoopsie daisy.');
    end;
end;

This is a typical example of calling the function. Just place on your form two TEdit controls and a button, then define the onClick action of the button as follows:

Edit2.Text := GetShortURL(Edit1.Text);

Now the function will respond with a short link everytime you fill in a regular URL and click on the button.

Note: this work is based on a piece of code released courtesy of Scalabium Software and modified by me to suit the purpose. You are free to use it as you see fit, but please be aware that this snippet is released “as-is” and there are no guarantees as to the functionality and usability of the code.

PS: since the piece of code relies on wininet.dll, which is a significant part of Microsoft’s Internet Explorer, the code will no work on systems that do not have Internet Explorer installed.