/// <summary> /// Sends a new direct message to specified user. /// </summary> /// <param name="userID">User ID of user to send to.</param> /// <param name="text">Direct message contents.</param> /// <returns>Direct message element.</returns> public async Task <DirectMessage> NewDirectMessageAsync(ulong userID, string text, CancellationToken cancelToken = default(CancellationToken)) { if (userID == 0) { throw new ArgumentException("userID must be set.", "userID"); } if (string.IsNullOrWhiteSpace(text)) { throw new ArgumentException("text is a required parameter.", "text"); } var newUrl = BaseUrl + "direct_messages/new.json"; var reqProc = new DirectMessageRequestProcessor <DirectMessage>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <DirectMessage>( HttpMethod.Post.ToString(), newUrl, new Dictionary <string, string> { { "user_id", userID.ToString() }, { "text", text } }, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, DirectMessageType.Show)); }
/// <summary> /// Lets logged-in user follow another user. /// </summary> /// <param name="screenName">Screen name of user to follow</param> /// <param name="follow">Receive notifications for the followed friend</param> /// <returns>followed friend user info</returns> public async Task <User?> CreateFriendshipAsync(string screenName, bool follow, CancellationToken cancelToken = default(CancellationToken)) { if (string.IsNullOrWhiteSpace(screenName)) { throw new ArgumentException("screenName is a required parameter.", "screenName"); } string destroyUrl = BaseUrl + "friendships/create.json"; var createParams = new Dictionary <string, string?> { { "screen_name", screenName } }; // If follow exists in the parameter list, Twitter will // always treat it as true, even if the value is false; // Therefore, only add follow if it is true. if (follow) { createParams.Add("follow", "true"); } var reqProc = new FriendshipRequestProcessor <User>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <User>( HttpMethod.Post.ToString(), destroyUrl, createParams, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, FriendshipAction.Create)); }
/// <summary> /// Deletes a direct message. /// </summary> /// <param name="id">id of direct message</param> /// <param name="includeEntites">Set to false to prevent entities from being included (default: true).</param> /// <returns>direct message element</returns> public async Task <DirectMessage> DestroyDirectMessageAsync(ulong id, bool includeEntites, CancellationToken cancelToken = default(CancellationToken)) { if (id == 0) { throw new ArgumentNullException("id", "id is required."); } var destroyUrl = BaseUrl + "direct_messages/destroy.json"; var reqProc = new DirectMessageRequestProcessor <DirectMessage>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <DirectMessage>( HttpMethod.Post.ToString(), destroyUrl, new Dictionary <string, string> { { "id", id.ToString() }, { "include_entities", includeEntites.ToString().ToLower() } }, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, DirectMessageType.Show)); }
/// <summary> /// Deletes a favorite from the logged-in user's profile. /// </summary> /// <param name="id">id of status to add to favorites</param> /// <param name="includeEntities">Response doesn't include entities when false. (default: true)</param> /// <returns>status of favorite</returns> public async Task <Status> DestroyFavoriteAsync(ulong id, bool includeEntities, CancellationToken cancelToken = default(CancellationToken)) { if (id == 0) { throw new ArgumentException("id is a required parameter.", "id"); } var favoritesUrl = BaseUrl + "favorites/destroy.json"; var reqProc = new StatusRequestProcessor <Status>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <Status>( HttpMethod.Post.ToString(), favoritesUrl, new Dictionary <string, string> { { "id", id.ToString() }, { "include_entities", includeEntities.ToString() } }, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, FavoritesAction.SingleStatus)); }
/// <summary> /// Lets logged-in user set retweets and/or device notifications for a follower. /// </summary> /// <param name="userID">Twitter's ID for user</param> /// <param name="screenName">screen name of user to update</param> /// <param name="retweets">Enable retweets</param> /// <param name="device">Receive notifications</param> /// <returns>updated friend user info</returns> async Task <Friendship?> UpdateFriendshipSettingsAsync(ulong userID, string?screenName, bool retweets, bool device, CancellationToken cancelToken = default(CancellationToken)) { var parms = new Dictionary <string, string?> { { "retweets", retweets.ToString().ToLower() }, { "device", device.ToString().ToLower() } }; if (screenName != null) { parms.Add("screen_name", screenName); } if (userID > 0) { parms.Add("user_id", userID.ToString()); } string updateUrl = BaseUrl + "friendships/update.json"; var reqProc = new FriendshipRequestProcessor <Friendship>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <Friendship>( HttpMethod.Post.ToString(), updateUrl, parms, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, FriendshipAction.Update)); }
/// <summary> /// Adds a saved search to your twitter account /// </summary> /// <param name="id">ID of saved search</param> /// <param name="callback">Async Callback used in Silverlight queries</param> /// <returns>SavedSearch object</returns> public async Task <SavedSearch?> DestroySavedSearchAsync(ulong id, CancellationToken cancelToken = default(CancellationToken)) { if (id == 0) { throw new ArgumentException("Invalid Saved Search ID: " + id, "id"); } var savedSearchUrl = BaseUrl + "saved_searches/destroy/" + id + ".json"; var reqProc = new SavedSearchRequestProcessor <SavedSearch>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <SavedSearch>( HttpMethod.Post.ToString(), savedSearchUrl, new Dictionary <string, string?>(), cancelToken) .ConfigureAwait(false); SavedSearch?result = reqProc.ProcessActionResult(RawResult, SavedSearchAction.Destroy); if (result != null) { result.ID = id; } return(result); }
[Obsolete("This twitter endpoint doesn't exist anymore", error: true)] // TODO: remove after a few versions. public async Task <Account> UpdateDeliveryDeviceAsync(DeviceType device, bool?includeEntitites, CancellationToken cancelToken = default(CancellationToken)) { var accountUrl = BaseUrl + "account/update_delivery_device.json"; var reqProc = new AccountRequestProcessor <Account>(); var parameters = new Dictionary <string, string> { { "device", device.ToString().ToLower() } }; if (includeEntitites != null) { parameters.Add("include_entities", includeEntitites.ToString().ToLower()); } RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <Account>( HttpMethod.Post.ToString(), accountUrl, parameters, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, AccountAction.Settings)); }
[Obsolete("This twitter endpoint doesn't exist anymore", error: true)] // TODO: remove after a few versions. public async Task <User> UpdateAccountColorsAsync(string background, string text, string link, string sidebarFill, string sidebarBorder, bool includeEntities, bool skipStatus, CancellationToken cancelToken = default(CancellationToken)) { var accountUrl = BaseUrl + "account/update_profile_colors.json"; if (string.IsNullOrWhiteSpace(background) && string.IsNullOrWhiteSpace(text) && string.IsNullOrWhiteSpace(link) && string.IsNullOrWhiteSpace(sidebarFill) && string.IsNullOrWhiteSpace(sidebarBorder)) { throw new ArgumentException("At least one of the colors (background, text, link, sidebarFill, or sidebarBorder) must be provided as arguments, but none are specified.", NoInputParam); } var reqProc = new UserRequestProcessor <User>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <User>( HttpMethod.Post.ToString(), accountUrl, new Dictionary <string, string> { { "profile_background_color", string.IsNullOrWhiteSpace(background) ? null : background.TrimStart('#') }, { "profile_text_color", string.IsNullOrWhiteSpace(text) ? null : text.TrimStart('#') }, { "profile_link_color", string.IsNullOrWhiteSpace(link) ? null : link.TrimStart('#') }, { "profile_sidebar_fill_color", string.IsNullOrWhiteSpace(sidebarFill) ? null : sidebarFill.TrimStart('#') }, { "profile_sidebar_border_color", string.IsNullOrWhiteSpace(sidebarBorder) ? null : sidebarBorder.TrimStart('#') }, { "include_entities", includeEntities.ToString().ToLower() }, { "skip_status", skipStatus.ToString().ToLower() } }, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, UserAction.SingleUser)); }
/// <summary> /// Unblocks a user. /// </summary> /// <param name="userID">ID of user to block</param> /// <param name="screenName">Screen name of user to block</param> /// <param name="includeEntities">Set to false to not include entities (default: true)</param> /// <param name="skipStatus">Don't include status</param> /// <returns>User that was unblocked</returns> public async Task <User> DestroyBlockAsync(ulong userID, string screenName, bool includeEntities, bool skipStatus, CancellationToken cancelToken = default(CancellationToken)) { if (userID <= 0 && string.IsNullOrWhiteSpace(screenName)) { throw new ArgumentException("Either userID or screenName are required parameters.", "UserIDOrScreenName"); } var blocksUrl = BaseUrl + "blocks/destroy.json"; var reqProc = new BlocksRequestProcessor <User>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <User>( HttpMethod.Post.ToString(), blocksUrl, new Dictionary <string, string> { { "user_id", userID <= 0 ? (string)null : userID.ToString() }, { "screen_name", screenName }, { "include_entities", includeEntities.ToString().ToLower() }, { "skip_status", skipStatus.ToString().ToLower() } }, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, UserAction.SingleUser)); }
/// <summary> /// Sends an image to Twitter to be placed as the user's profile banner. /// </summary> /// <param name="banner">byte[] containing image data.</param> /// <param name="width">Pixel width to clip image.</param> /// <param name="height">Pixel height to clip image.</param> /// <param name="offsetLeft">Pixels to offset start of image from the left.</param> /// <param name="offsetTop">Pixels to offset start of image from the top.</param> /// <returns> /// Account of authenticated user who's profile banner will be updated. /// Url of new banner will appear in ProfileBannerUrl property. /// </returns> public async Task <User> UpdateProfileBannerAsync(byte[] banner, int width, int height, int offsetLeft, int offsetTop, CancellationToken cancelToken = default(CancellationToken)) { var accountUrl = BaseUrl + "account/update_profile_banner.json"; if (banner == null || banner.Length == 0) { throw new ArgumentException("banner is required.", "banner"); } var parameters = new Dictionary <string, string?> { { "width", width.ToString() }, { "height", height.ToString() }, { "offset_left", offsetLeft.ToString() }, { "offset_top", offsetTop.ToString() }, { "banner", Convert.ToBase64String(banner) } }; var reqProc = new UserRequestProcessor <User>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <User>( HttpMethod.Post.ToString(), accountUrl, parameters, cancelToken) .ConfigureAwait(false); return(new User()); }
/// <summary> /// Removes one or more users from a Site Stream /// </summary> /// <param name="userIDs">List of user IDs to remove from Site Stream</param> /// <param name="streamID">ID of Site Stream to remove users from</param> /// <returns>Control Stream with CommandResponse property for Twitter's response message</returns> public async Task <ControlStream> RemoveSiteStreamUserAsync(List <ulong> userIDs, string streamID, CancellationToken cancelToken = default(CancellationToken)) { if (string.IsNullOrWhiteSpace(streamID)) { throw new ArgumentNullException("streamID", "streamID is required."); } var newUrl = SiteStreamUrl + "site/c/" + streamID + "/remove_user.json"; string userIDString = string.Join(",", userIDs.Select(user => user.ToString()).ToArray()); var reqProc = new ControlStreamRequestProcessor <ControlStream>(); var resultsJson = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <ControlStream>( HttpMethod.Post.ToString(), newUrl, new Dictionary <string, string> { { "user_id", userIDString } }, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(resultsJson, ControlStreamType.Info)); }
/// <summary> /// Sends a status update. /// </summary> /// <param name="tweetID">ID (aka StatusID) of tweet to reply to. Sent via ReplyAsync overloads.</param> /// <param name="status">Status text.</param> /// <param name="latitude">Latitude coordinate of where tweet occurred.</param> /// <param name="longitude">Longitude coordinate of where tweet occurred.</param> /// <param name="placeID">ID of place (found via Geo Reverse lookup query).</param> /// <param name="displayCoordinates">Allow or prevent display of coordinates for this tweet.</param> /// <param name="trimUser">Remove user entity from response</param> /// <param name="mediaIds">Collection of ids of media to include in tweet.</param> /// <param name="autoPopulateReplyMetadata">Enables extended tweet mode where mentions don't count towards tweet length.</param> /// <param name="excludeReplyUserIds">Comma-separated list of @mentions to exclude from extended tweet prefix list.</param> /// <param name="attachmentUrl">Tweet link or DM deep link for extended tweet suffix that doesn't count towards tweet length.</param> /// <param name="cancelToken">Async cancellation token.</param> /// <returns>Tweeted status.</returns> internal virtual async Task <Status> TweetOrReplyAsync(ulong tweetID, string status, decimal latitude, decimal longitude, string placeID, bool displayCoordinates, bool trimUser, IEnumerable <ulong> mediaIds, bool autoPopulateReplyMetadata, IEnumerable <ulong> excludeReplyUserIds, string attachmentUrl, CancellationToken cancelToken = default(CancellationToken)) { if (string.IsNullOrWhiteSpace(status) && (mediaIds == null || !mediaIds.Any())) { throw new ArgumentException("status is a required parameter.", "status"); } var updateUrl = BaseUrl + "statuses/update.json"; RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <Status>( HttpMethod.Post.ToString(), updateUrl, new Dictionary <string, string> { { "status", status }, { "in_reply_to_status_id", tweetID == NoReply ? null : tweetID.ToString() }, { "lat", latitude == NoCoordinate ? null : latitude.ToString(Culture.US) }, { "long", longitude == NoCoordinate ? null : longitude.ToString(Culture.US) }, { "place_id", placeID == NoInputParam ? null : placeID }, { "display_coordinates", displayCoordinates ? displayCoordinates.ToString().ToLower() : null }, { "trim_user", trimUser ? trimUser.ToString().ToLower() : null }, { "media_ids", mediaIds == null || !mediaIds.Any() ? null : string.Join(",", mediaIds) }, { "auto_populate_reply_metadata", autoPopulateReplyMetadata ? autoPopulateReplyMetadata.ToString().ToLower() : null }, { "exclude_reply_user_ids", excludeReplyUserIds == null || !excludeReplyUserIds.Any() ? null : string.Join(",", excludeReplyUserIds) }, { "attachment_url", attachmentUrl } }, cancelToken) .ConfigureAwait(false); return(new StatusRequestProcessor <Status>() .ProcessActionResult(RawResult, StatusAction.SingleStatus)); }
/// <summary> /// Modifies an existing list. /// </summary> /// <param name="listID">ID of list</param> /// <param name="slug">name of list</param> /// <param name="ownerID">ID of user who owns the list.</param> /// <param name="ownerScreenName">Screen name of user who owns the list.</param> /// <param name="mode">public or private</param> /// <param name="description">list description</param> /// <returns>List info for modified list</returns> public async Task <List> UpdateListAsync(ulong listID, string slug, string name, ulong ownerID, string ownerScreenName, string mode, string description, CancellationToken cancelToken = default(CancellationToken)) { if (listID == 0 && string.IsNullOrWhiteSpace(slug)) { throw new ArgumentException("Either listID or slug is required.", ListIDOrSlugParam); } if (!string.IsNullOrWhiteSpace(slug) && ownerID == 0 && string.IsNullOrWhiteSpace(ownerScreenName)) { throw new ArgumentException("If you specify a Slug, you must also specify either OwnerID or OwnerScreenName.", OwnerIDOrOwnerScreenNameParam); } var updateListUrl = BaseUrl + "lists/update.json"; var reqProc = new ListRequestProcessor <List>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <List>( HttpMethod.Post.ToString(), updateListUrl, new Dictionary <string, string> { { "list_id", listID.ToString() }, { "slug", slug }, { "owner_id", ownerID.ToString() }, { "owner_screen_name", ownerScreenName }, { "mode", mode }, { "description", description }, { "name", name } }, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, ListAction.Update)); }
/// <summary> /// Adds a new webhook to account /// </summary> /// <param name="url">Url of webhook.</param> /// <returns>Account Activity data.</returns> public async Task <AccountActivity?> AddAccountActivityWebhookAsync(string url, CancellationToken cancelToken = default) { if (string.IsNullOrWhiteSpace(url)) { throw new ArgumentException($"{nameof(url)} must be set.", nameof(url)); } var newUrl = BaseUrl + $"account_activity/webhooks.json"; RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <AccountActivity>( HttpMethod.Post.ToString(), newUrl, new Dictionary <string, string?> { { "url", url } }, cancelToken) .ConfigureAwait(false); var reqProc = new AccountActivityRequestProcessor <AccountActivity>(); AccountActivity?accAct = reqProc.ProcessActionResult(RawResult, AccountActivityType.Webhooks); if (accAct != null) { accAct.Url = url; } return(accAct); }
/// <summary> /// Marks direct messages as having been read. /// </summary> /// <param name="lastReadEventID">ID of last direct message read.</param> /// <param name="recipientID">ID of user to send typing indicator to.</param> /// <param name="cancelToken">Async cancellation token.</param> public async Task MarkReadAsync(ulong lastReadEventID, ulong recipientID, CancellationToken cancelToken = default(CancellationToken)) { if (lastReadEventID == default(ulong)) { throw new ArgumentException($"{nameof(lastReadEventID)} must be set.", nameof(lastReadEventID)); } if (recipientID == default(ulong)) { throw new ArgumentException($"{nameof(recipientID)} must be set.", nameof(recipientID)); } var newUrl = BaseUrl + "direct_messages/mark_read.json"; RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <DirectMessageEvents>( HttpMethod.Post.ToString(), newUrl, new Dictionary <string, string> { ["last_read_event_id"] = lastReadEventID.ToString(), ["recipient_id"] = recipientID.ToString() }, cancelToken) .ConfigureAwait(false); }
/// <summary> /// Creates a new list. /// </summary> /// <param name="listName">name of list</param> /// <param name="mode">public or private</param> /// <param name="description">list description</param> /// <returns>List info for new list</returns> public async Task <List> CreateListAsync(string listName, string mode, string description, CancellationToken cancelToken = default(CancellationToken)) { if (string.IsNullOrWhiteSpace(listName)) { throw new ArgumentException("listName is required.", "listName"); } var createUrl = BaseUrl + "lists/create.json"; var reqProc = new ListRequestProcessor <List>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <List>( HttpMethod.Post.ToString(), createUrl, new Dictionary <string, string> { { "name", listName }, { "mode", mode }, { "description", description } }, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, ListAction.Create)); }
/// <summary> /// Lets you perform a query by specifying the raw URL and parameters yourself. /// Useful for when Twitter changes or adds new features before they are added to LINQ to Twitter. /// </summary> /// <param name="queryString">The segments that follow the base URL. i.e. "statuses/home_timeline.json" for a home timeline query</param> /// <param name="parameters">Querystring parameters that will be appended to the URL</param> /// <param name="method"><see cref="HttpMethod"/> for sending the request.</param> /// <returns>Twitter JSON response.</returns> public async Task <string> ExecuteRawAsync(string queryString, Dictionary <string, string> parameters, HttpMethod method, CancellationToken cancelToken = default) { string rawUrl = BaseUrl.TrimEnd('/') + "/" + queryString.TrimStart('/'); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <Raw>(method.ToString(), rawUrl, parameters, cancelToken).ConfigureAwait(false); return(RawResult); }
/// <summary> /// Deletes membership for a comma-separated list of users. /// </summary> /// <param name="listID">ID of list.</param> /// <param name="slug">Name of list to remove from.</param> /// <param name="userIds">List of user IDs of users to remove from list membership.</param> /// <param name="screenNames">List of screen names of users to remove from list membership.</param> /// <param name="ownerID">ID of users who owns the list.</param> /// <param name="ownerScreenName">Screen name of user who owns the list.</param> /// <returns>List info for list subscription removed from</returns> async Task <List> DeleteMemberRangeFromListAsync(ulong listID, string slug, List <ulong> userIDs, List <string> screenNames, ulong ownerID, string ownerScreenName, CancellationToken cancelToken = default(CancellationToken)) { if (listID == 0 && string.IsNullOrWhiteSpace(slug)) { throw new ArgumentException("Either listID or slug is required.", ListIDOrSlugParam); } if (listID == 0 && !string.IsNullOrWhiteSpace(slug) && ownerID == 0 && string.IsNullOrWhiteSpace(ownerScreenName)) { throw new ArgumentException("If using slug, you must also provide either ownerID or ownerScreenName.", OwnerIDOrOwnerScreenNameParam); } if ((userIDs != null && userIDs.Count > 100) || (screenNames != null && screenNames.Count > 100)) { throw new ArgumentException("You can only remove 100 members at a Time.", "userIDs"); } var destroyAllUrl = BaseUrl + "lists/members/destroy_all.json"; var reqProc = new ListRequestProcessor <List>(); var parameters = new Dictionary <string, string>(); if (listID != 0) { parameters.Add("list_id", listID.ToString()); } if (!string.IsNullOrWhiteSpace(slug)) { parameters.Add("slug", slug); } if (userIDs != null && userIDs.Any()) { parameters.Add("user_id", string.Join(",", userIDs.Select(id => id.ToString(CultureInfo.InvariantCulture)).ToArray())); } if (screenNames != null && screenNames.Any()) { parameters.Add("screen_name", string.Join(",", screenNames)); } if (ownerID != 0) { parameters.Add("owner_id", ownerID.ToString()); } if (!string.IsNullOrWhiteSpace(ownerScreenName)) { parameters.Add("owner_screen_name", ownerScreenName); } RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <List>(HttpMethod.Post.ToString(), destroyAllUrl, parameters, cancelToken).ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, ListAction.DestroyAll)); }
/// <summary> /// Removes a user as a list member. /// </summary> /// <param name="userID">ID of user to add to list.</param> /// <param name="screenName">ScreenName of user to add to list.</param> /// <param name="listID">ID of list.</param> /// <param name="slug">Name of list to remove from.</param> /// <param name="ownerID">ID of user who owns the list.</param> /// <param name="ownerScreenName">Screen name of user who owns the list.</param> /// <returns>List info for list member removed from</returns> public async Task <List> DeleteMemberFromListAsync(ulong userID, string screenName, ulong listID, string slug, ulong ownerID, string ownerScreenName, CancellationToken cancelToken = default(CancellationToken)) { if (userID == 0 && string.IsNullOrWhiteSpace(screenName)) { throw new ArgumentException("Either userID or screenName is required.", UserIDOrScreenNameParam); } if (listID == 0 && string.IsNullOrWhiteSpace(slug)) { throw new ArgumentException("Either listID or slug is required.", ListIDOrSlugParam); } if (!string.IsNullOrWhiteSpace(slug) && ownerID == 0 && string.IsNullOrWhiteSpace(ownerScreenName)) { throw new ArgumentException("If using slug, you must also provide either ownerID or ownerScreenName.", OwnerIDOrOwnerScreenNameParam); } var deleteUrl = BaseUrl + "lists/members/destroy.json"; var reqProc = new ListRequestProcessor <List>(); var parameters = new Dictionary <string, string>(); if (listID != 0) { parameters.Add("list_id", listID.ToString()); } if (!string.IsNullOrWhiteSpace(slug)) { parameters.Add("slug", slug); } if (userID != 0) { parameters.Add("user_id", userID.ToString()); } if (!string.IsNullOrWhiteSpace(screenName)) { parameters.Add("screen_name", screenName); } if (ownerID != 0) { parameters.Add("owner_id", ownerID.ToString()); } if (!string.IsNullOrWhiteSpace(ownerScreenName)) { parameters.Add("owner_screen_name", ownerScreenName); } RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <List>(HttpMethod.Post.ToString(), deleteUrl, parameters, cancelToken).ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, ListAction.DeleteMember)); }
internal async Task <User?> ReportSpamAsync(IDictionary <string, string?> reportParams, CancellationToken cancelToken = default(CancellationToken)) { string reportSpamUrl = BaseUrl + "users/report_spam.json"; RawResult = await TwitterExecutor .PostFormUrlEncodedToTwitterAsync <User>(HttpMethod.Post.ToString(), reportSpamUrl, reportParams, cancelToken) .ConfigureAwait(false); return(new UserRequestProcessor <User>() .ProcessActionResult(RawResult, StatusAction.SingleStatus)); }
/// <summary> /// Update account profile info /// </summary> /// <param name="name">User Name</param> /// <param name="url">Web Address</param> /// <param name="location">Geographic Location</param> /// <param name="description">Personal Description</param> /// <param name="includeEntities">Set to false to not include entities. (default: true)</param> /// <param name="skipStatus">Don't include status with response.</param> /// <returns>User with new info</returns> public async Task <User> UpdateAccountProfileAsync(string name, string url, string location, string description, bool includeEntities, bool skipStatus, CancellationToken cancelToken = default(CancellationToken)) { var accountUrl = BaseUrl + "account/update_profile.json"; if (string.IsNullOrWhiteSpace(name) && string.IsNullOrWhiteSpace(url) && string.IsNullOrWhiteSpace(location) && string.IsNullOrWhiteSpace(description)) { throw new ArgumentException("At least one of the text fields (name, email, url, location, or description) must be provided as arguments, but none are specified.", NoInputParam); } if (!string.IsNullOrWhiteSpace(name) && name.Length > 20) { throw new ArgumentException("name must be no longer than 20 characters", "name"); } if (!string.IsNullOrWhiteSpace(url) && url.Length > 100) { throw new ArgumentException("url must be no longer than 100 characters", "url"); } if (!string.IsNullOrWhiteSpace(location) && location.Length > 30) { throw new ArgumentException("location must be no longer than 30 characters", "location"); } if (!string.IsNullOrWhiteSpace(description) && description.Length > 160) { throw new ArgumentException("description must be no longer than 160 characters", "description"); } var reqProc = new UserRequestProcessor <User>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <User>( HttpMethod.Post.ToString(), accountUrl, new Dictionary <string, string> { { "name", name }, { "url", url }, { "location", location }, { "description", description }, { "include_entities", includeEntities.ToString().ToLower() }, { "skip_status", skipStatus.ToString().ToLower() } }, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, UserAction.SingleUser)); }
async Task <User> MuteAsync(IDictionary <string, string> muteParams, CancellationToken cancelToken = default(CancellationToken)) { var muteUrl = BaseUrl + "mutes/users/create.json"; var reqProc = new UserRequestProcessor <User>(); RawResult = await TwitterExecutor .PostFormUrlEncodedToTwitterAsync <User>(HttpMethod.Post.ToString(), muteUrl, muteParams, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, UserAction.SingleUser)); }
/// <summary> /// Updates user's account settings /// </summary> /// <param name="trendLocationWeoid">WEOID for Trend Location the user is interested in.</param> /// <param name="sleepTimeEnabled">Turn on time periods when notifications won't be sent.</param> /// <param name="startSleepTime">Don't send notifications at this time or later this time. (hour from 00 to 23)</param> /// <param name="endSleepTime">Start sending notifications again after this time. (hour from 00 to 23)</param> /// <param name="timeZone">User's time zone.</param> /// <param name="lang">User's language.</param> /// <returns>Account information with Settings property populated.</returns> public async Task <Account> UpdateAccountSettingsAsync(int?trendLocationWoeid, bool?sleepTimeEnabled, int?startSleepTime, int?endSleepTime, string timeZone, string lang, CancellationToken cancelToken = default(CancellationToken)) { var accountUrl = BaseUrl + "account/settings.json"; if (trendLocationWoeid == null && sleepTimeEnabled == null && startSleepTime == null && endSleepTime == null && string.IsNullOrWhiteSpace(timeZone) && string.IsNullOrWhiteSpace(lang)) { throw new ArgumentException("At least one parameter must be provided as arguments, but none are specified.", NoInputParam); } var reqProc = new AccountRequestProcessor <Account>(); var parameters = new Dictionary <string, string> { { "time_zone", timeZone }, { "lang", lang } }; if (trendLocationWoeid != null) { parameters.Add("trend_location_woeid", trendLocationWoeid.ToString()); } if (sleepTimeEnabled != null) { parameters.Add("sleep_time_enabled", sleepTimeEnabled.ToString().ToLower()); } if (startSleepTime != null) { parameters.Add("start_sleep_time", startSleepTime.ToString()); } if (endSleepTime != null) { parameters.Add("end_sleep_time", endSleepTime.ToString()); } RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <Account>( HttpMethod.Post.ToString(), accountUrl, parameters, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, AccountAction.Settings)); }
/// <summary> /// Retweets a tweet. /// </summary> /// <param name="tweetID">ID of tweet being retweeted.</param> /// <returns>Retweeted tweet.</returns> public virtual async Task <Status> RetweetAsync(ulong tweetID, CancellationToken cancelToken = default(CancellationToken)) { if (tweetID == MissingID) { throw new ArgumentException("0 is *not* a valid tweetID. You must provide the ID of the tweet you're retweeting.", "tweetID"); } var retweetUrl = BaseUrl + "statuses/retweet/" + tweetID + ".json"; RawResult = await TwitterExecutor .PostFormUrlEncodedToTwitterAsync <Status>(HttpMethod.Post.ToString(), retweetUrl, new Dictionary <string, string>(), cancelToken) .ConfigureAwait(false); return(new StatusRequestProcessor <Status>() .ProcessActionResult(RawResult, StatusAction.SingleStatus)); }
/// <summary> /// Removes banner from authenticated user's profile. /// </summary> /// <returns>Empty User instance.</returns> public async Task <User> RemoveProfileBannerAsync(CancellationToken cancelToken = default(CancellationToken)) { var accountUrl = BaseUrl + "account/remove_profile_banner.json"; var reqProc = new UserRequestProcessor <User>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <User>( HttpMethod.Post.ToString(), accountUrl, new Dictionary <string, string>(), cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, UserAction.SingleUser)); }
/// <summary> /// Sends a typing indicator to a user. /// </summary> /// <param name="recipientID">ID of user to send typing indicator to.</param> /// <param name="cancelToken">Async cancellation token.</param> public async Task IndicateTypingAsync(ulong recipientID, CancellationToken cancelToken = default) { if (recipientID == default) { throw new ArgumentException($"{nameof(recipientID)} must be set.", nameof(recipientID)); } var newUrl = BaseUrl + "direct_messages/indicate_typing.json"; RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <DirectMessageEvents>( HttpMethod.Post.ToString(), newUrl, new Dictionary <string, string?> { ["recipient_id"] = recipientID.ToString() }, cancelToken) .ConfigureAwait(false); }
/// <summary> /// Deletes a direct message. /// </summary> /// <param name="directMessageID">ID of direct message to delete.</param> /// <param name="cancelToken">Async cancellation token.</param> public async Task DeleteDirectMessageEventAsync(ulong directMessageID, CancellationToken cancelToken = default(CancellationToken)) { if (directMessageID == default(ulong)) { throw new ArgumentException($"{nameof(directMessageID)} must be set.", nameof(directMessageID)); } var newUrl = BaseUrl + "direct_messages/events/destroy.json?id=" + directMessageID; RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <DirectMessageEvents>( HttpMethod.Delete.ToString(), newUrl, new Dictionary <string, string> { ["id"] = directMessageID.ToString() }, cancelToken) .ConfigureAwait(false); }
/// <summary> /// Creates a new compliance job /// </summary> /// <param name="jobName"></param> /// <param name="resumable"></param> /// <param name="cancelToken">Optional cancellation token</param> /// <returns>New <see cref="ComplianceJob"/> details</returns> public async Task <ComplianceJob?> CreateComplianceJobAsync(string jobName, bool resumable, CancellationToken cancelToken = default) { string url = $"{BaseUrl2}tweets/compliance/jobs"; var postData = new Dictionary <string, string?> { { "job_name", jobName }, { "resumable", resumable ? "true" : "false" } }; RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <ComplianceJob>( HttpMethod.Post.ToString(), url, postData, cancelToken) .ConfigureAwait(false); ComplianceJob?job = JsonSerializer.Deserialize <ComplianceJob>(RawResult); return(job); }
/// <summary> /// Lets logged-in user un-follow another user. /// </summary> /// <param name="screenName">Screen name of user to unfollow</param> /// <returns>followed friend user info</returns> public async Task <User?> DestroyFriendshipAsync(string screenName, CancellationToken cancelToken = default(CancellationToken)) { if (string.IsNullOrWhiteSpace(screenName)) { throw new ArgumentException("screenName is a required parameter.", "screenName"); } string destroyUrl = BaseUrl + "friendships/destroy.json"; var reqProc = new FriendshipRequestProcessor <User>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <User>( HttpMethod.Post.ToString(), destroyUrl, new Dictionary <string, string?> { { "screen_name", screenName } }, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, FriendshipAction.Destroy)); }
/// <summary> /// Lets logged-in user un-follow another user. /// </summary> /// <param name="userID">ID of user to unfollow</param> /// <returns>followed friend user info</returns> public async Task <User?> DestroyFriendshipAsync(ulong userID, CancellationToken cancelToken = default(CancellationToken)) { if (userID == 0) { throw new ArgumentException("userID is a required parameter.", "userID"); } string destroyUrl = BaseUrl + "friendships/destroy.json"; var reqProc = new FriendshipRequestProcessor <User>(); RawResult = await TwitterExecutor.PostFormUrlEncodedToTwitterAsync <User>( HttpMethod.Post.ToString(), destroyUrl, new Dictionary <string, string?> { { "user_id", userID.ToString() } }, cancelToken) .ConfigureAwait(false); return(reqProc.ProcessActionResult(RawResult, FriendshipAction.Destroy)); }