-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add initial support for Twitter V2 Timelines #1144
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using Tweetinvi.Core.Iterators; | ||
using Tweetinvi.Core.Controllers.V2; | ||
using Tweetinvi.Core.Web; | ||
using Tweetinvi.Models; | ||
using Tweetinvi.Models.V2; | ||
using Tweetinvi.Parameters.V2; | ||
|
||
namespace Tweetinvi.Controllers.Timeline | ||
{ | ||
public class TimelinesV2Controller : ITimelinesV2Controller | ||
{ | ||
private readonly ITimelinesV2QueryExecutor _queryExecutor; | ||
|
||
public TimelinesV2Controller(ITimelinesV2QueryExecutor queryExecutor) | ||
{ | ||
_queryExecutor = queryExecutor; | ||
} | ||
|
||
private ITwitterPageIterator<ITwitterResult<TimelinesV2Response>, string> GetIterator( | ||
Func<IGetTimelinesV2Parameters, ITwitterRequest, Task<ITwitterResult<TimelinesV2Response>>> Method, | ||
IGetTimelinesV2Parameters parameters, | ||
ITwitterRequest request) | ||
{ | ||
Func<string, Task<ITwitterResult<TimelinesV2Response>>> getNext = nextToken => | ||
{ | ||
var cursoredParameters = new GetTimelinesV2Parameters(parameters) | ||
{ | ||
PaginationToken = nextToken | ||
}; | ||
|
||
return Method(cursoredParameters, request); | ||
}; | ||
|
||
var twitterCursorResult = new TwitterPageIterator<ITwitterResult<TimelinesV2Response>, string>( | ||
parameters.PaginationToken, | ||
getNext, | ||
page => | ||
{ | ||
if (page.Model.Tweets.Length == 0) | ||
{ | ||
return null; | ||
} | ||
|
||
return page.Model.Meta.NextToken; | ||
}, | ||
page => | ||
{ | ||
if (page.Model.Tweets.Length == 0) | ||
{ | ||
return true; | ||
} | ||
|
||
return page.Model.Meta.NextToken == null; | ||
}); | ||
|
||
return twitterCursorResult; | ||
} | ||
|
||
public ITwitterPageIterator<ITwitterResult<TimelinesV2Response>, string> GetUserTweetsTimelineIterator(IGetTimelinesV2Parameters parameters, ITwitterRequest request) | ||
{ | ||
return GetIterator(_queryExecutor.GetUserTweetsTimelineAsync, parameters, request); | ||
} | ||
|
||
public ITwitterPageIterator<ITwitterResult<TimelinesV2Response>, string> GetUserMentionedTimelineIterator(IGetTimelinesV2Parameters parameters, ITwitterRequest request) | ||
{ | ||
return GetIterator(_queryExecutor.GetUserMentionedTimelineAsync, parameters, request); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using System.Threading.Tasks; | ||
using Tweetinvi.Core.QueryGenerators.V2; | ||
using Tweetinvi.Core.Web; | ||
using Tweetinvi.Models; | ||
using Tweetinvi.Models.V2; | ||
using Tweetinvi.Parameters.V2; | ||
|
||
namespace Tweetinvi.Controllers.Timeline | ||
{ | ||
public interface ITimelinesV2QueryExecutor | ||
{ | ||
Task<ITwitterResult<TimelinesV2Response>> GetUserTweetsTimelineAsync(IGetTimelinesV2Parameters parameters, ITwitterRequest request); | ||
Task<ITwitterResult<TimelinesV2Response>> GetUserMentionedTimelineAsync(IGetTimelinesV2Parameters parameters, ITwitterRequest request); | ||
} | ||
|
||
public class TimelinesV2QueryExecutor : ITimelinesV2QueryExecutor | ||
{ | ||
private readonly JsonContentFactory _jsonContentFactory; | ||
private readonly ITimelinesV2QueryGenerator _timelinesQueryGenerator; | ||
private readonly ITwitterAccessor _twitterAccessor; | ||
|
||
public TimelinesV2QueryExecutor( | ||
JsonContentFactory jsonContentFactory, | ||
ITimelinesV2QueryGenerator timelinesQueryGenerator, | ||
ITwitterAccessor twitterAccessor) | ||
{ | ||
_jsonContentFactory = jsonContentFactory; | ||
_timelinesQueryGenerator = timelinesQueryGenerator; | ||
_twitterAccessor = twitterAccessor; | ||
} | ||
|
||
public Task<ITwitterResult<TimelinesV2Response>> GetUserTweetsTimelineAsync(IGetTimelinesV2Parameters parameters, ITwitterRequest request) | ||
{ | ||
request.Query.Url = _timelinesQueryGenerator.GetTimelineQuery(parameters); | ||
request.Query.HttpMethod = HttpMethod.GET; | ||
return _twitterAccessor.ExecuteRequestAsync<TimelinesV2Response>(request); | ||
} | ||
public Task<ITwitterResult<TimelinesV2Response>> GetUserMentionedTimelineAsync(IGetTimelinesV2Parameters parameters, ITwitterRequest request) | ||
{ | ||
request.Query.Url = _timelinesQueryGenerator.GetMentionTimelineQuery(parameters); | ||
return _twitterAccessor.ExecuteRequestAsync<TimelinesV2Response>(request); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
using System.Text; | ||
using Tweetinvi.Controllers.Properties; | ||
using Tweetinvi.Core.Extensions; | ||
using Tweetinvi.Core.QueryGenerators.V2; | ||
using Tweetinvi.Parameters.V2; | ||
|
||
namespace Tweetinvi.Controllers.Timeline | ||
{ | ||
public class TimelinesV2QueryGenerator : ITimelinesV2QueryGenerator | ||
{ | ||
private readonly ITweetsV2QueryGenerator _tweetsV2QueryGenerator; | ||
|
||
public TimelinesV2QueryGenerator(ITweetsV2QueryGenerator tweetsV2QueryGenerator) | ||
{ | ||
_tweetsV2QueryGenerator = tweetsV2QueryGenerator; | ||
} | ||
|
||
public string GetTimelineQuery(IGetTimelinesV2Parameters parameters) | ||
{ | ||
var query = new StringBuilder($"{Resources.UserV2_Get}/{parameters.UserId}/tweets"); | ||
AddTimelineFieldsParameters(parameters, query); | ||
query.AddFormattedParameterToQuery(parameters.FormattedCustomQueryParameters); | ||
return query.ToString(); | ||
} | ||
|
||
public string GetMentionTimelineQuery(IGetTimelinesV2Parameters parameters) | ||
{ | ||
var query = new StringBuilder($"{Resources.UserV2_Get}/{parameters.UserId}/mentions"); | ||
AddTimelineFieldsParameters(parameters, query); | ||
query.AddFormattedParameterToQuery(parameters.FormattedCustomQueryParameters); | ||
return query.ToString(); | ||
} | ||
|
||
public void AddTimelineFieldsParameters(IGetTimelinesV2Parameters parameters, StringBuilder query) | ||
{ | ||
_tweetsV2QueryGenerator.AddTweetFieldsParameters(parameters, query); | ||
|
||
// specific timeline parameters | ||
query.AddParameterToQuery("exclude", parameters.Exclude); | ||
query.AddParameterToQuery("max_results", parameters.MaxResults); | ||
query.AddParameterToQuery("pagination_token", parameters.PaginationToken); | ||
query.AddParameterToQuery("since_id", parameters.SinceId); | ||
query.AddParameterToQuery("start_time", parameters.StartTime?.ToString("yyy-MM-ddThh:mm:ssZ")); | ||
query.AddParameterToQuery("end_time", parameters.EndTime?.ToString("yyy-MM-ddThh:mm:ssZ")); | ||
query.AddParameterToQuery("until_id", parameters.UntilId); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using Tweetinvi.Core.Iterators; | ||
using Tweetinvi.Core.Web; | ||
using Tweetinvi.Models; | ||
using Tweetinvi.Models.V2; | ||
using Tweetinvi.Parameters.V2; | ||
|
||
namespace Tweetinvi.Core.Controllers.V2 | ||
{ | ||
public interface ITimelinesV2Controller | ||
{ | ||
ITwitterPageIterator<ITwitterResult<TimelinesV2Response>, string> GetUserTweetsTimelineIterator(IGetTimelinesV2Parameters parameters, ITwitterRequest request); | ||
ITwitterPageIterator<ITwitterResult<TimelinesV2Response>, string> GetUserMentionedTimelineIterator(IGetTimelinesV2Parameters parameters, ITwitterRequest request); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using System.Text; | ||
using Tweetinvi.Parameters.V2; | ||
|
||
namespace Tweetinvi.Core.QueryGenerators.V2 | ||
{ | ||
public interface ITimelinesV2QueryGenerator | ||
{ | ||
string GetTimelineQuery(IGetTimelinesV2Parameters parameters); | ||
string GetMentionTimelineQuery(IGetTimelinesV2Parameters parameters); | ||
void AddTimelineFieldsParameters(IGetTimelinesV2Parameters parameters, StringBuilder query); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
using Tweetinvi.Iterators; | ||
using Tweetinvi.Models.V2; | ||
using Tweetinvi.Parameters.V2; | ||
|
||
namespace Tweetinvi.Client.V2 | ||
{ | ||
public interface ITimelinesV2Client | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should include additional methods here to provide access directly to a single request and not necessarily the iterator. This is similar to
I guess this can be done in another commit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok. Let's work on this in the next commit. |
||
{ | ||
/// <summary> | ||
/// Returns Tweets composed by a single user, specified by the requested user ID. By default, | ||
/// the most recent ten Tweets are returned per request. Using pagination, the most recent | ||
/// 3,200 Tweets can be retrieved. | ||
/// <para>Read more : https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-tweets </para> | ||
/// </summary> | ||
/// <returns>The Timeline</returns> | ||
ITwitterRequestIterator<TimelinesV2Response, string> GetUserTweetsTimelineIterator(IGetTimelinesV2Parameters parameters); | ||
|
||
/// <summary> | ||
/// Returns Tweets mentioning a single user specified by the requested user ID. By default, | ||
/// the most recent ten Tweets are returned per request. Using pagination, up to the most | ||
/// recent 800 Tweets can be retrieved. | ||
/// <para>Read more : https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-mentions </para> | ||
/// </summary> | ||
ITwitterRequestIterator<TimelinesV2Response, string> GetUserMentionedTimelineIterator(IGetTimelinesV2Parameters parameters); | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
using Tweetinvi.Core.Iterators; | ||
using Tweetinvi.Core.Web; | ||
using Tweetinvi.Models.V2; | ||
using Tweetinvi.Parameters.V2; | ||
|
||
namespace Tweetinvi.Client.Requesters.V2 | ||
{ | ||
public interface ITimelinesV2Requester | ||
{ | ||
/// <summary> | ||
/// Returns Tweets composed by a single user, specified by the requested user ID. By default, | ||
/// the most recent ten Tweets are returned per request. Using pagination, the most recent | ||
/// 3,200 Tweets can be retrieved. | ||
/// <para>Read more : https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-tweets </para> | ||
/// </summary> | ||
/// <returns>The Timeline</returns> | ||
ITwitterPageIterator<ITwitterResult<TimelinesV2Response>, string> GetUserTweetsTimelineIterator(IGetTimelinesV2Parameters parameters); | ||
|
||
/// <summary> | ||
/// Returns Tweets mentioning a single user specified by the requested user ID. By default, | ||
/// the most recent ten Tweets are returned per request. Using pagination, up to the most | ||
/// recent 800 Tweets can be retrieved. | ||
/// <para>Read more : https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-mentions </para> | ||
/// </summary> | ||
ITwitterPageIterator<ITwitterResult<TimelinesV2Response>, string> GetUserMentionedTimelineIterator(IGetTimelinesV2Parameters parameters); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
using Newtonsoft.Json; | ||
|
||
namespace Tweetinvi.Models.V2 | ||
{ | ||
public class TimelinesV2Response | ||
{ | ||
/// <summary> | ||
/// Tweets returned by the request | ||
/// </summary> | ||
[JsonProperty("data")] public TweetV2[] Tweets { get; set; } = new TweetV2[0]; | ||
|
||
/// <summary> | ||
/// Contains all the requested expansions | ||
/// </summary> | ||
[JsonProperty("includes")] public TweetIncludesV2 Includes { get; set; } | ||
|
||
/// <summary> | ||
/// All errors that prevented Twitter to send some data, | ||
/// but which did not prevent the request to be resolved. | ||
/// </summary> | ||
[JsonProperty("errors")] public ErrorV2[] Errors { get; set; } | ||
|
||
/// <summary> | ||
/// This object contains information about the Timeline Tweets | ||
/// returned in the current request and pagination details. | ||
/// </summary> | ||
[JsonProperty("meta")] public TimelineMetaV2 Meta { get; set; } | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
using System; | ||
using Newtonsoft.Json; | ||
|
||
namespace Tweetinvi.Models.V2 | ||
{ | ||
/// <summary> | ||
/// A Tweet | ||
/// <para>Read more here : https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-tweets</para> | ||
/// </summary> | ||
public class TimelineMetaV2 | ||
{ | ||
/// <summary> | ||
/// The Tweet ID of the oldest Tweet returned in the response. | ||
/// </summary> | ||
[JsonProperty("oldest_id")] public string OldestId { get; set; } | ||
|
||
/// <summary> | ||
/// The Tweet ID of the most recent Tweet returned in the response. | ||
/// </summary> | ||
[JsonProperty("newest_id")] public string NewestId { get; set; } | ||
|
||
/// <summary> | ||
/// The number of Tweet results returned in the response. | ||
/// </summary> | ||
[JsonProperty("count")] public int Count { get; set; } | ||
|
||
/// <summary> | ||
/// A value that encodes the next 'page' of results that can be requested, | ||
/// via the pagination_token request parameter. | ||
/// </summary> | ||
[JsonProperty("next_token")] public string NextToken { get; set; } | ||
|
||
/// <summary> | ||
/// A value that encodes the previous 'page' of results that can be requested, | ||
/// via the pagination_token request parameter. | ||
/// </summary> | ||
[JsonProperty("previous_token")] public string PreviousToken { get; set; } | ||
|
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.