.NET Fetch user timeline using API 1.1 and oAuth: 401 Unauthorized


#1

Example of my base string and header. I am getting 401 unauthorized every single time and unfortunately unable to identify any issue here. Pointers will be highly appreciated.

  • I can’t use any third party libraries (requirement)

Base string
GET&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fstatuses%2Fuser_timeline.json%3Fscreen_name%3Dcountscar%26count%3D30&oauth_consumer_key%3DrUgr1nLBLABLA%26oauth_nonce%3DBLABLA%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1353462617%26oauth_token%BLABLA-eC7VqXajmgAju3bG41wFkJcwDg1fT4THLNMj2EHj%26oauth_version%3D1.0

Header
Authorization: OAuth oauth_nonce=“BLABLA”, oauth_signature_method=“HMAC-SHA1”, oauth_consumer_key=“BLABLA”, oauth_token=“BLABLA-eC7VqXajmgAju3bG41wFkJcwDg1fT4THLNMj2EHj”, oauth_signature=“BLABLA8HSMGi9bH4HznY%3D”, oauth_timestamp=“1353462617”, oauth_version="1.0"
Content-Type: application/x-www-form-urlencoded

This is how I am generating my signature

var timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);

            var oauthTimestamp = Convert.ToInt64(timeSpan.TotalSeconds)
                .ToString(CultureInfo.InvariantCulture);

            var encoding = Encoding.ASCII;

            var oauthNonce = Convert.ToBase64String(
                encoding.GetBytes(DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture)));

            var userTimelineUrl = string.Format(
                "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name={0}&count={1}",
                parameters.ScreenName,
                parameters.FetchCount);

            var baseString = string.Format(
                "&oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}&oauth_timestamp={5}&oauth_token={3}&oauth_version={4}",
                consumerKey,
                oauthNonce,
                oauthSignatureMethod,
                accessToken,
                oauthVersion,
                oauthTimestamp);

            var compositeKey = string.Concat(Uri.EscapeDataString(consumerSecret),
                                                "&", Uri.EscapeDataString(accessTokenSecret));

            string oauthSignature;
            using (var hasher = new HMACSHA1(encoding.GetBytes(compositeKey)))
            {
                oauthSignature = Convert.ToBase64String(
                    hasher.ComputeHash(encoding.GetBytes(
                        string.Concat("GET&", Uri.EscapeDataString(userTimelineUrl),
                        Uri.EscapeDataString(baseString)))));
            }

            var authHeader = string.Format(
                "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", oauth_consumer_key=\"{2}\", oauth_token=\"{3}\", oauth_signature=\"{4}\", oauth_timestamp=\"{5}\", oauth_version=\"{6}\"",
                Uri.EscapeDataString(oauthNonce),
                Uri.EscapeDataString(oauthSignatureMethod),
                Uri.EscapeDataString(consumerKey),
                Uri.EscapeDataString(accessToken),
                Uri.EscapeDataString(oauthSignature),
                Uri.EscapeDataString(oauthTimestamp),
                Uri.EscapeDataString(oauthVersion));

            ServicePointManager.Expect100Continue = false;

            var request = WebRequest.Create(userTimelineUrl);

            request.Headers.Add("Authorization", authHeader);
            request.Method = "GET";
            request.ContentType = "application/x-www-form-urlencoded";

            var responseStream = request.GetResponse().GetResponseStream();

#2

Can anyone please point any mistake int he code above? Thanks in advance


#3

Bump


#4
  1. I think the baseString is incorrect. This string must also include any parameters in the url request. In your case, this would be screen_name and count. Include both key and value. Be sure to add them in the correct order sorted by key.

  2. In my code, I also sort the keys in the authHeader string, but this may not be required.


#5

Working code for Get Operation on any user timeline

