Category Archives: CodeProject

TwitPic API Library : TwiPLi

On last weekend, I have been playing around with TwitPic API.

Ok! The thing is that TwitPic API is not that much complex, since all TwitPic provides is that it lets you post your funny/sad looking pictures or any picture you want to post on it, so it can be shared on twitter or any other site. Its pretty much easy to implement all you have to know is how to create a web request, parse a XML, and post Multipart/form-data. You can get complete reference to TwitPic API here: http://twitpic.com/api.do

Since, hosting pictures is a part of some web applications that, I write and will write in future. So, I wrote my own library in .NET framework, that I can use to post pictures on TwitPic. As usual being a lazy guy and considering that code and methods involved are straight forward. I’m giving link to the CodePlex hosted project page, where you can download the library and complete source code (MS-Pl Licensed).

I have documented code at many places, wherever I thought was needed. So, there is very small possibility that you would say the “Holy F Word” while going through it, still if you may want to say so. 😛

CodePlex Project Link http://twipli.codeplex.com

Here I would share the basic process, you need to follow to post your image file on TwitPic.com

TwitPic.com provides 2 methods: UploadAndPost and Upload

——————————————————————————————————————————–

METHOD: UploadAndPost

http://twitpic.com/api/uploadAndPost

Use this method to upload an image to TwitPic and to send it as a status update to Twitter.

——————————————————————————————————————————–

METHOD: Upload

http://twitpic.com/api/upload

Use this method if you just want to upload a photo to TwitPic.

——————————————————————————————————————————–

response to both method is in XML format.

Here is an example:

Fields to post in Method: UploadAndPost
(post data should be formatted as multipart/form-data):

– media (required) – Binary image data
– username (required) – Twitter username
– password (required) – Twitter password
– message (optional) – Message to post to twitter. The URL of the image is automatically added.

Response XML:

<?xml version="1.0" encoding="UTF-8"?>

<rsp status="ok"> <statusid>1111</statusid>

<userid>11111</userid>

<mediaid>abc123</mediaid>

<mediaurl>http://twitpic.com/abc123</mediaurl>

</rsp>

 

Here is the abstract sequence in C# that is needed to do above:

Let the variable Username and Password store the Twitter account credentials and ImagePath and Message are the path to image and Message to be posted.

The first step would be to prepare the post data in Multipart/form-data format

string boundary = Guid.NewGuid().ToString();

string requestUrl = "http://twitpic.com/api/uploadAndPost";

string encoding = "iso-8859-1";
string header = string.Format("--{0}", boundary);
string footer = string.Format("--{0}--", boundary);
StringBuilder contents = new StringBuilder();
contents.AppendLine(header);

//Add image to POST content string

 //determing file content-type                
string fileContentType = GetFileContentType(filename); //MIME type of image //The filename of image
string fileHeader =
String.Format("Content-Disposition: file; name="{0}"; filename="{1}"", "media", filename);
string fileData = Encoding.GetEncoding(encoding).GetString(binaryImageData);

contents.AppendLine(fileHeader);
contents.AppendLine(String.Format("Content-Type: {0}", fileContentType));
contents.AppendLine();
contents.AppendLine(fileData);

 //Add user field in POST string                  
contents.AppendLine(header);
contents.AppendLine(String.Format("Content-Disposition: form-data; name="{0}"", "username"));
contents.AppendLine();
contents.AppendLine(Username);

//Add Password in POST string                 
contents.AppendLine(header);
contents.AppendLine(String.Format("Content-Disposition: form-data; name="{0}"", "password"));
contents.AppendLine();
contents.AppendLine(Password);

 //Add Message in Post string                
if (!String.IsNullOrEmpty(Message))
{
                    contents.AppendLine(header);
                    contents.AppendLine(String.Format("Content-Disposition: form-data; name="{0}"", "message"));
                    contents.AppendLine();
                    contents.AppendLine(Message);
}

contents.AppendLine(footer);
encoding = "iso-8859-1";
byte[] bytes = Encoding.GetEncoding(encoding).GetBytes(contents.ToString());

 

Here is the details of Method: GetFileContentType

It simply returns appropriate MIME type, for an image format.

