Skip to content

Commit 834ff6a

Browse files
josiasalexandrejosiasal
authored andcommitted
Add initial support for Twitter V2 Timelines
1 parent 0207234 commit 834ff6a

File tree

15 files changed

+441
-0
lines changed

15 files changed

+441
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using Tweetinvi.Core.Iterators;
4+
using Tweetinvi.Core.Controllers.V2;
5+
using Tweetinvi.Core.Web;
6+
using Tweetinvi.Models;
7+
using Tweetinvi.Models.V2;
8+
using Tweetinvi.Parameters.V2;
9+
10+
namespace Tweetinvi.Controllers.Timeline
11+
{
12+
public class TimelinesV2Controller : ITimelinesV2Controller
13+
{
14+
private readonly ITimelinesV2QueryExecutor _queryExecutor;
15+
16+
public TimelinesV2Controller(ITimelinesV2QueryExecutor queryExecutor)
17+
{
18+
_queryExecutor = queryExecutor;
19+
}
20+
21+
private ITwitterPageIterator<ITwitterResult<TimelinesV2Response>, string> GetIterator(
22+
Func<IGetTimelinesV2Parameters, ITwitterRequest, Task<ITwitterResult<TimelinesV2Response>>> Method,
23+
IGetTimelinesV2Parameters parameters,
24+
ITwitterRequest request)
25+
{
26+
Func<string, Task<ITwitterResult<TimelinesV2Response>>> getNext = nextToken =>
27+
{
28+
var cursoredParameters = new GetTimelinesV2Parameters(parameters)
29+
{
30+
PaginationToken = nextToken
31+
};
32+
33+
return Method(cursoredParameters, request);
34+
};
35+
36+
var twitterCursorResult = new TwitterPageIterator<ITwitterResult<TimelinesV2Response>, string>(
37+
parameters.PaginationToken,
38+
getNext,
39+
page =>
40+
{
41+
if (page.Model.Tweets.Length == 0)
42+
{
43+
return null;
44+
}
45+
46+
return page.Model.Meta.NextToken;
47+
},
48+
page =>
49+
{
50+
if (page.Model.Tweets.Length == 0)
51+
{
52+
return true;
53+
}
54+
55+
return page.Model.Meta.NextToken == null;
56+
});
57+
58+
return twitterCursorResult;
59+
}
60+
61+
public ITwitterPageIterator<ITwitterResult<TimelinesV2Response>, string> GetUserTweetsTimelineIterator(IGetTimelinesV2Parameters parameters, ITwitterRequest request)
62+
{
63+
return GetIterator(_queryExecutor.GetUserTweetsTimelineAsync, parameters, request);
64+
}
65+
66+
public ITwitterPageIterator<ITwitterResult<TimelinesV2Response>, string> GetUserMentionedTimelineIterator(IGetTimelinesV2Parameters parameters, ITwitterRequest request)
67+
{
68+
return GetIterator(_queryExecutor.GetUserMentionedTimelineAsync, parameters, request);
69+
}
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System.Threading.Tasks;
2+
using Tweetinvi.Core.QueryGenerators.V2;
3+
using Tweetinvi.Core.Web;
4+
using Tweetinvi.Models;
5+
using Tweetinvi.Models.V2;
6+
using Tweetinvi.Parameters.V2;
7+
8+
namespace Tweetinvi.Controllers.Timeline
9+
{
10+
public interface ITimelinesV2QueryExecutor
11+
{
12+
Task<ITwitterResult<TimelinesV2Response>> GetUserTweetsTimelineAsync(IGetTimelinesV2Parameters parameters, ITwitterRequest request);
13+
Task<ITwitterResult<TimelinesV2Response>> GetUserMentionedTimelineAsync(IGetTimelinesV2Parameters parameters, ITwitterRequest request);
14+
}
15+
16+
public class TimelinesV2QueryExecutor : ITimelinesV2QueryExecutor
17+
{
18+
private readonly JsonContentFactory _jsonContentFactory;
19+
private readonly ITimelinesV2QueryGenerator _timelinesQueryGenerator;
20+
private readonly ITwitterAccessor _twitterAccessor;
21+
22+
public TimelinesV2QueryExecutor(
23+
JsonContentFactory jsonContentFactory,
24+
ITimelinesV2QueryGenerator timelinesQueryGenerator,
25+
ITwitterAccessor twitterAccessor)
26+
{
27+
_jsonContentFactory = jsonContentFactory;
28+
_timelinesQueryGenerator = timelinesQueryGenerator;
29+
_twitterAccessor = twitterAccessor;
30+
}
31+
32+
public Task<ITwitterResult<TimelinesV2Response>> GetUserTweetsTimelineAsync(IGetTimelinesV2Parameters parameters, ITwitterRequest request)
33+
{
34+
request.Query.Url = _timelinesQueryGenerator.GetTimelineQuery(parameters);
35+
request.Query.HttpMethod = HttpMethod.GET;
36+
return _twitterAccessor.ExecuteRequestAsync<TimelinesV2Response>(request);
37+
}
38+
public Task<ITwitterResult<TimelinesV2Response>> GetUserMentionedTimelineAsync(IGetTimelinesV2Parameters parameters, ITwitterRequest request)
39+
{
40+
request.Query.Url = _timelinesQueryGenerator.GetMentionTimelineQuery(parameters);
41+
return _twitterAccessor.ExecuteRequestAsync<TimelinesV2Response>(request);
42+
}
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System.Text;
2+
using Tweetinvi.Controllers.Properties;
3+
using Tweetinvi.Core.Extensions;
4+
using Tweetinvi.Core.QueryGenerators.V2;
5+
using Tweetinvi.Parameters.V2;
6+
7+
namespace Tweetinvi.Controllers.Timeline
8+
{
9+
public class TimelinesV2QueryGenerator : ITimelinesV2QueryGenerator
10+
{
11+
public string GetTimelineQuery(IGetTimelinesV2Parameters parameters)
12+
{
13+
var query = new StringBuilder($"{Resources.UserV2_Get}/{parameters.UserId}/tweets");
14+
AddTimelineFieldsParameters(parameters, query);
15+
query.AddFormattedParameterToQuery(parameters.FormattedCustomQueryParameters);
16+
return query.ToString();
17+
}
18+
19+
public string GetMentionTimelineQuery(IGetTimelinesV2Parameters parameters)
20+
{
21+
var query = new StringBuilder($"{Resources.UserV2_Get}/{parameters.UserId}/mentions");
22+
AddTimelineFieldsParameters(parameters, query);
23+
query.AddFormattedParameterToQuery(parameters.FormattedCustomQueryParameters);
24+
return query.ToString();
25+
}
26+
27+
public void AddTimelineFieldsParameters(IGetTimelinesV2Parameters parameters, StringBuilder query)
28+
{
29+
// IBaseTweetsV2Parameters
30+
query.AddParameterToQuery("expansions", parameters.Expansions);
31+
query.AddParameterToQuery("media.fields", parameters.MediaFields);
32+
query.AddParameterToQuery("place.fields", parameters.PlaceFields);
33+
query.AddParameterToQuery("poll.fields", parameters.PollFields);
34+
query.AddParameterToQuery("tweet.fields", parameters.TweetFields);
35+
query.AddParameterToQuery("user.fields", parameters.UserFields);
36+
37+
query.AddParameterToQuery("exclude", parameters.Exclude);
38+
query.AddParameterToQuery("max_results", parameters.MaxResults);
39+
query.AddParameterToQuery("pagination_token", parameters.PaginationToken);
40+
query.AddParameterToQuery("since_id", parameters.SinceId);
41+
query.AddParameterToQuery("start_time", parameters.StartTime?.ToString("yyy-MM-ddThh:mm:ssZ"));
42+
query.AddParameterToQuery("end_time", parameters.EndTime?.ToString("yyy-MM-ddThh:mm:ssZ"));
43+
query.AddParameterToQuery("until_id", parameters.UntilId);
44+
}
45+
}
46+
}

src/Tweetinvi.Controllers/TweetinviControllersModule.cs

+3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ private void InitializeControllers(ITweetinviContainer container)
5252
container.RegisterType<ISearchV2Controller, SearchV2Controller>(RegistrationLifetime.InstancePerApplication);
5353
container.RegisterType<ITweetsV2Controller, TweetsV2Controller>(RegistrationLifetime.InstancePerApplication);
5454
container.RegisterType<IUsersV2Controller, UsersV2Controller>(RegistrationLifetime.InstancePerApplication);
55+
container.RegisterType<ITimelinesV2Controller, TimelinesV2Controller>(RegistrationLifetime.InstancePerApplication);
5556

5657
container.RegisterType<IStreamsV2Controller, StreamsV2Controller>(RegistrationLifetime.InstancePerApplication);
5758
}
@@ -77,6 +78,7 @@ private void InitializeQueryExecutors(ITweetinviContainer container)
7778
container.RegisterType<ISearchV2QueryExecutor, SearchV2QueryExecutor>();
7879
container.RegisterType<ITweetsV2QueryExecutor, TweetsV2QueryExecutor>();
7980
container.RegisterType<IUsersV2QueryExecutor, UsersV2QueryExecutor>();
81+
container.RegisterType<ITimelinesV2QueryExecutor, TimelinesV2QueryExecutor>();
8082

8183
container.RegisterType<IStreamsV2QueryExecutor, StreamsV2QueryExecutor>(RegistrationLifetime.InstancePerApplication);
8284
}
@@ -107,6 +109,7 @@ private void InitializeQueryGenerators(ITweetinviContainer container)
107109
container.RegisterType<ISearchV2QueryGenerator, SearchV2QueryGenerator>(RegistrationLifetime.InstancePerApplication);
108110
container.RegisterType<ITweetsV2QueryGenerator, TweetsV2QueryGenerator>(RegistrationLifetime.InstancePerApplication);
109111
container.RegisterType<IUsersV2QueryGenerator, UsersV2QueryGenerator>(RegistrationLifetime.InstancePerApplication);
112+
container.RegisterType<ITimelinesV2QueryGenerator, TimelinesV2QueryGenerator>(RegistrationLifetime.InstancePerApplication);
110113

111114
container.RegisterType<IStreamsV2QueryGenerator, StreamsV2QueryGenerator>(RegistrationLifetime.InstancePerApplication);
112115
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Tweetinvi.Core.Iterators;
2+
using Tweetinvi.Core.Web;
3+
using Tweetinvi.Models;
4+
using Tweetinvi.Models.V2;
5+
using Tweetinvi.Parameters.V2;
6+
7+
namespace Tweetinvi.Core.Controllers.V2
8+
{
9+
public interface ITimelinesV2Controller
10+
{
11+
ITwitterPageIterator<ITwitterResult<TimelinesV2Response>, string> GetUserTweetsTimelineIterator(IGetTimelinesV2Parameters parameters, ITwitterRequest request);
12+
ITwitterPageIterator<ITwitterResult<TimelinesV2Response>, string> GetUserMentionedTimelineIterator(IGetTimelinesV2Parameters parameters, ITwitterRequest request);
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.Text;
2+
using Tweetinvi.Parameters.V2;
3+
4+
namespace Tweetinvi.Core.QueryGenerators.V2
5+
{
6+
public interface ITimelinesV2QueryGenerator
7+
{
8+
string GetTimelineQuery(IGetTimelinesV2Parameters parameters);
9+
string GetMentionTimelineQuery(IGetTimelinesV2Parameters parameters);
10+
void AddTimelineFieldsParameters(IGetTimelinesV2Parameters parameters, StringBuilder query);
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Tweetinvi.Iterators;
2+
using Tweetinvi.Models.V2;
3+
using Tweetinvi.Parameters.V2;
4+
5+
namespace Tweetinvi.Client.V2
6+
{
7+
public interface ITimelinesV2Client
8+
{
9+
/// <summary>
10+
/// Returns Tweets composed by a single user, specified by the requested user ID. By default,
11+
/// the most recent ten Tweets are returned per request. Using pagination, the most recent
12+
/// 3,200 Tweets can be retrieved.
13+
/// <para>Read more : https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-tweets </para>
14+
/// </summary>
15+
/// <returns>The Timeline</returns>
16+
ITwitterRequestIterator<TimelinesV2Response, string> GetUserTweetsTimelineIterator(IGetTimelinesV2Parameters parameters);
17+
18+
/// <summary>
19+
/// Returns Tweets mentioning a single user specified by the requested user ID. By default,
20+
/// the most recent ten Tweets are returned per request. Using pagination, up to the most
21+
/// recent 800 Tweets can be retrieved.
22+
/// <para>Read more : https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-mentions </para>
23+
/// </summary>
24+
ITwitterRequestIterator<TimelinesV2Response, string> GetUserMentionedTimelineIterator(IGetTimelinesV2Parameters parameters);
25+
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Tweetinvi.Core.Iterators;
2+
using Tweetinvi.Core.Web;
3+
using Tweetinvi.Models.V2;
4+
using Tweetinvi.Parameters.V2;
5+
6+
namespace Tweetinvi.Client.Requesters.V2
7+
{
8+
public interface ITimelinesV2Requester
9+
{
10+
/// <summary>
11+
/// Returns Tweets composed by a single user, specified by the requested user ID. By default,
12+
/// the most recent ten Tweets are returned per request. Using pagination, the most recent
13+
/// 3,200 Tweets can be retrieved.
14+
/// <para>Read more : https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-tweets </para>
15+
/// </summary>
16+
/// <returns>The Timeline</returns>
17+
ITwitterPageIterator<ITwitterResult<TimelinesV2Response>, string> GetUserTweetsTimelineIterator(IGetTimelinesV2Parameters parameters);
18+
19+
/// <summary>
20+
/// Returns Tweets mentioning a single user specified by the requested user ID. By default,
21+
/// the most recent ten Tweets are returned per request. Using pagination, up to the most
22+
/// recent 800 Tweets can be retrieved.
23+
/// <para>Read more : https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-mentions </para>
24+
/// </summary>
25+
ITwitterPageIterator<ITwitterResult<TimelinesV2Response>, string> GetUserMentionedTimelineIterator(IGetTimelinesV2Parameters parameters);
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Tweetinvi.Models.V2
4+
{
5+
public class TimelinesV2Response
6+
{
7+
/// <summary>
8+
/// Tweets returned by the request
9+
/// </summary>
10+
[JsonProperty("data")] public TweetV2[] Tweets { get; set; } = new TweetV2[0];
11+
12+
/// <summary>
13+
/// Contains all the requested expansions
14+
/// </summary>
15+
[JsonProperty("includes")] public TweetIncludesV2 Includes { get; set; }
16+
17+
/// <summary>
18+
/// All errors that prevented Twitter to send some data,
19+
/// but which did not prevent the request to be resolved.
20+
/// </summary>
21+
[JsonProperty("errors")] public ErrorV2[] Errors { get; set; }
22+
23+
/// <summary>
24+
/// This object contains information about the number of users
25+
/// returned in the current request and pagination details.
26+
/// </summary>
27+
[JsonProperty("meta")] public TweetMetaV2 Meta { get; set; }
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System;
2+
using Newtonsoft.Json;
3+
4+
namespace Tweetinvi.Models.V2
5+
{
6+
/// <summary>
7+
/// A Tweet
8+
/// <para>Read more here : https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-tweets</para>
9+
/// </summary>
10+
public class TweetMetaV2
11+
{
12+
/// <summary>
13+
/// The Tweet ID of the oldest Tweet returned in the response.
14+
/// </summary>
15+
[JsonProperty("oldest_id")] public string OldestId { get; set; }
16+
17+
/// <summary>
18+
/// The Tweet ID of the most recent Tweet returned in the response.
19+
/// </summary>
20+
[JsonProperty("newest_id")] public string NewestId { get; set; }
21+
22+
/// <summary>
23+
/// The number of Tweet results returned in the response.
24+
/// </summary>
25+
[JsonProperty("count")] public int Count { get; set; }
26+
27+
/// <summary>
28+
/// A value that encodes the next 'page' of results that can be requested,
29+
/// via the pagination_token request parameter.
30+
/// </summary>
31+
[JsonProperty("next_token")] public string NextToken { get; set; }
32+
33+
/// <summary>
34+
/// A value that encodes the previous 'page' of results that can be requested,
35+
/// via the pagination_token request parameter.
36+
/// </summary>
37+
[JsonProperty("previous_token")] public string PreviousToken { get; set; }
38+
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using System;
2+
using Tweetinvi.Core.Parameters;
3+
4+
namespace Tweetinvi.Parameters.V2
5+
{
6+
public interface IGetTimelinesV2Parameters : IBaseTweetsV2Parameters
7+
{
8+
string UserId { get; set; }
9+
string Exclude { get; set; }
10+
int? MaxResults { get; set; }
11+
string PaginationToken { get; set; }
12+
string SinceId { get; set; }
13+
DateTime? StartTime { get; set; }
14+
DateTime? EndTime { get; set; }
15+
string UntilId { get; set; }
16+
}
17+
18+
public class GetTimelinesV2Parameters : BaseTweetsV2Parameters, IGetTimelinesV2Parameters
19+
{
20+
public GetTimelinesV2Parameters(string userId)
21+
{
22+
UserId = userId;
23+
}
24+
public GetTimelinesV2Parameters(IGetTimelinesV2Parameters parameters)
25+
{
26+
UserId = parameters.UserId;
27+
Exclude = parameters?.Exclude;
28+
MaxResults = parameters?.MaxResults;
29+
PaginationToken = parameters?.PaginationToken;
30+
SinceId = parameters?.SinceId;
31+
StartTime = parameters?.StartTime;
32+
EndTime = parameters?.EndTime;
33+
UntilId = parameters?.UntilId;
34+
35+
Expansions = parameters.Expansions;
36+
MediaFields = parameters.MediaFields;
37+
PlaceFields = parameters.PlaceFields;
38+
PollFields = parameters.PollFields;
39+
TweetFields = parameters.TweetFields;
40+
UserFields = parameters.UserFields;
41+
42+
}
43+
44+
public string UserId { get; set; }
45+
public string Exclude { get; set; }
46+
public int? MaxResults { get; set; }
47+
public string PaginationToken { get; set; }
48+
public string SinceId { get; set; }
49+
public DateTime? StartTime { get; set; }
50+
public DateTime? EndTime { get; set; }
51+
public string UntilId { get; set; }
52+
}
53+
}

0 commit comments

Comments
 (0)