// oauth application keys var oauth_token = "update me"; var oauth_token_secret = "update me"; var oauth_consumer_key = "update me"; var oauth_consumer_secret = "update me";
        // oauth implementation details
        var oauth_version = "1.0";
        var oauth_signature_method = "HMAC-SHA1";

        // unique request details
        var oauth_nonce = Convert.ToBase64String(
            new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
        var timeSpan = DateTime.UtcNow
            - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
        var oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();

        // message api details
        var status = "Updating status via REST API if this works";
        var resource_url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
        var screen_name = "updateme";
        // create oauth signature
        var baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
                        "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&screen_name={6}";

        var baseString = string.Format(baseFormat,
                                    oauth_consumer_key,
                                    oauth_nonce,
                                    oauth_signature_method,
                                    oauth_timestamp,
                                    oauth_token,
                                    oauth_version,
                                     Uri.EscapeDataString(screen_name)
                                    );

        baseString = string.Concat("GET&", Uri.EscapeDataString(resource_url), "&", Uri.EscapeDataString(baseString));

        var compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret),
                                "&", Uri.EscapeDataString(oauth_token_secret));

        string oauth_signature;
        using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
        {
            oauth_signature = Convert.ToBase64String(
                hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
        }

        // create the request header
        var headerFormat = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", " +
                           "oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", " +
                           "oauth_token=\"{4}\", oauth_signature=\"{5}\", " +
                           "oauth_version=\"{6}\"";

        var authHeader = string.Format(headerFormat,
                                Uri.EscapeDataString(oauth_nonce),
                                Uri.EscapeDataString(oauth_signature_method),
                                Uri.EscapeDataString(oauth_timestamp),
                                Uri.EscapeDataString(oauth_consumer_key),
                                Uri.EscapeDataString(oauth_token),
                                Uri.EscapeDataString(oauth_signature),
                                Uri.EscapeDataString(oauth_version)
                        );


        // make the request
       
        ServicePointManager.Expect100Continue = false;

        var postBody = "screen_name=" + Uri.EscapeDataString(screen_name);//
        resource_url += "?" + postBody;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resource_url);
        request.Headers.Add("Authorization", authHeader);
        request.Method = "GET";
        request.ContentType = "application/x-www-form-urlencoded";
  
       
        WebResponse response = request.GetResponse();
        string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();

#6

Bobby - I’m trying to use this with API ver 1.1 but keep getting the error “(400) Bad Request.” Is that indicative of anything in particular, or do you know where I could start to try and figure out why it’s not working?

Thanks


#7

Never mind Bobby, I had one of the variables misspelled. It works great!

Thanks


#8

Bobby this is great. Though how do I add that I only want 5 posts? Is it just adding “&count=5” to the POST body? I am getting a 401 as soon as I add that. Where does it need to go?

Thanks.


#9

@bobbykc13 thanks for posting this. My solution was very close, I just wasn’t appending the query string variables. A lot of people have been frustrated by this problem

@DIYMediaService, The following code will get you the count

var baseFormat = "count={7}&oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" + "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&screen_name={6}";

var baseString = string.Format(baseFormat,
oauth_consumer_key,
oauth_nonce,
oauth_signature_method,
oauth_timestamp,
oauth_token,
oauth_version,
Uri.EscapeDataString(screen_name),
Uri.EscapeDataString(count)
);



.var postBody = string.Format(“screen_name={0}&count={1}”, Uri.EscapeDataString(screenName), Uri.EscapeDataString(count));


#10

Cheers, above tips saved me! How about if the screen_name has a list called “thelist”, can I access it just by adding like “list_name={8}” in the baseFormat and then add it to the baseString String.Format like Uri.EscapeDataString(“thelist”), maybe also add it to the postBody as &=list_name=thelist

I looked in the docs but I can not find it… Thankful for a solution :slight_smile:

EDIT: Found “solution”, its an other resource_url and som ohter vars in the base.


#11

Change of access to public data seems to be the end of twitter popularity. You can find millions of apps using simply the REST api 1.0 which will not be able to ask a API KEY from each users. They will shut down the twitter option…


#12

Thankyou very much for this I had to make use of this for a VB.NET application. See below for VB.NET version:

