0

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.

dbc
  • 104,963
  • 20
  • 228
  • 340
Pooki
  • 13
  • 3
  • I looked into the source code a bit. They have a dependency on Json.NET but their actual serialization code, [`TweetinviJsonConverter`](https://github.com/linvi/tweetinvi/blob/master/src/Tweetinvi.Core/Core/Json/TweetinviJsonConverter.cs), is so full of factories & dependency injections that it's not clear to me how anything is actually serialized under the hood. – dbc May 21 '23 at 00:29
  • That being said, [`PublishTweetParameters`](https://github.com/linvi/tweetinvi/blob/master/src/Tweetinvi.Core/Public/Parameters/TweetsClient/PublishTweetParameters.cs) has [`List MediaIds { get; set; }`](https://github.com/linvi/tweetinvi/blob/master/src/Tweetinvi.Core/Public/Parameters/TweetsClient/PublishTweetParameters.cs#L59) so could you do something like `await client.Tweets.PublishTweetAsync(new PublishTweetParameters("myText") { MediaIds = tweetItemshopImg.Id == null ? new () : new() { tweetItemshopImg.Id.Value }} );`? – dbc May 21 '23 at 00:49
  • @dbc The problem is, the "PublishTweetAsync" Method is using the v1.1 Twitter API and Ive gotten an error at this method. In the past it worked that way, but I think I cannot use this Method anymore so Im trying to use the v2 Twitter API – Pooki May 21 '23 at 08:41
  • *Reason: Forbidden Details: You currently have access to Twitter API v2 endpoints and limited v1.1 endpoints only. If you need access to this endpoint, you may need a different access level. You can learn more here: https://developer.twitter.com/en/docs/twitter-api/getting-started/about-twitter-api#v2-access-leve","code":453}]} Code: 403 Forbidden - The request is understood, but it has been refused or access is not allowed. An accompanying error message will explain why. This code is used when requests are being denied due to update limits* @dbc this is the error Im getting by this method – Pooki May 21 '23 at 08:45
  • Incidentally [tweetinvi](https://github.com/linvi/tweetinvi) was last updated on Nov 14, 2021. Are you sure it's still being maintained? – dbc May 21 '23 at 16:56
  • Couldn't find a package that worked. Not much harder just to make the right calls directly: https://github.com/GrimRob/TweetSend – Rob Sedgwick Jun 29 '23 at 10:44

1 Answers1

0

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.

dbc
  • 104,963
  • 20
  • 228
  • 340