/// <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));
        }
예제 #2
0
        /// <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));
        }
예제 #4
0
        /// <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));
        }
예제 #5
0
        /// <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);
        }
예제 #7
0
        [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));
        }
예제 #8
0
        [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));
        }
예제 #9
0
        /// <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());
        }
예제 #11
0
        /// <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));
        }
예제 #12
0
        /// <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));
        }
예제 #20
0
        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));
        }
예제 #21
0
        /// <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));
        }
예제 #22
0
        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));
        }
예제 #23
0
        /// <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));
        }
예제 #24
0
        /// <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));
        }
예제 #25
0
        /// <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));
        }
예제 #26
0
        /// <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);
        }
예제 #28
0
        /// <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);
        }
예제 #29
0
        /// <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));
        }
예제 #30
0
        /// <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));
        }