OAuth lib works with image upload API

Aug 22, 2011 at 7:08 AM

Twitter now has an API for uploading images direct to twitter: https://dev.twitter.com/docs/api/1/post/statuses/update_with_media

Something you might want to consider using from the cropper plugins?

I've got it going with the OAuth lib.  I'm using the Upload.PostFile from Salient as the System.Net.WebClient won't allow me to name the file's form variable.

OAuth.Manager man = new OAuth.Manager(CONSUMER_KEY, CONSUMER_SECRET, token, secret);
string url = "https://upload.twitter.com/1/statuses/update_with_media.xml?"+
    "status=" + OAuth.Manager.UrlEncode("setting up my twitter 私!!"
    );
string header = man.GenerateAuthzHeader(url, "POST");

NameValueCollection headers = new NameValueCollection();
headers.Add("Authorization", header);
            
WebResponse fileResponse = Upload.PostFile(new Uri(url)
    , new NameValueCollection()
    , @"C:\Users\Russ\4063b622-4716-4c19-9050-c7cf8f9f7ec2.jpg"
    , "img/jpeg"
    , "media[]"
    , null
    , headers);


Stream s = fileResponse.GetResponseStream();
using (StreamReader sr = new StreamReader(s))
{
    string res = sr.ReadToEnd();
    Console.Write(res);
}

Coordinator
Oct 10, 2011 at 10:14 PM

Thanks for posting this - very good. 

Seems like the right thing to do is to create a new plugin for this, and let the existing twitpic plugin remain.

 

Coordinator
Oct 10, 2011 at 10:15 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Coordinator
Oct 11, 2011 at 2:50 AM
Edited Oct 11, 2011 at 2:53 AM

This code worked for me, uploading an image to Twitter.

    string twitterUrl1 = "http://api.twitter.com/1/statuses/update.xml?status=";
    string twitterUrl2 = "https://upload.twitter.com/1/statuses/update_with_media.xml";

    private string GetTwitterUpdateUrl()
    {
        return (imageFile == null) ?
            twitterUrl1 + message :  twitterUrl2;
    }

    private static string GetMimeType(String filename)
    {
        var extension = System.IO.Path.GetExtension(filename).ToLower();
        var regKey =  Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(extension);

        string result =
            ((regKey != null) && (regKey.GetValue("Content Type") != null))
            ? regKey.GetValue("Content Type").ToString()
            : "image/unknown" ;
        return result;
    }

    private void Tweet()
    {
        var url = GetTwitterUpdateUrl();
        var authzHeader = oauth.GenerateAuthzHeader(url, "POST");
        var request = (HttpWebRequest)WebRequest.Create(url);

        request.Method = "POST";
        request.PreAuthenticate = true;
        request.AllowWriteStreamBuffering = true;
        request.Headers.Add("Authorization", authzHeader);

        if (imageFile != null)
        {
            string boundary = "======" +
                          Guid.NewGuid().ToString().Substring(18).Replace("-","") +
                          "======";

            var separator = "--" + boundary;
            var footer = "\r\n" + separator + "--\r\n";

            string shortFileName = Path.GetFileName(imageFile);
            string fileContentType = GetMimeType(shortFileName);
            string fileHeader = string.Format("Content-Disposition: file; " +
                                              "name=\"media\"; filename=\"{0}\"",
                                              shortFileName);
            var encoding = System.Text.Encoding.GetEncoding("iso-8859-1");

            var contents = new System.Text.StringBuilder();
            contents.AppendLine(separator);
            contents.AppendLine("Content-Disposition: form-data; name=\"status\"");
            contents.AppendLine();
            contents.AppendLine(message);
            contents.AppendLine(separator);
            contents.AppendLine(fileHeader);
            contents.AppendLine(string.Format("Content-Type: {0}", fileContentType));
            contents.AppendLine();

            request.ServicePoint.Expect100Continue = false;
            request.ContentType = "multipart/form-data; boundary=" + boundary;
            // actually send the request
            using (var s = request.GetRequestStream())
            {
                byte[] bytes = encoding.GetBytes(contents.ToString());
                s.Write(bytes, 0, bytes.Length);
                bytes = File.ReadAllBytes(imageFile);
                s.Write(bytes, 0, bytes.Length);
                bytes = encoding.GetBytes(footer);
                s.Write(bytes, 0, bytes.Length);
            }
        }


        using (var response = (HttpWebResponse)request.GetResponse())
        {
            if (response.StatusCode != HttpStatusCode.OK)
                MessageBox.Show("There's been a problem trying to tweet:" +
                                Environment.NewLine +
                                response.StatusDescription +
                                Environment.NewLine +
                                Environment.NewLine +
                                "You will have to tweet manually." +
                                Environment.NewLine);
        }
    }

To use it, I created the oauth manager class, and set the message and imageFile fields.  like this:

    oauth = new OAuth.Manager();
    oauth["consumer_key"] = APP_CONSUMER_KEY;
    oauth["consumer_secret"] = APP_CONSUMER_SECRET;
    oauth["token"]           = accessToken;
    oauth["token_secret"]    = accessSecret;
    message = "This is the twitter status message";
    imageFile = "C:\\users\\Melvin\\Documents\\MyPhoto.jpg";

 

Oct 31, 2012 at 1:10 PM

Works fantastic, but how can this be used with the in_reply_to_status_id parameter ?

Oct 31, 2012 at 1:47 PM

Ah, that turned out to be not so difficult, just add:

contents.AppendLine(separator)

contents.AppendLine("Content-Disposition: form-data; name=""in_reply_to_status_id""")
contents.AppendLine()
contents.AppendLine(IDofTweetToReplyTo)

Oct 23, 2013 at 3:25 AM
Just an update this no longer works. However if you update the Twitter URLs to this:
    string twitterUrl1 = "https://api.twitter.com/1.1/statuses/update.json?status=";
    string twitterUrl2 = "https://api.twitter.com/1.1/statuses/update_with_media.json";
It 100% works!!

Thanks
Oct 20, 2014 at 9:28 PM
Any full source code working now in oct 2014 with complete changes API Twitter ?