2015-03-24 2 views
1

Я пытаюсь отправить несколько изображений в твиттер, используя медиа/загрузку, чтобы я мог чирикать с помощью нескольких изображений. Но не могу этого сделать ... Я получаю несанкционированную ошибку 401. Я не могу использовать стороннюю библиотеку.Загрузка мультимедиа в твиттер без сторонней библиотеки

var oauth_token = "***"; //"insert here..."; 
      var oauth_token_secret = "***"; //"insert here..."; 
      var oauth_consumer_key = "***";// = "insert here..."; 
      var oauth_consumer_secret = "***";// = "insert here..."; 

      // 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(); 


      var resource_url = "https://upload.twitter.com/1.1/media/upload.json"; 

      // 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}"; 

      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("POST&", 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; 

      byte[] bytes = File.ReadAllBytes(@"C:\Users\Public\Pictures\Sample Pictures\desert.jpg"); 
      var postBody = "media=" + Convert.ToBase64String(bytes); 
      resource_url += "?" + postBody; 
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resource_url); 
      request.Headers.Add("Authorization", authHeader); 
      request.Method = "POST"; 
      request.ContentType = "application/x-www-form-urlencoded"; 

      WebResponse response = request.GetResponse(); 
      string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd(); 
      response.Close(); 
      // return responseData; 


     } 
     catch (Exception ed) 
     { 
     } 

Было бы здорово, если бы кто-то мог мне помочь в этом.

ответ

5

Решил проблему с помощью класса tinytwitter Juan María Эрнандеса с изменениями, которые мне нужны

using System; 
using System.Collections.Generic; 
using System.Globalization; 
using System.IO; 
using System.Linq; 
using System.Net; 
using System.Security.Cryptography; 
using System.Text; 
using System.Text.RegularExpressions; 
using System.Web.Script.Serialization; 

namespace tweetmedia.Models 
{ 
public class OAuthInfo 
{ 
    public string ConsumerKey { get; set; } 
    public string ConsumerSecret { get; set; } 
    public string AccessToken { get; set; } 
    public string AccessSecret { get; set; } 
} 

public class Tweet 
{ 
    public long Id { get; set; } 
    public DateTime CreatedAt { get; set; } 
    public string UserName { get; set; } 
    public string ScreenName { get; set; } 
    public string Text { get; set; } 
} 

public class TinyTwitter 
{ 
    private readonly OAuthInfo oauth; 

    public TinyTwitter(OAuthInfo oauth) 
    { 
     this.oauth = oauth; 
    } 

    public string UpdateStatus(string message) 
    { 
     string web = new RequestBuilder(oauth, "POST", "https://api.twitter.com/1.1/statuses/update.json") 
      .AddParameter("status", message) 
      .Execute(); 
     return web; 
    } 
    public string UpdateStatuswithmedia(string message, string media) 
    { 
     string web = new RequestBuilder(oauth, "POST", "https://api.twitter.com/1.1/statuses/update.json") 
      .AddParameter("status", message) 
      .AddParameter("media_ids", media) 
      .Execute(); 
     return web; 
    } 
    public string UpdateMedia(string message) 
    { 
     string web = new RequestBuilder(oauth, "POST", "https://upload.twitter.com/1.1/media/upload.json") 
      .AddParameter("media", message) 
      .Execute(); 
     return web; 
    } 

    public IEnumerable<Tweet> GetHomeTimeline(long? sinceId = null, int? count = 20) 
    { 
     return GetTimeline("https://api.twitter.com/1.1/statuses/home_timeline.json", sinceId, count); 
    } 

    public IEnumerable<Tweet> GetMentions(long? sinceId = null, int? count = 20) 
    { 
     return GetTimeline("https://api.twitter.com/1.1/statuses/mentions.json", sinceId, count); 
    } 

    public IEnumerable<Tweet> GetUserTimeline(long? sinceId = null, int? count = 20) 
    { 
     return GetTimeline("https://api.twitter.com/1.1/statuses/user_timeline.json", sinceId, count); 
    } 

    private IEnumerable<Tweet> GetTimeline(string url, long? sinceId, int? count) 
    { 
     var builder = new RequestBuilder(oauth, "GET", url); 

     if (sinceId.HasValue) 
      builder.AddParameter("since_id", sinceId.Value.ToString()); 

     if (count.HasValue) 
      builder.AddParameter("count", count.Value.ToString()); 

     string content; 
     var response = builder.Execute(out content); 

     var serializer = new JavaScriptSerializer(); 

     var tweets = (object[])serializer.DeserializeObject(content); 

     return tweets.Cast<Dictionary<string, object>>().Select(tweet => 
     { 
      var user = ((Dictionary<string, object>)tweet["user"]); 
      var date = DateTime.ParseExact(tweet["created_at"].ToString(), 
       "ddd MMM dd HH:mm:ss zz00 yyyy", 
       CultureInfo.InvariantCulture).ToLocalTime(); 
      return new Tweet 
      { 
       Id = (long)tweet["id"], 
       CreatedAt = 
        date, 
       Text = (string)tweet["text"], 
       UserName = (string)user["name"], 
       ScreenName = (string)user["screen_name"] 
      }; 
     }).ToArray(); 
    } 