'oauth application keys ' https://dev.twitter.com/apps/ Dim oauth_token As String = "" Dim oauth_token_secret As String = "" Dim oauth_consumer_key As String = "" Dim oauth_consumer_secret As String = ""
    ' oauth implementation details
    Dim oauth_version As String = "1.0"
    Dim oauth_signature_method As String = "HMAC-SHA1"

    ' unique request details
    Dim oauth_nonce As String = Convert.ToBase64String(New ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()))
    Dim TimeSpan As TimeSpan = DateTime.UtcNow - New DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
    Dim oauth_timestamp As String = Convert.ToInt64(TimeSpan.TotalSeconds).ToString()

    ' message api details
    Dim status As String = "Updating status via REST API if this works"
    Dim resource_url As String = "https://api.twitter.com/1.1/statuses/user_timeline.json"
    Dim screen_name As String = "<REPLACE>"

    ' create oauth signature
    Dim baseFormat As String = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" + _
                    "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&screen_name={6}"

    Dim baseString As String = String.Format(baseFormat,
                                    oauth_consumer_key,
                                    oauth_nonce,
                                    oauth_signature_method,
                                    oauth_timestamp,
                                    oauth_token,
                                    oauth_version,
                                    Uri.EscapeDataString(screen_name)
                                    )

    baseString = String.Concat("GET&", Uri.EscapeDataString(resource_url), "&", Uri.EscapeDataString(baseString))

    Dim compositeKey As String = String.Concat(Uri.EscapeDataString(oauth_consumer_secret), _
                            "&", Uri.EscapeDataString(oauth_token_secret))

    Dim oauth_signature As String
    Dim hasher As New HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey))

    oauth_signature = Convert.ToBase64String(hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)))
    hasher.Dispose()


    ' create the request header
    Dim headerFormat As String = "OAuth oauth_nonce=""{0}"", oauth_signature_method=""{1}"", " + _
                                    "oauth_timestamp=""{2}"", oauth_consumer_key=""{3}"", " + _
                                    "oauth_token=""{4}"", oauth_signature=""{5}"", " + _
                                    "oauth_version=""{6}"""

    Dim authHeader As String = String.Format(headerFormat, _
                            Uri.EscapeDataString(oauth_nonce), _
                            Uri.EscapeDataString(oauth_signature_method), _
                            Uri.EscapeDataString(oauth_timestamp), _
                            Uri.EscapeDataString(oauth_consumer_key), _
                            Uri.EscapeDataString(oauth_token), _
                            Uri.EscapeDataString(oauth_signature), _
                            Uri.EscapeDataString(oauth_version))


    ' make the request
    ServicePointManager.Expect100Continue = False

    Dim postBody As String = "screen_name=" + Uri.EscapeDataString(screen_name)
    resource_url += "?" + postBody


    Dim request As HttpWebRequest = CType(WebRequest.Create(resource_url), HttpWebRequest)
    request.Headers.Add("Authorization", authHeader)
    request.Method = "GET"
    request.ContentType = "application/x-www-form-urlencoded"

    Dim response As WebResponse = request.GetResponse()
    Dim responseData As String = New StreamReader(response.GetResponseStream()).ReadToEnd()

And don’t forget the imports statements required:

Imports System.Net Imports System.Security.Cryptography Imports System.IO

To obtain the security token, key etc for a new application:


#13

I want to send other parameters as well to https://api.twitter.com/1.1/statuses/user_timeline.json.
I tried to send count=5 in the same way you have suggested and it is working fine. I want to send trim_user=true,include_rts=false. I tried to send it in a similar way but its not working. It is returning 401 unauthorised. Please help


#14

Hi,
I want to send other parameters as well to https://api.twitter.com/1.1/statuses/user_timeline.json.
I tried to send count=5 in the same way you have suggested and it is working fine. I want to send trim_user=true,include_rts=false. I tried to send it in a similar way but its not working. It is returning 401 unauthorised. Please help


#15

In a mad panic all week to find a simple replacement for the RSS feed which I’ve used on dozens of websites and this looks like it will do the trick. I’m especially grateful for the VB code which has got me to the point of returning the data. Now I just have to figure out how to parse this, any VB examples would be very nice thank you.


#16

SittingbourneMe Zoe,

I too have had to rush to get this working again, for an app in our case was using twitterizer previously.

I’ve broken this down into a few classes to abstract away a lot of the code and parse the response. Admittedly I’ve rushed a bit.

Classes:

OAuth for authentication
GETRequest to send the web request
TimeLine & Tweet - Data Structures
TimeLineParser - Changes the response text into a timeline object.

oAuth:

Option Strict On

Imports System.IO
Imports System.Text
Imports System.Net
Imports System.Security.Cryptography

Namespace SocialNetworking.Twitter
Public Class OAuth

