Search code examples
c#jsontwittertweetinvi

C# - Tweet API v2 - Attach Media to Tweet / Create JsonProperty


for your information Im using the"TweetinviAPI (5.0.4)" nugget package

I found here something related to post a tweet with media, but I dont know how to use it in C#:

https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets

Here is an example --> media.media_ids


At the moment I have an JsonProperty called "text". That works totally fine. Here is my "Poster" Class:

namespace MainData.Twitter_API_v2
{
    public class TweetsV2Poster
    {
        private readonly ITwitterClient client;

        public TweetsV2Poster(ITwitterClient client)
        {
            this.client = client;
        }

        public Task<ITwitterResult> PostTweet(TweetV2PostRequest tweetParams)
        {
            return this.client.Execute.AdvanceRequestAsync(
                (ITwitterRequest request) =>
                {
                    var jsonBody = this.client.Json.Serialize(tweetParams);

                    var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
                    request.Query.Url = "https://api.twitter.com/2/tweets";
                    request.Query.HttpMethod = Tweetinvi.Models.HttpMethod.POST;
                    request.Query.HttpContent = content;
                }
            );
        }
    }

    public class TweetV2PostRequest
    {
        /// <summary>
        /// The text of the tweet to post.
        /// </summary>
        [JsonProperty("text")]
        public string Text { get; set; } = string.Empty;
    }
}

And here I'm calling the "Poster" Class:

//Get the byte[] --> itemshopImg
GetItemshopImage dailyData = new GetItemshopImage();
var itemshopImg = dailyData.GetItemshopImg();

//Create Twitter Client
var client = new TwitterClient(
                "x",
                "x",
                "x",
                "x"
            );

//Upload Tweet Image
var tweetItemshopImg = await client.Upload.UploadTweetImageAsync(itemshopImg);

//Post Tweet
var poster = new TweetsV2Poster(client);
ITwitterResult result = await poster.PostTweet(
    new TweetV2PostRequest
    {
        Text = "myText"
    });

My goal is to use the Id (media.id in the Image at the beginning) from the "tweetItemshopImg" variable and give it the to an JSON Property inside the "TweetsV2Poster" class.


Solution

  • To generate the JSON sample shown in the documentation:

    {
       "text":"Tweeting with media!",
       "media":{
          "media_ids":[
             "1455952740635586573"
          ]
       }
    }   
    

    Modify your TweetV2PostRequest as follows:

    public class TweetV2PostRequest
    {
        /// <summary>
        /// The text of the tweet to post.
        /// </summary>
        [JsonProperty("text")]
        public string Text { get; set; } = string.Empty;
        
        [JsonProperty("media", NullValueHandling = NullValueHandling.Ignore)]
        public TweetV2Media? Media { get; set; }
    }
    
    public class TweetV2Media
    {
        [JsonIgnore]
        public List<long>? MediaIds { get; set; }
        
        [JsonProperty("media_ids", NullValueHandling = NullValueHandling.Ignore)]
        public string []? MediaIdStrings { 
            get => MediaIds?.Select(i => JsonConvert.ToString(i)).ToArray(); 
            set => MediaIds = value?.Select(s =>JsonConvert.DeserializeObject<long>(s)).ToList(); }
    
        // Add others here as required, setting NullValueHandling.Ignore or DefaultValueHandling = DefaultValueHandling.Ignore to suppress unneeded properties
    }
    

    And call poster.PostTweet() as follows:

    //Post Tweet
    // tweetItemshopImg.Id is a Nullable<long>
    var poster = new TweetsV2Poster(client);
    ITwitterResult result = await poster.PostTweet(
        new TweetV2PostRequest
        {
            Text = "Tweeting with media!",
            Media = tweetItemshopImg?.Id == null ? null : new () { MediaIds = new () { tweetItemshopImg.Id.Value } }
        });
    

    Notes:

    • It seems that does not currently have support for posting tweets with associated media using the Twitter V2 API. A search of the source code for BaseTweetsV2Parameters turns up several derived types such as GetTweetsV2Parameters -- but no PostTweetsV2Parameters.

    • To confirm the correct JSON was generated, I modified TweetsV2Poster as follows:

      public Task<ITwitterResult> PostTweet(TweetV2PostRequest tweetParams)
      {
          return this.client.Execute.AdvanceRequestAsync(
              (ITwitterRequest request) =>
              {
                  var jsonBody = this.client.Json.Serialize(tweetParams);
      
                  Debug.WriteLine(JToken.Parse(jsonBody));
      
                  Assert.That(JToken.Parse(jsonBody).ToString() == JToken.Parse(GetRequiredJson()).ToString());
      
                  var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
                  request.Query.Url = "https://api.twitter.com/2/tweets";
                  request.Query.HttpMethod = Tweetinvi.Models.HttpMethod.POST;
                  request.Query.HttpContent = content;
              }
          );
      }
      
      static string GetRequiredJson() => 
          """
          {
             "text":"Tweeting with media!",
             "media":{
                "media_ids":[
                   "1455952740635586573"
                ]
             }
          }   
          """;
      

      There was no assert, indicating the JSON matched the sample (aside from formatting).

    • Tweetinvi does not document the JSON serializer it uses, however its nuget has a dependency on Newtonsoft.Json indicating that is the serializer currently used.