    #region RequestBuilder 

    public class RequestBuilder 
    { 
     private const string VERSION = "1.0"; 
     private const string SIGNATURE_METHOD = "HMAC-SHA1"; 

     private readonly OAuthInfo oauth; 
     private readonly string method; 
     private readonly IDictionary<string, string> customParameters; 
     private readonly string url; 

     public RequestBuilder(OAuthInfo oauth, string method, string url) 
     { 
      this.oauth = oauth; 
      this.method = method; 
      this.url = url; 
      customParameters = new Dictionary<string, string>(); 
     } 

     public RequestBuilder AddParameter(string name, string value) 
     { 
      customParameters.Add(name, value.EscapeUriDataStringRfc3986()); 
      return this; 
     } 

     public string Execute() 
     { 
      string content; 
      Execute(out content); 
      return content; 
     } 

     public WebResponse Execute(out string content) 
     { 
      try 
      { 
       var timespan = GetTimestamp(); 
       var nonce = CreateNonce(); 

       var parameters = new Dictionary<string, string>(customParameters); 
       AddOAuthParameters(parameters, timespan, nonce); 

       var signature = GenerateSignature(parameters); 
       var headerValue = GenerateAuthorizationHeaderValue(parameters, signature); 

       var request = (HttpWebRequest)WebRequest.Create(GetRequestUrl()); 
       request.Method = method; 
       request.ContentType = "application/x-www-form-urlencoded"; 

       request.Headers.Add("Authorization", headerValue); 

       WriteRequestBody(request); 

       // It looks like a bug in HttpWebRequest. It throws random TimeoutExceptions 
       // after some requests. Abort the request seems to work. More info: 
       // http://stackoverflow.com/questions/2252762/getrequeststream-throws-timeout-exception-randomly 

       var response = request.GetResponse(); 

       using (var stream = response.GetResponseStream()) 
       { 
        using (var reader = new StreamReader(stream)) 
        { 
         content = reader.ReadToEnd(); 
        } 
       } 

       request.Abort(); 

       return response; 
      } 
      catch (Exception ex) 
      { 
       content = ""; 
       return null; 
      } 
     } 

     private void WriteRequestBody(HttpWebRequest request) 
     { 
      if (method == "GET") 
       return; 

      var requestBody = Encoding.ASCII.GetBytes(GetCustomParametersString()); 
      using (var stream = request.GetRequestStream()) 
       stream.Write(requestBody, 0, requestBody.Length); 
     } 

     private string GetRequestUrl() 
     { 
      if (method != "GET" || customParameters.Count == 0) 
       return url; 

      return string.Format("{0}?{1}", url, GetCustomParametersString()); 
     } 

     private string GetCustomParametersString() 
     { 
      return customParameters.Select(x => string.Format("{0}={1}", x.Key, x.Value)).Join("&"); 
     } 

     private string GenerateAuthorizationHeaderValue(IEnumerable<KeyValuePair<string, string>> parameters, string signature) 
     { 
      return new StringBuilder("OAuth ") 
       .Append(parameters.Concat(new KeyValuePair<string, string>("oauth_signature", signature)) 
          .Where(x => x.Key.StartsWith("oauth_")) 
          .Select(x => string.Format("{0}=\"{1}\"", x.Key, x.Value.EscapeUriDataStringRfc3986())) 
          .Join(",")) 
       .ToString(); 
     } 

     private string GenerateSignature(IEnumerable<KeyValuePair<string, string>> parameters) 
     { 
      var dataToSign = new StringBuilder() 
       .Append(method).Append("&") 
       .Append(url.EscapeUriDataStringRfc3986()).Append("&") 
       .Append(parameters 
          .OrderBy(x => x.Key) 
          .Select(x => string.Format("{0}={1}", x.Key, x.Value)) 
          .Join("&") 
          .EscapeUriDataStringRfc3986()); 

      var signatureKey = string.Format("{0}&{1}", oauth.ConsumerSecret.EscapeUriDataStringRfc3986(), oauth.AccessSecret.EscapeUriDataStringRfc3986()); 
      var sha1 = new HMACSHA1(Encoding.ASCII.GetBytes(signatureKey)); 

      var signatureBytes = sha1.ComputeHash(Encoding.ASCII.GetBytes(dataToSign.ToString())); 
      return Convert.ToBase64String(signatureBytes); 
     } 

     private void AddOAuthParameters(IDictionary<string, string> parameters, string timestamp, string nonce) 
     { 
      parameters.Add("oauth_version", VERSION); 
      parameters.Add("oauth_consumer_key", oauth.ConsumerKey); 
      parameters.Add("oauth_nonce", nonce); 
      parameters.Add("oauth_signature_method", SIGNATURE_METHOD); 
      parameters.Add("oauth_timestamp", timestamp); 
      parameters.Add("oauth_token", oauth.AccessToken); 
     } 