#Region "Members"
Private m_Token As String = ""
Private m_TokenSecret As String = ""
Private m_ConsumerKey As String = ""
Private m_ConsumerSecret As String = “”

    Private m_Version As String = "1.0"
    Private m_SignatureMethod As String = "HMAC-SHA1"
    Private m_Signature As String = ""

    Private m_Nonce As String = ""
    Private m_TimeSpan As TimeSpan = Nothing
    Private m_Timestamp As String = ""

    Private m_ScreenName As String = ""
    Private m_ResourceURL As String = ""

#End Region

#Region "Properties"
Public Property Token() As String
Get
Return m_Token
End Get
Set(value As String)
m_Token = value
End Set
End Property
Public Property TokenSecret() As String
Get
Return m_TokenSecret
End Get
Set(value As String)
m_TokenSecret = value
End Set
End Property
Public Property ConsumerKey() As String
Get
Return m_ConsumerKey
End Get
Set(value As String)
m_ConsumerKey = value
End Set
End Property
Public Property ConsumerSecret() As String
Get
Return m_ConsumerSecret
End Get
Set(value As String)
m_ConsumerSecret = value
End Set
End Property
Public Property ScreenName() As String
Get
Return m_ScreenName
End Get
Set(value As String)
m_ScreenName = value
End Set
End Property
Public Property ResourceURL() As String
Get
Return m_ResourceURL
End Get
Set(value As String)
m_ResourceURL = value
End Set
End Property

#End Region

#Region “Constructors”

    Private Sub CommonNew()
        m_Nonce = Convert.ToBase64String(New ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()))
        m_TimeSpan = DateTime.UtcNow - New DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
        m_Timestamp = Convert.ToInt64(m_TimeSpan.TotalSeconds).ToString()
    End Sub

    Public Sub New()
        CommonNew()
    End Sub

    Public Sub New(ByVal ScreenName As String)
        CommonNew()
        m_ScreenName = ScreenName
    End Sub

    Public Sub New(ByVal ScreenName As String, ByVal ResourceURL As String)
        CommonNew()
        m_ScreenName = ScreenName
        m_ResourceURL = ResourceURL
    End Sub

#End Region

    Private Sub CreateToken()

        Dim baseFormat As String = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" + _
                                    "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&screen_name={6}"

        Dim baseString As String = String.Format(baseFormat,
                                        m_ConsumerKey,
                                        m_Nonce,
                                        m_SignatureMethod,
                                        m_Timestamp,
                                        m_Token,
                                        m_Version,
                                        Uri.EscapeDataString(m_ScreenName))

        baseString = String.Concat("GET&", Uri.EscapeDataString(m_ResourceURL), "&", Uri.EscapeDataString(baseString))

        Dim compositeKey As String = String.Concat(Uri.EscapeDataString(m_ConsumerSecret), "&", Uri.EscapeDataString(m_TokenSecret))


        Dim hasher As New HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey))
        m_Signature = Convert.ToBase64String(hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)))
        'hasher.Dispose()

    End Sub

    Public Function GetHeader() As String

        CreateToken()

        ' create the request header
        Dim headerFormat As String = "OAuth oauth_nonce=""{0}"", oauth_signature_method=""{1}"", " + _
                                        "oauth_timestamp=""{2}"", oauth_consumer_key=""{3}"", " + _
                                        "oauth_token=""{4}"", oauth_signature=""{5}"", " + _
                                        "oauth_version=""{6}"""

        Dim authHeader As String = String.Format(headerFormat, _
                                Uri.EscapeDataString(m_Nonce), _
                                Uri.EscapeDataString(m_SignatureMethod), _
                                Uri.EscapeDataString(m_Timestamp), _
                                Uri.EscapeDataString(m_ConsumerKey), _
                                Uri.EscapeDataString(m_Token), _
                                Uri.EscapeDataString(m_Signature), _
                                Uri.EscapeDataString(m_Version))

        Return authHeader

    End Function

End Class

End Namespace

GetRequest

Option Strict On

Imports System.Net
Imports System.IO

Namespace SocialNetworking.Twitter
Public Class GETRequest