private string GetFileContentType(string FileName)
        {
            if(FileName.EndsWith("jpg",true,System.Globalization.CultureInfo.CurrentCulture))
            {
                return "image/jpeg";
            }
            else if(FileName.EndsWith("jpeg",true,System.Globalization.CultureInfo.CurrentCulture))
            {
                return "image/jpeg";
            }
            else if(FileName.EndsWith("gif",true,System.Globalization.CultureInfo.CurrentCulture))
            {
                return "image/gif";
            }
            else if(FileName.EndsWith("png",true,System.Globalization.CultureInfo.CurrentCulture))
            {
                return "image/png";
            }
            else
            {
                return "";
            }
        }

Finally parse the response XML, this is done by METHOD: RSPXMLParser

 

private Response RSPXMLParser(string XMLresponse)
        {
            XmlDocument XmlDoc = new XmlDocument();
            int  UserId;
            int StatusId;
            string MediaId;
            string MediaUrl;
            int ErrorCode;
            string ErrorMessage;

            try
            {
                XmlDoc.LoadXml(XMLresponse);
                XmlNodeList RootNode = XmlDoc.SelectNodes("rsp");
                if(RootNode.Item(0).Attributes["status"].InnerText=="ok")
                {
                    MediaId = RootNode.Item(0).SelectNodes("mediaid").Item(0).InnerText;
                    MediaUrl = RootNode.Item(0).SelectNodes("mediaurl").Item(0).InnerText;
                    try
                    {
                        UserId = int.Parse(RootNode.Item(0).SelectNodes("userid").Item(0).InnerText);
                        StatusId = int.Parse(RootNode.Item(0).SelectNodes("statusid").Item(0).InnerText);
                        return new Response(StatusId, UserId, MediaId, MediaUrl);
                    }
                    catch
                    {
                        return new Response(MediaId, MediaUrl);
                    }
                }
                else
                {
                    //<err code="1001" msg="Invalid twitter username or password" />
                    ErrorCode = int.Parse(RootNode.Item(0).SelectNodes("err").Item(0).Attributes["code"].InnerText);
                    ErrorMessage = RootNode.Item(0).SelectNodes("err").Item(0).Attributes["msg"].InnerText;
                    return new Response(ErrorCode, ErrorMessage);
                }
            }
            catch(Exception ex)
            {
                return new Response("XML Parse error: "+ex.ToString());
            }
        }

The Response object referred above:

public class Response
    {
        public readonly int StatusID;                  // like 1111
        public readonly int UserID;                     // like 11111
        public readonly string MediaID;             // like abc123
        public readonly string MediaUrl;            // Something like this http://twitpic.com/abc123
        public readonly string MiniImage;         // Mini Thumbnail URL
        public readonly string ThumbImage;     // Thumbnail URL
        public readonly bool Status;                  // True = Success | False= Fail :-(
        public readonly int ErrorCode;                 // err_code= 1001 - Invalid twitter username or passwor
                                                        // err_code= 1002 - Image not found
                                                        // err_code= 1003 - Invalid image type
                                                        // err_code= 1004 - Image larger than 4MB 

        public readonly string ErrorMessage;     //Will contain the sorry excuse for not doing ur job 😉
                                                         //Invalid twitter username or password

        public Response(int statusid, int userid, string mediaid, string mediaurl) //to be called, when Method = UploadAndPost
        {
                    StatusID = statusid;
                    UserID = userid;
                    MediaID = mediaid;
                    MediaUrl = mediaurl;
                    MiniImage = "http://twitpic.com/show/mini/"+mediaid;
                    ThumbImage = "http://twitpic.com/show/thumb/"+mediaid;;
                    Status = true;
                    ErrorCode = 0;
                    ErrorMessage = "";
        }
        public Response(string mediaid, string mediaurl) //to be called, when Method = Upload
        {
            StatusID = 0;
            UserID = 0;
            MediaID = mediaid;
            MediaUrl = mediaurl;
            MiniImage = "http://twitpic.com/show/mini/" + mediaid;
            ThumbImage = "http://twitpic.com/show/thumb/" + mediaid; ;
            Status = true;
            ErrorCode = 0;
            ErrorMessage = "";
        }
        public Response(int errorcode, string message) //to be called, when error occurs
        {
                    StatusID = -1;
                    UserID = -1;
                    MediaID = "";
                    MediaUrl = "";
                    MiniImage = "";
                    ThumbImage = "";
                    Status = false;
                    ErrorCode = errorcode;
                    ErrorMessage = message;
        }
        public Response(string message)
        {
            Status = false;
            ErrorCode = 0; //there is some internal problem
            ErrorMessage = message;
        }

    }

 

You can run a quick demo of the Library, by creating an Instance in Object test bench and invoking the UploadAndPost method.

In case you want the source code, please download it from here