     private static string GetTimestamp() 
     { 
      return ((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds).ToString(); 
     } 

     private static string CreateNonce() 
     { 
      return new Random().Next(0x0000000, 0x7fffffff).ToString("X8"); 
     } 
    } 

    #endregion 
} 

public static class TinyTwitterHelperExtensions 
{ 
    public static string Join<T>(this IEnumerable<T> items, string separator) 
    { 
     return string.Join(separator, items.ToArray()); 
    } 

    public static IEnumerable<T> Concat<T>(this IEnumerable<T> items, T value) 
    { 
     return items.Concat(new[] { value }); 
    } 

    public static string EncodeRFC3986(this string value) 
    { 
     // From Twitterizer http://www.twitterizer.net/ 

     if (string.IsNullOrEmpty(value)) 
      return string.Empty; 

     var encoded = Uri.EscapeDataString(value); 

     return Regex 
      .Replace(encoded, "(%[0-9a-f][0-9a-f])", c => c.Value.ToUpper()) 
      .Replace("(", "%28") 
      .Replace(")", "%29") 
      .Replace("$", "%24") 
      .Replace("!", "%21") 
      .Replace("*", "%2A") 
      .Replace("'", "%27") 
      .Replace("%7E", "~"); 
    } 

    public static string EscapeUriDataStringRfc3986(this string value) 
    { 
     StringBuilder escaped = new StringBuilder(); 

     string validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~"; 

     foreach (char c in value) 
     { 
      if (validChars.Contains(c.ToString())) 
      { 
       escaped.Append(c); 
      } 
      else 
      { 
       escaped.Append("%" + Convert.ToByte(c).ToString("x2").ToUpper()); 
      } 
     } 

     // Return the fully-RFC3986-escaped string. 
     return escaped.ToString(); 
    } 
} 
} 

Я использую этот метод, чтобы загрузить изображение с поста

public string PostToTwitter(string PostData, string SelectedMedia) 
    { 
     string tweetresp = ""; 
     DataSet ds = new DataSet(); 
     try 
     { 


      var oauth = new OAuthInfo 
      { 
       AccessToken = Convert.ToString(Session["twitter_token"]), 
       AccessSecret = Convert.ToString(Session["twitter_token_secret"]), 
       ConsumerKey = Convert.ToString(ConfigurationSettings.AppSettings["TwitterConsumerKey"]) , 
       ConsumerSecret =Convert.ToString(ConfigurationSettings.AppSettings["TwitterConsumerSecret"]) 
      }; 

      var twitter = new TinyTwitter(oauth); 
      List<string> li = new List<string>(); 
      string[] files = SelectedMedia.Split(','); 
      List<string> FileList = new List<string>(); 
      string media = ""; 

      if (!string.IsNullOrEmpty(SelectedMedia)) 
      { 
       foreach (string file in files) 
        FileList.Add(Server.MapPath(file)); 


       foreach (string item in FileList) 
       { 
        li.Add(GetMediaId(twitter, item)); 
       } 
       media = string.Join(",", li); 
      } 
      //li.Add(GetMediaId(twitter, file1)); 
      if (!string.IsNullOrEmpty(SelectedMedia)) 
      { 
       tweetresp = twitter.UpdateStatuswithmedia(PostData, media); 
      } 
      else 
      tweetresp = twitter.UpdateStatus(PostData); 
     } 
     catch (Exception ex) 
     { 
     } 
     return tweetresp; 
    } 

Вот метод GetMediaId

 public string GetMediaId(TinyTwitter twit, string file) 
    { 
     byte[] files = System.IO.File.ReadAllBytes(file); 
     string Base64File = Convert.ToBase64String(files); 
     string response = twit.UpdateMedia(Base64File); 
     JObject j = JObject.Parse(response); 
     return Convert.ToString(j["media_id"]); 
    } 
+1

Можете ли вы привести пример того, как вы могли бы разместить обновление статуса с изображением, используя это, пожалуйста? Это не очевидно из вашего кода. Благодарю. – Dave

+0

Привет, Дейв, я обновил свой ответ. Вы можете использовать метод PostToTwitter для публикации обновления состояния с изображением или несколькими изображениями. – xoanon

+0

Привет, спасибо за ваш ответ, но это даже не похоже, что это сработает, например, где есть: - метод: 'GetMediaId'? - сборка Общая информация - класс Influencer etc etc ?? – Dave

0

Ошибка 401 обычно означает, что ваш токен недействителен или ваш ключ и секрет недействительны. Также возможно, что он не достигнет Twitter. Я в спешке, чтобы запустить свой код, но я хотел бы, чтобы убедиться, что следующие две вещи:

  1. Можете ли вы сделать то же самое с Twitter.com без ошибок?

  2. Можете ли вы сделать сообщение без средств массовой информации, используя эти жетоны?

+0

Actua lly no Я тоже не могу сделать сообщение с этим – xoanon

+0

Кажется, ваши токены недействительны. Перейдите в свое приложение и получите новый набор учетных данных. Определите проблемы один за другим и исправьте их по порядку. – dinwal

Смежные вопросы