#Region “Members”

    Private m_ResourceUrl As String = ""
    Private m_Authenticate As Boolean = True
    Private m_AuthHeader As String = ""
    Private m_RequestMethod As String = "GET"
    Private m_ContentType As String = "text/plain" '"application/x-www-form-urlencoded"
    Private m_ScreenName As String = ""
    Private m_OAuth As OAuth = Nothing

#End Region

#Region "Properties"
Public Property OAuth() As OAuth
Get
Return m_OAuth
End Get
Set(value As OAuth)
m_OAuth = value
End Set
End Property
Public Property ScreenName() As String
Get
Return m_ScreenName
End Get
Set(value As String)
m_ScreenName = value
End Set
End Property
#End Region

    Public Sub New(ByVal ResourceURL As String)
        m_ResourceUrl = ResourceURL
    End Sub

    Public Sub New(ByVal ResourceURL As String, ByVal Authenticate As Boolean)
        m_ResourceUrl = ResourceURL
        m_Authenticate = Authenticate
    End Sub

    Public Sub New(ByVal ResourceURL As String, ByVal Authenticate As Boolean, OAuth As OAuth)
        m_ResourceUrl = ResourceURL
        m_Authenticate = Authenticate
        m_OAuth = OAuth
    End Sub

    Public Function GETResponse() As String

        ServicePointManager.Expect100Continue = False

        Dim postBody As String = "screen_name=" + Uri.EscapeDataString(m_ScreenName)
        m_ResourceUrl += "?" + postBody

        Dim request As HttpWebRequest = CType(WebRequest.Create(m_ResourceUrl), HttpWebRequest)

        If m_Authenticate Then
            m_AuthHeader = m_OAuth.GetHeader()
            request.Headers.Add("Authorization", m_AuthHeader)
        End If

        request.Method = m_RequestMethod
        request.ContentType = m_ContentType

        Dim response As WebResponse = request.GetResponse()
        Dim responseData As String = New StreamReader(response.GetResponseStream()).ReadToEnd()

        Return responseData

    End Function

End Class

End Namespace

Tweet

Option Strict On

Namespace SocialNetworking.Twitter
Public Class Tweet

    Private m_DateTime As Date
    Private m_Text As String

    Public Property DateTime() As Date
        Get
            Return m_DateTime
        End Get
        Set(value As Date)
            m_DateTime = value
        End Set
    End Property
    Public Property Text As String
        Get
            Return m_Text
        End Get
        Set(value As String)
            m_Text = value
        End Set
    End Property

End Class

End Namespace

TimeLine

Option Strict On

Namespace SocialNetworking.Twitter
Public Class TimeLine

    Private m_TimeLine As New List(Of Tweet)

    Public Property TimeLine() As List(Of Tweet)
        Get
            Return m_TimeLine
        End Get
        Set(value As List(Of Tweet))
            m_TimeLine = value
        End Set
    End Property

End Class

End Namespace

TimeLineParser

Option Strict On

