/// <summary> /// Initializes a new instance of the <see cref="Telebot" /> class. /// </summary> /// <param name="apiKey">Telegram API key.</param> public Telebot([NotNull] string apiKey) { Contracts.EnsureNotNull(apiKey, nameof(apiKey)); this.ApiKey = apiKey; this.Timeout = TimeSpan.FromMinutes(1); }
/// <summary>Sends answers to an inline query.</summary> /// <param name="inlineQueryId">Unique identifier for answered query.</param> /// <param name="results">Results of the inline query.</param> /// <param name="cacheTime"> /// The maximum amount of time in seconds the result of the inline query may be cached on the Telegram /// server. Default is 300. /// </param> /// <param name="isPersonal"> /// <c>true</c>, to cache the results on the Telegram server only for the user that sent the query. By /// default, results may be returned to any user who sends the same query. /// </param> /// <param name="nextOffset"> /// The offset that a client should send in the next query with the same text to receive more results. /// <c>null</c> or <see cref="string.Empty" /> if there are no more results or if you don't support /// pagination. Offset length can't exceed 64 bytes. /// </param> /// <param name="switchPrivateMessageText"> /// If passed, clients will display a button with specified text that switches the user to a private /// chat with the bot and sends the bot a start message with the parameter /// <paramref name="switchPrivateMessageParameter" />. /// </param> /// <param name="switchPrivateMessageParameter"> /// Parameter for the start message sent to the bot when user presses the switch button. /// <para> /// Example: An inline bot that sends YouTube videos can ask the user to connect the bot to their /// YouTube account to adapt search results accordingly. To do this, it displays a ‘Connect your /// YouTube account’ button above the results, or even before showing any. The user presses the button, /// switches to a private chat with the bot and, in doing so, passes a start parameter that instructs /// the bot to return an oauth link. Once done, the bot can offer a switch_inline button so that the /// user can easily return to the chat where they wanted to use the bot's inline capabilities. /// </para> /// </param> /// <param name="cancellationToken"> /// A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to /// complete. /// </param> /// <returns> /// A task that represents the asynchronous operation. The task results contains <c>true</c> if the /// answer successfully sent; otherwise <c>false</c>. /// </returns> /// <exception cref="System.ArgumentNullException"> /// <paramref name="inlineQueryId" /> is null -or- <paramref name="results" /> is null. /// </exception> /// <exception cref="System.ArgumentException"> /// The nextOffset argument must be less than 64 bytes. /// </exception> /// <exception cref="ArgumentException">No more than 50 results per query are allowed.</exception> public Task <bool> AnswerInlineQueryAsync([NotNull] string inlineQueryId, [NotNull] IEnumerable <InlineQueryResult> results, int cacheTime = 300, bool isPersonal = false, string nextOffset = null, string switchPrivateMessageText = null, string switchPrivateMessageParameter = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(inlineQueryId, nameof(inlineQueryId)); Contracts.EnsureNotNull(results, nameof(results)); var inlineQueryResults = results as IList <InlineQueryResult> ?? results.ToList(); if (inlineQueryResults.Count > 50) { throw new ArgumentException("No more than 50 results per query are allowed.", nameof(results)); } var parameters = new MultipartFormDataContent(); if (!string.IsNullOrWhiteSpace(nextOffset)) { Contracts.EnsureByteCount(nextOffset, nameof(nextOffset)); parameters.Add("next_offset", nextOffset); } parameters.Add("inline_query_id", inlineQueryId); parameters.Add("results", inlineQueryResults); parameters.AddIf(cacheTime != 300, "cache_time", cacheTime); parameters.AddIf(isPersonal, "is_peronal", isPersonal); parameters.AddIf(!string.IsNullOrWhiteSpace(switchPrivateMessageText), "switch_pm_text", switchPrivateMessageText); parameters.AddIf(!string.IsNullOrWhiteSpace(switchPrivateMessageParameter), "switch_pm_parameter", switchPrivateMessageParameter); return(this.CallTelegramMethodAsync <bool>(cancellationToken, "answerInlineQuery", parameters)); }
/// <summary> /// Edits captions of the message with the provided identifier sent by the bot or via the bot (for /// inline bots). /// </summary> /// <param name="chatId"> /// Unique identifier for the target chat or username of the target channel (in the format /// @channelusername). /// </param> /// <param name="messageId">Unique identifier of the sent message.</param> /// <param name="caption">New caption of the message.</param> /// <param name="replyMarkup"> /// An <see cref="InlineKeyboardMarkup" /> object for a custom reply keyboard. /// </param> /// <param name="cancellationToken"> /// A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to /// complete. /// </param> /// <returns> /// A task that represents the asynchronous operation. On success the task results contains the edited /// Message is returned. /// </returns> public Task <Message> EditMessageCaptionAsync([NotNull] string chatId, long messageId, [NotNull] string caption, InlineKeyboardMarkup replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsurePositiveNumber(messageId, nameof(messageId)); return(this.EditMessageCaptionAsync(chatId, messageId, null, caption, replyMarkup, cancellationToken)); }
/// <summary> /// Edits text messages sent by the bot or via the bot (for inline bots). /// </summary> /// <param name="chatId"> /// Unique identifier for the target chat or username of the target channel (in the format /// @channelusername). /// </param> /// <param name="messageId">Unique identifier of the sent message.</param> /// <param name="text">New text of the message</param> /// <param name="parseMode"> /// A value from <see cref="ParseMode" /> enum indicates the way that the Telegram should parse the /// sent message. Send <see cref="ParseMode.Markdown" />, if you want Telegram apps to show bold, /// italic, fixed-width text or inline URLs in your bot's message. /// </param> /// <param name="disableWebPagePreview">Disables link previews for links in this message</param> /// <param name="replyMarkup"> /// An <see cref="InlineKeyboardMarkup" /> object for a custom reply keyboard. /// </param> /// <param name="cancellationToken"> /// A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to /// complete. /// </param> /// <returns> /// A task that represents the asynchronous operation. The task results contains the edited /// <see cref="Message" /> on success. /// </returns> public Task <Message> EditMessageTextAsync([NotNull] string chatId, long messageId, [NotNull] string text, ParseMode parseMode = ParseMode.Normal, bool disableWebPagePreview = false, InlineKeyboardMarkup replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsurePositiveNumber(messageId, nameof(messageId)); return(this.EditMessageTextAsync(chatId, messageId, null, text, parseMode, disableWebPagePreview, replyMarkup, cancellationToken)); }
/// <summary> /// Use this method to set the score of the specified user in a game. /// </summary> /// <param name="disableEditMessage">Pass True, if the game message should not be automatically edited to include the current scoreboard</param> /// <param name="chatId">Required if inline_message_id is not specified. Unique identifier for the target chat</param> /// <param name="inlineMessageId">Required if chat_id and message_id are not specified. Identifier of the inline message</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <param name="userId">User identifier</param> /// <param name="score">New score, must be non-negative</param> /// <param name="force">Pass True, if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters</param> /// <param name="messageId">Required if inline_message_id is not specified. Identifier of the sent message</param> /// <returns> /// On success, if the message was sent by the bot, returns the edited <see cref="Message" />., otherwise returns True. Returns an error, if the new score is not greater than the user's current score in the chat and force is False. /// </returns> public Task <object> SetGameScoreAsync(long userId, long score, bool force = false, bool disableEditMessage = false, string chatId = null, long messageId = 0, string inlineMessageId = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotZero(userId, nameof(userId)); Contracts.EnsureNotNegativeNumber(score, nameof(score)); var parameters = new NameValueCollection(); if (string.IsNullOrWhiteSpace(chatId) && messageId == 0) { Contracts.EnsureNotNull(inlineMessageId, nameof(inlineMessageId)); parameters.Add("inline_message_id", inlineMessageId); } else if (string.IsNullOrWhiteSpace(inlineMessageId)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotZero(messageId, nameof(messageId)); parameters.Add("chat_id", chatId); parameters.Add("message_id", messageId); } parameters.Add("user_id", userId); parameters.Add("score", score); parameters.AddIf(force == true, "force", force); parameters.AddIf(disableEditMessage == true, "disable_edit_message", disableEditMessage); return(this.CallTelegramMethodAsync <object>(cancellationToken, "setGameScore", parameters)); }
/// <summary> /// Downloads the file requested by the /// <see cref="GetFileAsync(string,System.Threading.CancellationToken)" /> method. /// </summary> /// <param name="file"> /// The file info received by calling /// <see cref="GetFileAsync(string,System.Threading.CancellationToken)" />. /// </param> /// <param name="cancellationToken"> /// A cancellation token that can be used by other objects or threads to receive notice of /// cancellation. /// </param> /// <exception cref="ArgumentNullException">File cannot be null.</exception> /// <returns> /// Returns a task containing the downloaded file as a stream. /// </returns> public Task <Stream> DownloadFileAsync([NotNull] File file, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(file, nameof(file)); var url = file.GetDownloadUrl(this.ApiKey); return(this.Client.GetStreamAsync(url)); }
/// <summary> /// Use this method to send a game. /// </summary> /// <param name="chatId">Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername).</param> /// <param name="gameShortName">Short name of the game, serves as the unique identifier for the game. Set up your games via Botfather.</param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param> /// <param name="replyToMessageId">If the message is a reply, ID of the original message.</param> /// <param name="replyMarkup">Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> public Task <Message> SendGameAsync([NotNull] string chatId, [NotNull] string gameShortName, bool disableNotification = false, long replyToMessageId = 0, InlineKeyboardMarkup replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(gameShortName, nameof(gameShortName)); var parameters = new NameValueCollection { { "game_short_name", gameShortName } }; return(this.CallTelegramMethodAsync <Message>(cancellationToken, "sendGame", parameters, chatId, replyToMessageId, replyMarkup, disableNotification)); }
/// <summary> /// Use this method to get the number of members in a chat. /// </summary> /// <param name="chatId"> /// Unique identifier for the target chat or username of the target supergroup or channel /// (in the format @channelusername). /// </param> /// <param name="cancellationToken"> /// A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to /// complete. /// </param> /// <returns> /// A task that represents the asynchronous operation. The task results contains <c>Chat</c> object on /// success. /// </returns> /// <exception cref="System.ArgumentNullException">chatId cannot be null.</exception> public Task <int> GetChatMembersCountAsync([NotNull] string chatId, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); var parameters = new NameValueCollection { { "chat_id", chatId } }; return(this.CallTelegramMethodAsync <int>(cancellationToken, "getChatMembersCount", parameters)); }
/// <summary> /// Sends a chat action. Use this method when you need to tell the user that something is happening on /// the bot's side. /// </summary> /// <param name="chatId"> /// Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername). /// </param> /// <param name="action">Type of action to broadcast.</param> /// <param name="cancellationToken"> /// A cancellation token that can be used by other objects or threads to receive notice of /// cancellation. /// </param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> /// <remarks> /// Use this method when you need to tell the user that something is happening on the bot's side. The /// status is set for 5 seconds or less (when a message arrives from your bot, Telegram clients clear /// its typing status). /// <example> /// The <c>ImageBot</c> needs some time to process a request and upload the image. Instead of sending a /// text message along the lines of "Retrieving image, please wait…", the bot may use /// <see cref="SendChatActionAsync(string,Taikandi.Telebot.Types.ChatAction,System.Threading.CancellationToken)" /> /// with action = upload_photo. The user will see a "sending photo" status for the bot. /// </example> /// </remarks> public Task <bool> SendChatActionAsync([NotNull] string chatId, ChatAction action, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); var parameters = new NameValueCollection { { "action", action.Value } }; return(this.CallTelegramMethodAsync <bool>(cancellationToken, "sendChatAction", parameters, chatId)); }
/// <summary> /// Use this method to get information about a member of a chat. /// </summary> /// <param name="chatId"> /// Unique identifier for the target chat or username of the target supergroup or channel (in the format /// @channelusername) /// </param> /// <param name="userId">Unique identifier of the target user.</param> /// <param name="cancellationToken"> /// A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to /// complete. /// </param> /// <returns> /// A task that represents the asynchronous operation. The task results contains <c>ChatMember</c> object on /// success. /// </returns> /// <exception cref="System.ArgumentNullException">chatId cannot be null.</exception> /// <exception cref="System.ArgumentException">userId must be a number greater than zero.</exception> public Task <ChatMember> GetChatMemberAsync([NotNull] string chatId, long userId, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsurePositiveNumber(userId, nameof(userId)); var parameters = new NameValueCollection { { "chat_id", chatId }, { "user_id", userId } }; return(this.CallTelegramMethodAsync <ChatMember>(cancellationToken, "getChatMember", parameters)); }
/// <summary> /// Sends <c>.webp</c> sticker. /// </summary> /// <param name="chatId">Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername).</param> /// <param name="stickerId">A file id as string to resend a sticker that is already on the Telegram servers.</param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param> /// <param name="replyToMessageId">If the message is a reply, ID of the original message.</param> /// <param name="replyMarkup">Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> public Task <Message> SendStickerAsync([NotNull] string chatId, [NotNull] string stickerId, bool disableNotification = false, long replyToMessageId = 0, IReply replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotNull(stickerId, nameof(stickerId)); var parameters = new NameValueCollection { { "sticker", stickerId } }; return(this.CallTelegramMethodAsync <Message>(cancellationToken, "sendSticker", parameters, chatId, replyToMessageId, replyMarkup, disableNotification)); }
/// <summary> /// Sends an audio file to be displayed as a playable voice message on Telegram clients. /// </summary> /// <param name="chatId">Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername).</param> /// <param name="filePath">Fully qualified path to the audio file.</param> /// <param name="caption"></param> /// <param name="duration">Duration of sent audio in seconds.</param> /// <param name="performer">The performer of the audio.</param> /// <param name="title">The track name.</param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param> /// <param name="replyToMessageId">If the message is a reply, ID of the original message.</param> /// <param name="replyMarkup">Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> public Task <Message> SendAudioFromFileAsync([NotNull] string chatId, [NotNull] string filePath, string caption = null, int duration = 0, string performer = null, string title = null, bool disableNotification = false, long replyToMessageId = 0, IReply replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotNull(filePath, nameof(filePath)); Contracts.EnsureFileExists(filePath); var fileName = Path.GetFileName(filePath); var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); return(this.SendAudioAsync(chatId, fileStream, fileName, caption, duration, performer, title, disableNotification, replyToMessageId, replyMarkup, cancellationToken)); }
/// <summary> /// Sends a point on the map. /// </summary> /// <param name="chatId">Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername).</param> /// <param name="latitude">Latitude of location</param> /// <param name="longitude">Longitude of location</param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param> /// <param name="replyToMessageId">If the message is a reply, ID of the original message.</param> /// <param name="replyMarkup">Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> public Task <Message> SendLocationAsync([NotNull] string chatId, double latitude, double longitude, bool disableNotification = false, long replyToMessageId = 0, IReply replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); var parameters = new NameValueCollection { { "latitude", latitude.ToString(CultureInfo.InvariantCulture) }, { "longitude", longitude.ToString(CultureInfo.InvariantCulture) } }; return(this.CallTelegramMethodAsync <Message>(cancellationToken, "sendLocation", parameters, chatId, replyToMessageId, replyMarkup, disableNotification)); }
/// <summary> /// Sends <c>.webp</c> sticker. /// </summary> /// <param name="chatId">Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername).</param> /// <param name="stickerStream">A <see cref="Stream" /> to the sticker file to send.</param> /// <param name="fileName">A name for the file to be sent using <paramref name="stickerStream" />.</param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param> /// <param name="replyToMessageId">If the message is a reply, ID of the original message.</param> /// <param name="replyMarkup">Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> public Task <Message> SendStickerAsync([NotNull] string chatId, [NotNull] Stream stickerStream, string fileName, bool disableNotification = false, long replyToMessageId = 0, IReply replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotNull(stickerStream, nameof(stickerStream)); // ReSharper disable once UseObjectOrCollectionInitializer var content = new MultipartFormDataContent(); content.Add("sticker", stickerStream, fileName); return(this.CallTelegramMethodAsync <Message>(cancellationToken, "sendSticker", content, chatId, replyToMessageId, replyMarkup, disableNotification)); }
/// <summary> /// Forwards message of any kind. /// </summary> /// <param name="chatId">Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername).</param> /// <param name="fromChatId">Unique identifier for the chat where the original message was sent or username of the target /// channel (in the format @channelusername).</param> /// <param name="messageId">Unique message identifier</param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> public Task <Message> ForwardMessageAsync([NotNull] string chatId, string fromChatId, long messageId, bool disableNotification = false, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); var parameters = new NameValueCollection { { "from_chat_id", fromChatId }, { "message_id", messageId.ToString() } }; return(this.CallTelegramMethodAsync <Message>(cancellationToken, "forwardMessage", parameters, chatId, disableNotification: disableNotification)); }
/// <summary> /// Sends a photo. /// </summary> /// <param name="chatId">Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername).</param> /// <param name="documentId">A file id as string to resend a photo that is already on the Telegram servers.</param> /// <param name="caption">Photo caption (may also be used when resending photos by file id).</param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param> /// <param name="replyToMessageId">If the message is a reply, ID of the original message.</param> /// <param name="replyMarkup">Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> public Task <Message> SendPhotoAsync([NotNull] string chatId, [NotNull] string documentId, string caption = null, bool disableNotification = false, long replyToMessageId = 0, IReply replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotNull(documentId, nameof(documentId)); var parameters = new NameValueCollection { { "photo", documentId } }; parameters.AddIf(!string.IsNullOrWhiteSpace(caption), "caption", caption); return(this.CallTelegramMethodAsync <Message>(cancellationToken, "sendPhoto", parameters, chatId, replyToMessageId, replyMarkup, disableNotification)); }
/// <summary> /// Edits captions of the message with the provided identifier sent by the bot or via the bot (for inline bots). /// </summary> /// <param name="chatId">Unique identifier for the target chat or username of the target channel (in the format @channelusername). Required if <paramref name="inlineMessageId" /> is not specified.</param> /// <param name="messageId">Unique identifier of the sent message. Required if <paramref name="inlineMessageId" /> is not specified.</param> /// <param name="inlineMessageId">Identifier of the inline message. Required if <paramref name="chatId"/> and <paramref name="messageId"/> are not specified. </param> /// <param name="caption">New caption of the message.</param> /// <param name="replyMarkup">An <see cref="InlineKeyboardMarkup" /> object for a custom reply keyboard.</param> /// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. On success the task results contains the edited Message is returned. /// </returns> private Task <Message> EditMessageCaptionAsync(string chatId, long messageId, string inlineMessageId, [NotNull] string caption, InlineKeyboardMarkup replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(caption, nameof(caption)); var parameters = new NameValueCollection(); parameters.AddIf(!string.IsNullOrWhiteSpace(chatId), "chat_id", chatId); parameters.AddIf(messageId > 0, "message_id", messageId.ToString()); parameters.AddIf(!string.IsNullOrWhiteSpace(inlineMessageId), "inline_message_id", inlineMessageId); parameters.Add("caption", caption); return(this.CallTelegramMethodAsync <Message>(cancellationToken, "editMessageText", parameters, replyMarkup: replyMarkup)); }
/// <summary> /// Sends a general file. /// </summary> /// <param name="chatId">Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername).</param> /// <param name="documentStream">A <see cref="Stream" /> to the document file to send.</param> /// <param name="fileName">A name for the file to be sent using <paramref name="documentStream" />.</param> /// <param name="caption">Document caption, 0-200 characters.</param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param> /// <param name="replyToMessageId">If the message is a reply, ID of the original message.</param> /// <param name="replyMarkup">Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> /// <remarks> /// Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the /// future. /// </remarks> public Task <Message> SendDocumentAsync([NotNull] string chatId, [NotNull] Stream documentStream, string fileName, string caption = null, bool disableNotification = false, long replyToMessageId = 0, IReply replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotNull(documentStream, nameof(documentStream)); // ReSharper disable once UseObjectOrCollectionInitializer var content = new MultipartFormDataContent(); content.Add("document", documentStream, fileName); content.AddIf(!string.IsNullOrWhiteSpace(caption), "caption", caption); return(this.CallTelegramMethodAsync <Message>(cancellationToken, "sendDocument", content, chatId, replyToMessageId, replyMarkup, disableNotification)); }
/// <summary>Sends a text message.</summary> /// <param name="chatId"> /// Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername). /// </param> /// <param name="text">Text of the message to be sent.</param> /// <param name="parseMode"> /// Indicates the way that the Telegram should parse the sent message. /// </param> /// <param name="disableWebPagePreview"> /// if set to <c>true</c> disables link previews for links in this message. /// </param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param> /// <param name="replyToMessageId"> /// If the message is a reply, ID of the original message. /// </param> /// <param name="replyMarkup"> /// Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user. /// </param> /// <param name="cancellationToken"> /// A cancellation token that can be used by other objects or threads to receive notice of /// cancellation. /// </param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> public Task <Message> SendMessageAsync([NotNull] string chatId, [NotNull] string text, ParseMode parseMode = ParseMode.Normal, bool disableWebPagePreview = false, bool disableNotification = false, long replyToMessageId = 0, IReply replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotNull(text, nameof(text)); var parameters = new NameValueCollection { { "text", text } }; parameters.AddIf(disableWebPagePreview, "disable_web_page_preview", true); parameters.AddIf(parseMode != ParseMode.Normal, "parse_mode", parseMode.ToString()); return(this.CallTelegramMethodAsync <Message>(cancellationToken, "sendMessage", parameters, chatId, replyToMessageId, replyMarkup, disableNotification)); }
/// <summary> /// Sends answers to callback queries sent from inline keyboards. The answer will be displayed to the /// user as a notification at the top of the chat screen or as an alert. /// </summary> /// <param name="callbackQueryId">Unique identifier for the query to be answered.</param> /// <param name="text"> /// Text of the notification. If not specified, nothing will be shown to the user. /// </param> /// <param name="showAlert"> /// If <c>true</c>, an alert will be shown by the client instead of a notification at the top of the /// chat screen. Defaults to <c>false</c>. /// </param> /// <param name="cancellationToken"> /// A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to /// complete. /// </param> /// <returns> /// A task that represents the asynchronous operation. The task results contains <c>true</c> on /// success; otherwise <c>false</c>. /// </returns> /// <exception cref="System.ArgumentNullException"></exception> public Task <bool> AnswerCallbackQueryAsync([NotNull] string callbackQueryId, string text = null, bool showAlert = false, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(callbackQueryId, nameof(callbackQueryId)); var parameters = new NameValueCollection { { "callback_query_id", callbackQueryId }, { "show_alert", showAlert.ToString() } }; parameters.AddIf(!string.IsNullOrWhiteSpace(text), "text", text); return(this.CallTelegramMethodAsync <bool>(cancellationToken, "answerCallbackQuery", parameters)); }
/// <summary> /// Sends an audio file. If you want Telegram clients to display them in the music player. Your audio must be in the .mp3 format. /// </summary> /// <param name="chatId">Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername).</param> /// <param name="audioStream">A <see cref="Stream" /> to the audio file to send.</param> /// <param name="fileName">A name for the file to be sent using <paramref name="audioStream" />.</param> /// <param name="duration">Duration of the audio in seconds.</param> /// <param name="performer">The performer of the audio.</param> /// <param name="title">The track name.</param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param> /// <param name="replyToMessageId">If the message is a reply, ID of the original message.</param> /// <param name="replyMarkup">Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> public Task <Message> SendAudioAsync([NotNull] string chatId, [NotNull] Stream audioStream, string fileName, int duration, string performer = null, string title = null, bool disableNotification = false, long replyToMessageId = 0, IReply replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotNull(audioStream, nameof(audioStream)); // ReSharper disable once UseObjectOrCollectionInitializer var content = new MultipartFormDataContent(); content.Add("audio", audioStream, fileName); content.AddIf(duration > 0, "duration", duration); content.AddIf(!string.IsNullOrWhiteSpace(performer), "performer", performer); content.AddIf(!string.IsNullOrWhiteSpace(title), "title", title); return(this.CallTelegramMethodAsync <Message>(cancellationToken, "sendAudio", content, chatId, replyToMessageId, replyMarkup, disableNotification)); }
/// <summary> /// Sends an audio file. If you want Telegram clients to display them in the music player. Your audio must be in the .mp3 format. /// </summary> /// <param name="chatId">Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername).</param> /// <param name="audioId">Id of an audio file that is already on the Telegram servers.</param> /// <param name="duration">Duration of the audio in seconds.</param> /// <param name="performer">The performer of the audio.</param> /// <param name="title">The track name.</param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param> /// <param name="replyToMessageId">If the message is a reply, ID of the original message.</param> /// <param name="replyMarkup">Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> public Task <Message> SendAudioAsync([NotNull] string chatId, [NotNull] string audioId, int duration = 0, string performer = null, string title = null, bool disableNotification = false, long replyToMessageId = 0, IReply replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotNull(chatId, nameof(audioId)); var parameters = new NameValueCollection { { "audio", audioId } }; parameters.AddIf(duration > 0, "duration", duration); parameters.AddIf(!string.IsNullOrWhiteSpace(performer), "performer", performer); parameters.AddIf(!string.IsNullOrWhiteSpace(title), "title", title); return(this.CallTelegramMethodAsync <Message>(cancellationToken, "sendAudio", parameters, chatId, replyToMessageId, replyMarkup, disableNotification)); }
/// <summary> /// Edits text messages sent by the bot or via the bot (for inline bots). /// </summary> /// <param name="chatId">Unique identifier for the target chat or username of the target channel (in the format @channelusername). Required if <paramref name="inlineMessageId"/> is not specified.</param> /// <param name="messageId">Unique identifier of the sent message. Required if <paramref name="inlineMessageId"/> is not specified.</param> /// <param name="inlineMessageId">The identifier of the inline message. Required if <paramref name="chatId"/> and <paramref name="messageId"/> are not specified.</param> /// <param name="text">New text of the message</param> /// <param name="parseMode"> /// A value from <see cref="ParseMode"/> enum indicates the way that the Telegram should parse the sent message. /// Send <see cref="ParseMode.Markdown"/>, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. /// </param> /// <param name="disableWebPagePreview">Disables link previews for links in this message</param> /// <param name="replyMarkup">An <see cref="InlineKeyboardMarkup" /> object for a custom reply keyboard.</param> /// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. The task results contains the edited <see cref="Message" /> on success. /// </returns> private Task <Message> EditMessageTextAsync(string chatId, long messageId, string inlineMessageId, [NotNull] string text, ParseMode parseMode = ParseMode.Normal, bool disableWebPagePreview = false, InlineKeyboardMarkup replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(text, nameof(text)); var parameters = new NameValueCollection(); parameters.AddIf(!string.IsNullOrWhiteSpace(chatId), "chat_id", chatId); parameters.AddIf(messageId > 0, "message_id", messageId.ToString()); parameters.AddIf(!string.IsNullOrWhiteSpace(inlineMessageId), "inline_message_id", inlineMessageId); parameters.Add("text", text); parameters.AddIf(parseMode != ParseMode.Normal, "parse_mode", parseMode.ToString()); parameters.AddIf(disableWebPagePreview, "disable_web_page_preview", true); return(this.CallTelegramMethodAsync <Message>(cancellationToken, "editMessageText", parameters, replyMarkup: replyMarkup)); }
/// <summary> /// Sends an audio file to be displayed as a playable voice message on Telegram clients. /// </summary> /// <param name="chatId">Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername).</param> /// <param name="voice">Id of an audio file that is already on the Telegram servers to resend it.</param> /// <param name="caption">Voice message caption, 0-200 characters</param> /// <param name="duration">Duration of sent audio in seconds.</param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param> /// <param name="replyToMessageId">If the message is a reply, ID of the original message.</param> /// <param name="replyMarkup">Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> /// <remarks> /// For this to work, your audio must be in an .ogg file encoded with OPUS (other formats may be sent /// as <see cref="Audio" /> or <see cref="Document" />). Bots can currently send audio files of up to /// 50 MB in size, this limit may be changed in the future. /// </remarks> public Task <Message> SendVoiceAsync([NotNull] string chatId, [NotNull] string voice, string caption, int duration = 0, bool disableNotification = false, long replyToMessageId = 0, IReply replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotNull(voice, nameof(voice)); var parameters = new NameValueCollection { { "voice", voice } }; parameters.AddIf(duration > 0, "duration", duration); parameters.AddIf(!string.IsNullOrWhiteSpace(caption), "caption", caption.Length > 200 ? caption.Substring(0, 200) : caption); return(this.CallTelegramMethodAsync <Message>(cancellationToken, "sendVoice", parameters, chatId, replyToMessageId, replyMarkup, disableNotification)); }
/// <summary> /// Sends an audio file to be displayed as a playable voice message on Telegram clients. /// </summary> /// <param name="chatId">Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername).</param> /// <param name="voice">Id of an audio file that is already on the Telegram servers to resend it.</param> /// <param name="duration">Duration of sent audio in seconds.</param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param> /// <param name="replyToMessageId">If the message is a reply, ID of the original message.</param> /// <param name="replyMarkup">Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> /// <remarks> /// For this to work, your audio must be in an .ogg file encoded with OPUS (other formats may be sent /// as <see cref="Audio" /> or <see cref="Document" />). Bots can currently send audio files of up to /// 50 MB in size, this limit may be changed in the future. /// </remarks> public Task <Message> SendVoiceAsync([NotNull] string chatId, [NotNull] string voice, int duration = 0, bool disableNotification = false, long replyToMessageId = 0, IReply replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotNull(voice, nameof(voice)); var parameters = new NameValueCollection { { "voice", voice } }; if (duration > 0) { parameters.Add("duration", duration); } return(this.CallTelegramMethodAsync <Message>(cancellationToken, "sendVoice", parameters, chatId, replyToMessageId, replyMarkup, disableNotification)); }
/// <summary>Send phone contacts.</summary> /// <param name="chatId"> /// Unique identifier for the target chat or username of the target channel (in the format /// @channelusername) /// </param> /// <param name="phoneNumber">Contact's phone number.</param> /// <param name="firstName">Contact's first name.</param> /// <param name="lastName">Contact's last name.</param> /// <param name="disableNotification"> /// If set to <c>true</c> sends the message silently. iOS users will not receive a notification, /// Android users will receive a notification with no sound. /// </param> /// <param name="replyToMessageId"> /// If the message is a reply, ID of the original message. /// </param> /// <param name="replyMarkup"> /// Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user. /// </param> /// <param name="cancellationToken"> /// A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to /// complete. /// </param> /// <returns> /// A task that represents the asynchronous operation. The task results contains sent /// <see cref="Message" /> on success. /// </returns> /// <exception cref="System.ArgumentNullException"> /// chatId cannot be null -or- phoneNumber cannot be null -or- firstName cannot be null. /// </exception> public Task <Message> SendContactAsync([NotNull] string chatId, [NotNull] string phoneNumber, [NotNull] string firstName, string lastName = null, bool disableNotification = false, long replyToMessageId = 0, IReply replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotNull(phoneNumber, nameof(phoneNumber)); Contracts.EnsureNotNull(firstName, nameof(firstName)); var parameters = new NameValueCollection { { "chat_id", chatId }, { "phone_number", phoneNumber }, { "first_name", firstName } }; parameters.AddIf(!string.IsNullOrWhiteSpace(lastName), "last_name", lastName); parameters.AddIf(!disableNotification, "disable_notification", true); parameters.AddIf(replyToMessageId > 0, "reply_to_message_id", replyToMessageId); return(this.CallTelegramMethodAsync <Message>(cancellationToken, "sendContact", parameters, replyMarkup: replyMarkup)); }
/// <summary> /// Use this method to get data for high score tables. Will return the score of the specified user and /// several of his neighbors in a game. On success, returns an Array of GameHighScore objects. /// </summary> /// <param name="userId">Target user id</param> /// <param name="chatId">Required if inline_message_id is not specified. Unique identifier for the target chat.</param> /// <param name="inlineMessageId">Required if chat_id and message_id are not specified. Identifier of the inline message.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <param name="messageId">Required if inline_message_id is not specified. Identifier of the sent message.</param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> public Task <GameHighScore[]> GetGameHighScoresAsync(long userId, string chatId = null, long messageId = 0, string inlineMessageId = null, CancellationToken cancellationToken = default(CancellationToken)) { var parameters = new NameValueCollection(); if (string.IsNullOrWhiteSpace(chatId) && messageId == 0) { Contracts.EnsureNotNull(inlineMessageId, nameof(inlineMessageId)); parameters.Add("inline_message_id", inlineMessageId); } else if (string.IsNullOrWhiteSpace(inlineMessageId)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotZero(messageId, nameof(messageId)); parameters.Add("chat_id", chatId); parameters.Add("message_id", messageId); } parameters.Add("user_id", userId); return(this.CallTelegramMethodAsync <GameHighScore[]>(cancellationToken, "getGameHighScores", parameters, chatId)); }
/// <summary> /// Send information about a venue. /// </summary> /// <param name="chatId">Unique identifier for the target chat or username of the target channel (in the format /// @channelusername).</param> /// <param name="latitude">Latitude of the venue.</param> /// <param name="longitude">Longitude of the venue.</param> /// <param name="title">Name of the venue.</param> /// <param name="address">Address of the venue.</param> /// <param name="forsquareId">Foursquare identifier of the venue.</param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, /// Android users will receive a notification with no sound.</param> /// <param name="replyToMessageId">If the message is a reply, ID of the original message.</param> /// <param name="replyMarkup">Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user.</param> /// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to /// complete.</param> /// <returns> /// A task that represents the asynchronous operation. The task results contains sent /// <see cref="Message" /> on success. /// </returns> /// <exception cref="System.ArgumentNullException">chatId cannot be null -or- title cannot be null -or- address cannot be null.</exception> public Task <Message> SendVenueAsync([NotNull] string chatId, float latitude, float longitude, [NotNull] string title, [NotNull] string address, string forsquareId = null, bool disableNotification = false, long replyToMessageId = 0, IReply replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotNull(title, nameof(title)); Contracts.EnsureNotNull(address, nameof(address)); var parameters = new NameValueCollection { { "chat_id", chatId }, { "latitude", latitude.ToString(CultureInfo.InvariantCulture) }, { "longitude", longitude.ToString(CultureInfo.InvariantCulture) }, { "title", title }, { "address", address } }; parameters.AddIf(!string.IsNullOrWhiteSpace(forsquareId), "foursquare_id", forsquareId); parameters.AddIf(!disableNotification, "disable_notification", true); parameters.AddIf(replyToMessageId > 0, "reply_to_message_id", replyToMessageId); return(this.CallTelegramMethodAsync <Message>(cancellationToken, "sendVenue", parameters, replyMarkup: replyMarkup)); }
/// <summary> /// Sends a video file. /// </summary> /// <param name="chatId">Unique identifier for the message recipient or username of the target channel (in the format /// @channelusername).</param> /// <param name="videoStream">A <see cref="Stream" /> to the video file to send.</param> /// <param name="fileName">A name for the file to be sent using <paramref name="videoStream" />.</param> /// <param name="duration">Duration of sent video in seconds.</param> /// <param name="caption">Video caption.</param> /// <param name="disableNotification">If set to <c>true</c> sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param> /// <param name="replyToMessageId">If the message is a reply, ID of the original message.</param> /// <param name="replyMarkup">Additional interface options. An <see cref="IReply" /> object for a custom reply keyboard, /// instructions to hide keyboard or to force a reply from the user.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of /// cancellation.</param> /// <returns> /// On success, returns the sent <see cref="Message" />. /// </returns> /// <remarks> /// Telegram clients support mp4 videos (other formats may be sent as <see cref="Document" />). Bots /// can currently send video files of up to 50 MB in size, this limit may be changed in the future. /// </remarks> public Task <Message> SendVideoAsync([NotNull] string chatId, [NotNull] Stream videoStream, string fileName, int duration = 0, string caption = null, bool disableNotification = false, long replyToMessageId = 0, IReply replyMarkup = null, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(chatId, nameof(chatId)); Contracts.EnsureNotNull(videoStream, nameof(videoStream)); var content = new MultipartFormDataContent { { new StreamContent(videoStream), "video", fileName } }; if (duration > 0) { content.Add("duration", duration); } if (caption != null) { content.Add("caption", caption); } return(this.CallTelegramMethodAsync <Message>(cancellationToken, "sendVideo", content, chatId, replyToMessageId, replyMarkup, disableNotification)); }
/// <summary> /// Downloads the file requested by the /// <see cref="GetFileAsync(string,System.Threading.CancellationToken)" /> method. /// </summary> /// <param name="file"> /// The file info received by calling /// <see cref="GetFileAsync(string,System.Threading.CancellationToken)" />. /// </param> /// <param name="fullPath"> /// The full directory and file name to the location where the downloaded file should be saved. /// </param> /// <param name="overwrite"> /// If set to <c>true</c> overwrites the file that exists in the <paramref name="fullPath" /> path. /// </param> /// <param name="cancellationToken"> /// A cancellation token that can be used by other objects or threads to receive notice of /// cancellation. /// </param> /// <exception cref="InvalidOperationException"> /// File already exists in the destination path but overwrite parameter is set to <c>false</c>. /// </exception> /// <exception cref="ArgumentNullException">file cannot be null | fullPath cannot be null.</exception> /// <returns>A task that represents the asynchronous operation.</returns> public async Task DownloadFileAsync([NotNull] File file, [NotNull] string fullPath, bool overwrite = false, CancellationToken cancellationToken = default(CancellationToken)) { Contracts.EnsureNotNull(file, nameof(file)); Contracts.EnsureNotNull(fullPath, nameof(fullPath)); if (System.IO.File.Exists(fullPath)) { if (!overwrite) { throw new IOException($"File '{fullPath}' already exists."); } System.IO.File.Delete(fullPath); } using (var response = await this.DownloadFileAsync(file, cancellationToken).ConfigureAwait(false)) { using (var fileStream = new FileStream(fullPath, FileMode.Create, FileAccess.Write, FileShare.None)) { await response.CopyToAsync(fileStream, 81920, cancellationToken).ConfigureAwait(false); } } }