Andy Brown
Andy Brown

Reputation: 5522

Tweeting using API 1.1 suddenly not working January 2014 - SSL/TLS

This is actually half a question, and half to help other people in the same predicament.

Our ASP.NET application has been sending out the odd tweet programmatically happily for a good while now (the last crisis was when Twitter changed their API from 1.0 to 1.1). All I want to be able to do is to send tweets, and I want to learn as little about OAuth as I have to.

I got the original C# code to send tweets in API 1.1 from this excellent page. When it stopped working, I converted the code to VB, so I now have a class which is reproduced here in case anyone finds this useful. Here's how you might call this class:

Dim tweet As New clsTweetVb

    Try
        tweet.Send(Message, ConsumerKey, ConsumerKeySecret, AccessToken, AccessTokenSecret)
    Catch
        ErrorMessage = tweet.ErrorMessage
    End Try

The class itself is as follows (sorry about the formatting - I can never get StackOverflow to paste code properly):

Imports Microsoft.VisualBasic

Imports System Imports System.Collections.Generic Imports System.Linq Imports System.Text Imports System.Net Imports System.IO Imports System.Security.Cryptography Public Class clsTweetVb

'from http//'www.overpie.com/aspnet/articles/csharp-post-message-to-twitter.cshtml then translated into VB by Wise Owl
Public IfWorked As Boolean = False
Public ErrorMessage As String = ""

'the message to send
Public Sub Send(message As String, oauth_consumer_key As String, oauth_consumer_secret As String, oauth_token As String,
         oauth_token_secret As String)

    'The JSON url to update the status
    Dim twitterUrl As String = "http://api.twitter.com/1.1/statuses/update.json"

    'set the oauth version and signature method
    Dim oauth_version As String = "1.0"
    Dim oauth_signature_method As String = "HMAC-SHA1"

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

    '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}&status={6}"

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

    Dim oauth_signature As String = Nothing
    Using hasher As HMACSHA1 = New HMACSHA1(ASCIIEncoding.ASCII.GetBytes(Uri.EscapeDataString(oauth_consumer_secret) & "&" & Uri.EscapeDataString(oauth_token_secret)))
        oauth_signature = Convert.ToBase64String(hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes("POST&" + Uri.EscapeDataString(twitterUrl) + "&" + Uri.EscapeDataString(baseString))))
    End Using

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

    Dim authorizationHeader As String = String.Format(
            authorizationFormat,
            Uri.EscapeDataString(oauth_consumer_key),
            Uri.EscapeDataString(oauth_nonce),
            Uri.EscapeDataString(oauth_signature),
            Uri.EscapeDataString(oauth_signature_method),
            Uri.EscapeDataString(oauth_timestamp),
            Uri.EscapeDataString(oauth_token),
            Uri.EscapeDataString(oauth_version)
        )

    Dim objHttpWebRequest As HttpWebRequest = CType(WebRequest.Create(twitterUrl), HttpWebRequest)
    objHttpWebRequest.Headers.Add("Authorization", authorizationHeader)
    objHttpWebRequest.Method = "POST"
    objHttpWebRequest.ContentType = "application/x-www-form-urlencoded"
    Using objStream As Stream = objHttpWebRequest.GetRequestStream()
        Dim content As Byte() = ASCIIEncoding.ASCII.GetBytes("status=" + Uri.EscapeDataString(message))
        objStream.Write(content, 0, content.Length)
    End Using

    Dim responseResult As String = ""

    ErrorMessage = "No error"
    Try

        'success posting
        Dim objWebResponse As WebResponse = objHttpWebRequest.GetResponse()
        Dim objStreamReader As StreamReader = New StreamReader(objWebResponse.GetResponseStream())
        responseResult = objStreamReader.ReadToEnd().ToString()

        IfWorked = True

    Catch EX As Exception

        'throw exception error
        responseResult = "Twitter Post Error: " + EX.Message.ToString() + ", authHeader: " + authorizationHeader
        ErrorMessage = responseResult
        IfWorked = False
    End Try

End Sub

End Class

When I try to tweet I now get the message The remote server returned an error: (403) Forbidden. My question is: is there something I can do easily to fix this, as I believe the problem is caused by Twitter tightening their security? An ideal solution would explain what I need to do without necessarily understanding too much! Thanks.

Upvotes: 1

Views: 322

Answers (1)

Yosoyke
Yosoyke

Reputation: 485

Maybe an easy solution for you can be using the TweetSharp API. I've been using this for a while now and it's very simple to post tweets, delete tweets, read tweets, get a lot of information about accounts, ...

For example to post a tweet: (I have an Object Called 'Obj_Twitter' which contains the consumer_key pair and Access_token pair)

Function post_Status(obj As Obj_Twitter, mess As String) As String

        Dim service As TwitterService = New TwitterService(obj.consumer_key, obj.consumer_secret)
        service.AuthenticateWith(obj.access_token, obj.access_token_secret)

        Dim options As SendTweetOptions = New SendTweetOptions()
        options.Status = mess

        Dim twreturn As TweetSharp.TwitterStatus = service.SendTweet(options)

        Return twreturn.IdStr
    End Function

(Can be found as Nuget Package in Visual Studio)

Only 'problem' is that this project is no longer actively developed by its creator. But it did the trick for me and maybe it can help you out too.

Upvotes: 1

Related Questions