Namespace SocialNetworking.Twitter
Public Class TimeLineParser

    Private m_Gumf As String = ""
    Private m_TimeLine As TimeLine = New TimeLine()

    Public Property Gumf() As String
        Get
            Return m_Gumf
        End Get
        Set(value As String)
            m_Gumf = value
            ProcessGumf()
        End Set
    End Property

    Public Property TimeLine() As TimeLine
        Get
            Return m_TimeLine
        End Get
        Set(value As TimeLine)
            m_TimeLine = value
        End Set
    End Property

    Private Sub ProcessGumf()

        Dim timelineParts As String() = m_Gumf.Split({"{""created_at"":"}, StringSplitOptions.RemoveEmptyEntries)

        For i As Integer = 1 To timelineParts.Length - 1 'miss first out
            Dim fullTweet As String = timelineParts(i)
            Dim tweetParts As String() = fullTweet.Split({""","""}, StringSplitOptions.None)

            Dim textPart As String = tweetParts(2).Replace("text"":""", "").Split({" http"}, StringSplitOptions.None)(0)


            Dim timePart As String = tweetParts(0).Replace("""", "")

            Try
                Dim year As Integer = CInt(timePart.Split(CChar(" "))(5))
                Dim day As Integer = CInt(timePart.Split(CChar(" "))(2))
                Dim monthName As String = timePart.Split(CChar(" "))(1)
                Dim month As Integer
                Select Case monthName.ToUpper()
                    Case "JAN"
                        month = 1
                    Case "FEB"
                        month = 2
                    Case "MAR"
                        month = 3
                    Case "APR"
                        month = 4
                    Case "MAY"
                        month = 5
                    Case "JUN"
                        month = 6
                    Case "JUL"
                        month = 7
                    Case "AUG"
                        month = 8
                    Case "SEP"
                        month = 9
                    Case "OCT"
                        month = 10
                    Case "NOV"
                        month = 11
                    Case "DEC"
                        month = 12
                End Select

                Dim hour As Integer
                Dim minute As Integer
                Dim second As Integer

                Dim hhmmss As String = timePart.Split(CChar(" "))(3)

                hour = CInt(hhmmss.Split(CChar(":"))(0))
                minute = CInt(hhmmss.Split(CChar(":"))(1))
                second = CInt(hhmmss.Split(CChar(":"))(2))

                Dim tweetDate As Date = New Date(year, month, day, hour, minute, second)


                Dim newTweet As New Tweet()
                With newTweet
                    .DateTime = tweetDate
                    .Text = System.Web.HttpUtility.HtmlDecode(textPart).Replace("\u2019", "'").Replace("\u00a0", " ")
                End With
                TimeLine.TimeLine.Add(newTweet)

            Catch ex As Exception
                Throw ex
            End Try

        Next

    End Sub

End Class

End Namespace

Example Consuming Code:

''Authentication rubbish!
Dim ao As New OAuth("", “https://api.twitter.com/1.1/statuses/user_timeline.json”)
ao.Token = ""
ao.TokenSecret = ""
ao.ConsumerKey = ""
ao.ConsumerSecret = “”

    Dim ge As New GETRequest("https://api.twitter.com/1.1/statuses/user_timeline.json", True, ao)
    ge.ScreenName = "<REPLACE>"

    Dim p As TimeLineParser = New TimeLineParser
    p.Gumf = ge.GETResponse()

    TextBox1.Clear()
    For i As Integer = 0 To 2 'first three tweets
        Try
            TextBox1.Text += vbCrLf + vbCrLf + vbCrLf
            TextBox1.Text += p.TimeLine.TimeLine(i).DateTime.ToString()
            TextBox1.Text += vbCrLf + vbCrLf
            TextBox1.Text += p.TimeLine.TimeLine(i).Text
        Catch ex As Exception
            throw ex
        End Try
    Next

You may need to add further properties to the tweet, and refine the parser to get them. Hope it helps.

Al


#17

Yeah, I had the same problem… Didn’t understand what the heck was going on, since I’m new to OAuth. Keep in mind that you need to pass variables in alphabetical order! And, your signature must have the same variables as the post body (I think ideally the code should be rewritten and done in the opposite order; first create the body and then the signature. Anyway. This messy code works for me:

  var oauth_token = "[INSERT THIS]";
  var oauth_token_secret = "[INSERT THIS]";
  var oauth_consumer_key = "[INSERT THIS]";
  var oauth_consumer_secret = "[INSERT THIS]";
  var screen_name = "[INSERT THIS]";

  // message api details
  var resource_url = "https://api.twitter.com/1.1/statuses/user_timeline.json";

  // oauth implementation details

  var oauth_version = "1.0";
  var oauth_signature_method = "HMAC-SHA1";

  // unique request details
  var oauth_nonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
  var timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
  var oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();


  // create oauth signature
  var baseFormat = "count=1&exclude_replies=1&include_entities=false&include_rts=false&oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&screen_name={6}&trim_user=1";
  var baseString = string.Format(baseFormat,
                              oauth_consumer_key,
                              oauth_nonce,
                              oauth_signature_method,
                              oauth_timestamp,
                              oauth_token,
                              oauth_version,
                               Uri.EscapeDataString(screen_name)
                              );


  baseString = string.Concat("GET&", Uri.EscapeDataString(resource_url), "&", Uri.EscapeDataString(baseString));

  var compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret), "&", Uri.EscapeDataString(oauth_token_secret));

  string oauth_signature;

  using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey))) {
    oauth_signature = Convert.ToBase64String(
        hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
  }

  // create the request header
  var headerFormat = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", oauth_token=\"{4}\", oauth_signature=\"{5}\", oauth_version=\"{6}\"";

  var authHeader = string.Format(headerFormat,
                          Uri.EscapeDataString(oauth_nonce),
                          Uri.EscapeDataString(oauth_signature_method),
                          Uri.EscapeDataString(oauth_timestamp),
                          Uri.EscapeDataString(oauth_consumer_key),
                          Uri.EscapeDataString(oauth_token),
                          Uri.EscapeDataString(oauth_signature),
                          Uri.EscapeDataString(oauth_version)
                  );

  // make the request
  ServicePointManager.Expect100Continue = false;
  var postBody = "screen_name=" + Uri.EscapeDataString(screen_name);//
  resource_url += "?" + postBody + "&count=1&exclude_replies=1&include_entities=false&include_rts=false&trim_user=1";

  Response.Write(resource_url);
  //Response.End();

  HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resource_url);

  request.Headers.Add("Authorization", authHeader);
  request.Method = "GET";
  request.ContentType = "application/x-www-form-urlencoded";

  WebResponse response = request.GetResponse();

  string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();

#18

I had the same problem. Keep in mind that with OAuth, you need to pass variables in alphabetical order…


#19

This is my working messy version. New to OAuth, didn’t know that variables need to be passed in alphabetical order, got 401’s all the time. Ideally, the original code should be rewritten; first create the post body and then the signature instead of the other way around. But yeah, we’re all in a hurry I guess…

var oauth_token = "[INSERT STUFF HERE]"; var oauth_token_secret = "[INSERT STUFF HERE]"; var oauth_consumer_key = "[INSERT STUFF HERE]"; var oauth_consumer_secret = "[INSERT STUFF HERE]"; var screen_name = "[INSERT STUFF HERE]";
  // message api details
  var resource_url = "https://api.twitter.com/1.1/statuses/user_timeline.json";

  // oauth implementation details

  var oauth_version = "1.0";
  var oauth_signature_method = "HMAC-SHA1";

  // unique request details
  var oauth_nonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
  var timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
  var oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();


  // create oauth signature
  var baseFormat = "count=1&exclude_replies=1&include_entities=false&include_rts=false&oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&screen_name={6}&trim_user=1";
  var baseString = string.Format(baseFormat,
                              oauth_consumer_key,
                              oauth_nonce,
                              oauth_signature_method,
                              oauth_timestamp,
                              oauth_token,
                              oauth_version,
                               Uri.EscapeDataString(screen_name)
                              );


  baseString = string.Concat("GET&", Uri.EscapeDataString(resource_url), "&", Uri.EscapeDataString(baseString));

  var compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret), "&", Uri.EscapeDataString(oauth_token_secret));

  string oauth_signature;

  using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey))) {
    oauth_signature = Convert.ToBase64String(
        hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
  }

  // create the request header
  var headerFormat = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", oauth_token=\"{4}\", oauth_signature=\"{5}\", oauth_version=\"{6}\"";

  var authHeader = string.Format(headerFormat,
                          Uri.EscapeDataString(oauth_nonce),
                          Uri.EscapeDataString(oauth_signature_method),
                          Uri.EscapeDataString(oauth_timestamp),
                          Uri.EscapeDataString(oauth_consumer_key),
                          Uri.EscapeDataString(oauth_token),
                          Uri.EscapeDataString(oauth_signature),
                          Uri.EscapeDataString(oauth_version)
                  );

  // make the request
  ServicePointManager.Expect100Continue = false;
  var postBody = "screen_name=" + Uri.EscapeDataString(screen_name);//
  resource_url += "?" + postBody + "&count=1&exclude_replies=1&include_entities=false&include_rts=false&trim_user=1";

  Response.Write(resource_url);
  //Response.End();

  HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resource_url);

  request.Headers.Add("Authorization", authHeader);
  request.Method = "GET";
  request.ContentType = "application/x-www-form-urlencoded";

  WebResponse response = request.GetResponse();

  string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();

#20

Hi all, thanks for this. @UPL_IT and @SittingbourneMe, I can’t get past an error in your first VB example at line 45. I get “BC30517: Overload resolution failed because no ‘Dispose’ is accessible.” Any thoughts as to what’s going wrong?