void UploadProgress(InstaUploaderProgress progress)
 {
     if (progress == null)
     {
         return;
     }
     Console.WriteLine($"{progress.Name} {progress.UploadState}");
 }
Exemplo n.º 2
0
 private void UploadProgress(InstaUploaderProgress progress)
 {
     if (progress == null)
     {
         return;
     }
     this.logger.LogTrace($"{progress.Name} {progress.UploadState}");
 }
Exemplo n.º 3
0
 //Function to be called by photo upload functions to update progressLbl
 private void UpdateUploadProgressToLabel(InstaUploaderProgress progress)
 {
     if (progress == null)
     {
         return;
     }
     progressLbl.Text = $"{progress.Name}: {progress.UploadState}";
 }
        void Invoke(long bytes, long size)
        {
            if (UploaderProgress == null)
            {
                UploaderProgress = new InstaUploaderProgress();
            }
            UploaderProgress.FileSize      = size;
            UploaderProgress.UploadedBytes = bytes;
            var state = size == bytes ? InstaUploadState.Uploaded : InstaUploadState.Uploading;

            UploaderProgress.UploadState = state;
            progress?.Invoke(UploaderProgress);
        }
Exemplo n.º 5
0
        /// <summary>
        ///     Configure story video
        /// </summary>
        /// <param name="video">Video to configure</param>
        /// <param name="uploadId">Upload id</param>
        /// <param name="caption">Caption</param>
        private async Task <IResult <InstaStoryMedia> > ConfigureStoryVideoAsync(Action <InstaUploaderProgress> progress, InstaUploaderProgress upProgress, InstaVideoUpload video, string uploadId,
                                                                                 string caption)
        {
            try
            {
                upProgress.UploadState = InstaUploadState.Configuring;
                progress?.Invoke(upProgress);
                var    instaUri = UriCreator.GetVideoStoryConfigureUri(false);
                Random rnd      = new Random();
                var    data     = new JObject
                {
                    { "filter_type", "0" },
                    { "timezone_offset", "16200" },
                    { "_csrftoken", _user.CsrfToken },
                    { "client_shared_at", (long.Parse(ApiRequestMessage.GenerateUploadId()) - rnd.Next(25, 55)).ToString() },
                    { "story_media_creation_date", (long.Parse(ApiRequestMessage.GenerateUploadId()) - rnd.Next(50, 70)).ToString() },
                    { "media_folder", "Camera" },
                    { "configure_mode", "1" },
                    { "source_type", "4" },
                    { "video_result", "" },
                    { "_uid", _user.LoggedInUser.Pk.ToString() },
                    { "_uuid", _deviceInfo.DeviceGuid.ToString() },
                    { "caption", caption },
                    { "date_time_original", DateTime.Now.ToString("yyyy-dd-MMTh:mm:ss-0fffZ") },
                    { "capture_type", "normal" },
                    { "mas_opt_in", "NOT_PROMPTED" },
                    { "upload_id", uploadId },
                    { "client_timestamp", ApiRequestMessage.GenerateUploadId() },
                    {
                        "device", new JObject {
                            { "manufacturer", _deviceInfo.HardwareManufacturer },
                            { "model", _deviceInfo.DeviceModelIdentifier },
                            { "android_release", _deviceInfo.AndroidVer.VersionNumber },
                            { "android_version", _deviceInfo.AndroidVer.APILevel }
                        }
                    },
                    { "length", 0 },
                    {
                        "extra", new JObject
                        {
                            { "source_width", 0 },
                            { "source_height", 0 }
                        }
                    },
                    { "audio_muted", false },
                    { "poster_frame_index", 0 },
                };
                var request         = HttpHelper.GetSignedRequest(HttpMethod.Post, instaUri, _deviceInfo, data);
                var uploadParamsObj = new JObject
                {
                    { "num_step_auto_retry", 0 },
                    { "num_reupload", 0 },
                    { "num_step_manual_retry", 0 }
                };
                var uploadParams = JsonConvert.SerializeObject(uploadParamsObj);
                request.Headers.Add("retry_context", uploadParams);
                var response = await _httpRequestProcessor.SendAsync(request);

                var json = await response.Content.ReadAsStringAsync();

                if (response.IsSuccessStatusCode)
                {
                    var mediaResponse = JsonConvert.DeserializeObject <InstaStoryMediaResponse>(json);
                    var converter     = ConvertersFabric.Instance.GetStoryMediaConverter(mediaResponse);
                    var obj           = Result.Success(converter.Convert());
                    upProgress.UploadState = InstaUploadState.Configured;
                    progress?.Invoke(upProgress);
                    upProgress.UploadState = InstaUploadState.Completed;
                    progress?.Invoke(upProgress);
                    return(obj);
                }
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                return(Result.UnExpectedResponse <InstaStoryMedia>(response, json));
            }
            catch (Exception exception)
            {
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                _logger?.LogException(exception);
                return(Result.Fail <InstaStoryMedia>(exception.Message));
            }
        }
Exemplo n.º 6
0
        /// <summary>
        ///     Upload story video (to self story) with progress
        /// </summary>
        /// <param name="progress">Progress action</param>
        /// <param name="video">Video to upload</param>
        /// <param name="caption">Caption</param>
        public async Task <IResult <InstaStoryMedia> > UploadStoryVideoAsync(Action <InstaUploaderProgress> progress, InstaVideoUpload video, string caption)
        {
            UserAuthValidator.Validate(_userAuthValidate);
            var upProgress = new InstaUploaderProgress
            {
                Caption     = caption ?? string.Empty,
                UploadState = InstaUploadState.Preparing
            };

            try
            {
                var uploadId      = ApiRequestMessage.GenerateRandomUploadId();
                var videoHashCode = Path.GetFileName(video.Video.Uri ?? $"C:\\{13.GenerateRandomString()}.mp4").GetHashCode();
                var photoHashCode = Path.GetFileName(video.VideoThumbnail.Uri ?? $"C:\\{13.GenerateRandomString()}.jpg").GetHashCode();

                var waterfallId = Guid.NewGuid().ToString();

                var videoEntityName = string.Format("{0}_0_{1}", uploadId, videoHashCode);
                var videoUri        = UriCreator.GetStoryUploadVideoUri(uploadId, videoHashCode);

                var photoEntityName = string.Format("{0}_0_{1}", uploadId, photoHashCode);
                var photoUri        = UriCreator.GetStoryUploadPhotoUri(uploadId, photoHashCode);

                upProgress.UploadId = uploadId;
                progress?.Invoke(upProgress);
                var videoMediaInfoData = new JObject
                {
                    { "_csrftoken", _user.CsrfToken },
                    { "_uid", _user.LoggedInUser.Pk },
                    { "_uuid", _deviceInfo.DeviceGuid.ToString() },
                    { "media_info", new JObject
                      {
                          { "capture_mode", "normal" },
                          { "media_type", 2 },
                          { "caption", caption },
                          { "mentions", new JArray() },
                          { "hashtags", new JArray() },
                          { "locations", new JArray() },
                          { "stickers", new JArray() },
                      } }
                };
                var request  = HttpHelper.GetSignedRequest(HttpMethod.Post, UriCreator.GetStoryMediaInfoUploadUri(), _deviceInfo, videoMediaInfoData);
                var response = await _httpRequestProcessor.SendAsync(request);

                var json = await response.Content.ReadAsStringAsync();

                var videoUploadParamsObj = new JObject
                {
                    { "upload_media_height", "0" },
                    { "upload_media_width", "0" },
                    { "upload_media_duration_ms", "46000" },
                    { "upload_id", uploadId },
                    { "for_album", "1" },
                    { "retry_context", "{\"num_step_auto_retry\":0,\"num_reupload\":0,\"num_step_manual_retry\":0}" },
                    { "media_type", "2" },
                };
                var videoUploadParams = JsonConvert.SerializeObject(videoUploadParamsObj);
                request = HttpHelper.GetDefaultRequest(HttpMethod.Get, videoUri, _deviceInfo);
                request.Headers.Add("X_FB_VIDEO_WATERFALL_ID", waterfallId);
                request.Headers.Add("X-Instagram-Rupload-Params", videoUploadParams);
                response = await _httpRequestProcessor.SendAsync(request);

                json = await response.Content.ReadAsStringAsync();

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    upProgress.UploadState = InstaUploadState.Error;
                    progress?.Invoke(upProgress);
                    return(Result.UnExpectedResponse <InstaStoryMedia>(response, json));
                }


                byte[] videoBytes;
                if (video.Video.VideoBytes == null)
                {
                    videoBytes = File.ReadAllBytes(video.Video.Uri);
                }
                else
                {
                    videoBytes = video.Video.VideoBytes;
                }
                var videoContent = new ByteArrayContent(videoBytes);
                videoContent.Headers.Add("Content-Transfer-Encoding", "binary");
                videoContent.Headers.Add("Content-Type", "application/octet-stream");
                var progressContent = new ProgressableStreamContent(videoContent, 4096, progress)
                {
                    UploaderProgress = upProgress
                };
                request         = HttpHelper.GetDefaultRequest(HttpMethod.Post, videoUri, _deviceInfo);
                request.Content = progressContent;
                var vidExt = Path.GetExtension(video.Video.Uri ?? $"C:\\{13.GenerateRandomString()}.mp4").Replace(".", "").ToLower();
                if (vidExt == "mov")
                {
                    request.Headers.Add("X-Entity-Type", "video/quicktime");
                }
                else
                {
                    request.Headers.Add("X-Entity-Type", "video/mp4");
                }
                request.Headers.Add("Offset", "0");
                request.Headers.Add("X-Instagram-Rupload-Params", videoUploadParams);
                request.Headers.Add("X-Entity-Name", videoEntityName);
                request.Headers.Add("X-Entity-Length", videoBytes.Length.ToString());
                request.Headers.Add("X_FB_VIDEO_WATERFALL_ID", waterfallId);
                response = await _httpRequestProcessor.SendAsync(request);

                json = await response.Content.ReadAsStringAsync();

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    upProgress.UploadState = InstaUploadState.Error;
                    progress?.Invoke(upProgress);
                    return(Result.UnExpectedResponse <InstaStoryMedia>(response, json));
                }

                var photoUploadParamsObj = new JObject
                {
                    { "retry_context", "{\"num_step_auto_retry\":0,\"num_reupload\":0,\"num_step_manual_retry\":0}" },
                    { "media_type", "2" },
                    { "upload_id", uploadId },
                    { "image_compression", "{\"lib_name\":\"moz\",\"lib_version\":\"3.1.m\",\"quality\":\"95\"}" },
                };
                var photoUploadParams = JsonConvert.SerializeObject(photoUploadParamsObj);
                request = HttpHelper.GetDefaultRequest(HttpMethod.Get, photoUri, _deviceInfo);
                request.Headers.Add("X_FB_PHOTO_WATERFALL_ID", waterfallId);
                request.Headers.Add("X-Instagram-Rupload-Params", photoUploadParams);
                response = await _httpRequestProcessor.SendAsync(request);

                json = await response.Content.ReadAsStringAsync();

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    upProgress.UploadState = InstaUploadState.Error;
                    progress?.Invoke(upProgress);
                    return(Result.UnExpectedResponse <InstaStoryMedia>(response, json));
                }

                upProgress.UploadState = InstaUploadState.UploadingThumbnail;
                progress?.Invoke(upProgress);
                byte[] imageBytes;
                if (video.VideoThumbnail.ImageBytes == null)
                {
                    imageBytes = File.ReadAllBytes(video.VideoThumbnail.Uri);
                }
                else
                {
                    imageBytes = video.VideoThumbnail.ImageBytes;
                }
                var imageContent = new ByteArrayContent(imageBytes);
                imageContent.Headers.Add("Content-Transfer-Encoding", "binary");
                imageContent.Headers.Add("Content-Type", "application/octet-stream");
                request         = HttpHelper.GetDefaultRequest(HttpMethod.Post, photoUri, _deviceInfo);
                request.Content = imageContent;
                request.Headers.Add("X-Entity-Type", "image/jpeg");
                request.Headers.Add("Offset", "0");
                request.Headers.Add("X-Instagram-Rupload-Params", photoUploadParams);
                request.Headers.Add("X-Entity-Name", photoEntityName);
                request.Headers.Add("X-Entity-Length", imageBytes.Length.ToString());
                request.Headers.Add("X_FB_PHOTO_WATERFALL_ID", waterfallId);
                response = await _httpRequestProcessor.SendAsync(request);

                json = await response.Content.ReadAsStringAsync();

                if (response.IsSuccessStatusCode)
                {
                    upProgress             = progressContent?.UploaderProgress;
                    upProgress.UploadState = InstaUploadState.ThumbnailUploaded;
                    progress?.Invoke(upProgress);
                    return(await ConfigureStoryVideoAsync(progress, upProgress, video, uploadId, caption));
                }
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                return(Result.UnExpectedResponse <InstaStoryMedia>(response, json));
            }
            catch (Exception exception)
            {
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                _logger?.LogException(exception);
                return(Result.Fail <InstaStoryMedia>(exception.Message));
            }
        }
Exemplo n.º 7
0
        /// <summary>
        ///     Configure story photo
        /// </summary>
        /// <param name="image">Photo to configure</param>
        /// <param name="uploadId">Upload id</param>
        /// <param name="caption">Caption</param>
        private async Task <IResult <InstaStoryMedia> > ConfigureStoryPhotoAsync(Action <InstaUploaderProgress> progress, InstaUploaderProgress upProgress, InstaImage image, string uploadId,
                                                                                 string caption)
        {
            try
            {
                upProgress.UploadState = InstaUploadState.Configuring;
                progress?.Invoke(upProgress);
                var instaUri = UriCreator.GetStoryConfigureUri();
                var data     = new JObject
                {
                    { "_uuid", _deviceInfo.DeviceGuid.ToString() },
                    { "_uid", _user.LoggedInUser.Pk },
                    { "_csrftoken", _user.CsrfToken },
                    { "source_type", "1" },
                    { "caption", caption },
                    { "upload_id", uploadId },
                    { "edits", new JObject() },
                    { "disable_comments", false },
                    { "configure_mode", 1 },
                    { "camera_position", "unknown" }
                };
                var request  = HttpHelper.GetSignedRequest(HttpMethod.Post, instaUri, _deviceInfo, data);
                var response = await _httpRequestProcessor.SendAsync(request);

                var json = await response.Content.ReadAsStringAsync();

                if (response.IsSuccessStatusCode)
                {
                    var mediaResponse = JsonConvert.DeserializeObject <InstaStoryMediaResponse>(json);
                    var converter     = ConvertersFabric.Instance.GetStoryMediaConverter(mediaResponse);
                    var obj           = converter.Convert();
                    upProgress.UploadState = InstaUploadState.Configured;
                    progress?.Invoke(upProgress);

                    upProgress.UploadState = InstaUploadState.Completed;
                    progress?.Invoke(upProgress);
                    return(Result.Success(obj));
                }
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                return(Result.UnExpectedResponse <InstaStoryMedia>(response, json));
            }
            catch (Exception exception)
            {
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                _logger?.LogException(exception);
                return(Result.Fail <InstaStoryMedia>(exception.Message));
            }
        }
Exemplo n.º 8
0
        /// <summary>
        ///     Upload story photo with progress
        /// </summary>
        /// <param name="progress">Progress action</param>
        /// <param name="image">Photo to upload</param>
        /// <param name="caption">Caption</param>
        public async Task <IResult <InstaStoryMedia> > UploadStoryPhotoAsync(Action <InstaUploaderProgress> progress, InstaImage image, string caption)
        {
            UserAuthValidator.Validate(_userAuthValidate);
            var upProgress = new InstaUploaderProgress
            {
                Caption     = caption ?? string.Empty,
                UploadState = InstaUploadState.Preparing
            };

            try
            {
                var instaUri = UriCreator.GetUploadPhotoUri();
                var uploadId = ApiRequestMessage.GenerateUploadId();
                upProgress.UploadId = uploadId;
                progress?.Invoke(upProgress);
                var requestContent = new MultipartFormDataContent(uploadId)
                {
                    { new StringContent(uploadId), "\"upload_id\"" },
                    { new StringContent(_deviceInfo.DeviceGuid.ToString()), "\"_uuid\"" },
                    { new StringContent(_user.CsrfToken), "\"_csrftoken\"" },
                    {
                        new StringContent("{\"lib_name\":\"jt\",\"lib_version\":\"1.3.0\",\"quality\":\"95\"}"),
                        "\"image_compression\""
                    }
                };
                byte[] imageBytes;
                if (image.ImageBytes == null)
                {
                    imageBytes = File.ReadAllBytes(image.Uri);
                }
                else
                {
                    imageBytes = image.ImageBytes;
                }
                var imageContent = new ByteArrayContent(imageBytes);
                imageContent.Headers.Add("Content-Transfer-Encoding", "binary");
                imageContent.Headers.Add("Content-Type", "application/octet-stream");

                var progressContent = new ProgressableStreamContent(imageContent, 4096, progress)
                {
                    UploaderProgress = upProgress
                };
                requestContent.Add(progressContent, "photo", $"pending_media_{ApiRequestMessage.GenerateUploadId()}.jpg");
                var request = HttpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo);
                request.Content = requestContent;
                var response = await _httpRequestProcessor.SendAsync(request);

                var json = await response.Content.ReadAsStringAsync();

                if (response.IsSuccessStatusCode)
                {
                    upProgress = progressContent?.UploaderProgress;
                    return(await ConfigureStoryPhotoAsync(progress, upProgress, image, uploadId, caption));
                }
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                return(Result.UnExpectedResponse <InstaStoryMedia>(response, json));
            }
            catch (Exception exception)
            {
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                _logger?.LogException(exception);
                return(Result.Fail <InstaStoryMedia>(exception.Message));
            }
        }
        private async Task <IResult <InstaMedia> > ConfigureAlbumAsync(Action <InstaUploaderProgress> progress, InstaUploaderProgress upProgress, string[] imagesUploadIds, Dictionary <string, InstaVideo> videos, string caption, InstaLocationShort location)
        {
            try
            {
                upProgress.Name        = "Album upload";
                upProgress.UploadState = InstaUploadState.Configuring;
                progress?.Invoke(upProgress);
                var instaUri        = UriCreator.GetMediaAlbumConfigureUri();
                var clientSidecarId = ApiRequestMessage.GenerateUploadId();
                var childrenArray   = new JArray();
                if (imagesUploadIds != null)
                {
                    foreach (var id in imagesUploadIds)
                    {
                        childrenArray.Add(new JObject
                        {
                            { "timezone_offset", "16200" },
                            { "source_type", 4 },
                            { "upload_id", id },
                            { "caption", "" },
                        });
                    }
                }
                if (videos != null)
                {
                    foreach (var id in videos)
                    {
                        childrenArray.Add(new JObject
                        {
                            { "timezone_offset", "16200" },
                            { "caption", "" },
                            { "upload_id", id.Key },
                            { "date_time_original", DateTime.Now.ToString("yyyy-dd-MMTh:mm:ss-0fffZ") },
                            { "source_type", "4" },
                            {
                                "extra", JsonConvert.SerializeObject(new JObject
                                {
                                    { "source_width", 0 },
                                    { "source_height", 0 }
                                })
                            },
                            {
                                "clips", JsonConvert.SerializeObject(new JArray {
                                    new JObject
                                    {
                                        { "length", id.Value.Length },
                                        { "source_type", "4" },
                                    }
                                })
                            },
                            {
                                "device", JsonConvert.SerializeObject(new JObject {
                                    { "manufacturer", _deviceInfo.HardwareManufacturer },
                                    { "model", _deviceInfo.DeviceModelIdentifier },
                                    { "android_release", _deviceInfo.AndroidVer.VersionNumber },
                                    { "android_version", _deviceInfo.AndroidVer.APILevel }
                                })
                            },
                            { "length", id.Value.Length },
                            { "poster_frame_index", 0 },
                            { "audio_muted", false },
                            { "filter_type", "0" },
                            { "video_result", "deprecated" },
                        });
                    }
                }
                var data = new JObject
                {
                    { "_uuid", _deviceInfo.DeviceGuid.ToString() },
                    { "_uid", _user.LoggedInUser.Pk },
                    { "_csrftoken", _user.CsrfToken },
                    { "caption", caption },
                    { "client_sidecar_id", clientSidecarId },
                    { "upload_id", clientSidecarId },
                    {
                        "device", new JObject
                        {
                            { "manufacturer", _deviceInfo.HardwareManufacturer },
                            { "model", _deviceInfo.DeviceModelIdentifier },
                            { "android_release", _deviceInfo.AndroidVer.VersionNumber },
                            { "android_version", _deviceInfo.AndroidVer.APILevel }
                        }
                    },
                    { "children_metadata", childrenArray },
                };
                if (location != null)
                {
                    data.Add("location", location.GetJson());
                    data.Add("date_time_digitalized", DateTime.Now.ToString("yyyy:dd:MM+h:mm:ss"));
                }
                var request  = _httpHelper.GetSignedRequest(HttpMethod.Post, instaUri, _deviceInfo, data);
                var response = await _httpRequestProcessor.SendAsync(request);

                var json = await response.Content.ReadAsStringAsync();

                if (!response.IsSuccessStatusCode)
                {
                    upProgress.UploadState = InstaUploadState.Error;
                    progress?.Invoke(upProgress);
                    return(Result.UnExpectedResponse <InstaMedia>(response, json));
                }
                var mediaResponse = JsonConvert.DeserializeObject <InstaMediaAlbumResponse>(json);
                var converter     = ConvertersFabric.Instance.GetSingleMediaFromAlbumConverter(mediaResponse);
                var obj           = converter.Convert();
                if (obj.Caption == null && !string.IsNullOrEmpty(caption))
                {
                    var editedMedia = await _instaApi.MediaProcessor.EditMediaAsync(obj.InstaIdentifier, caption, location);

                    if (editedMedia.Succeeded)
                    {
                        upProgress.UploadState = InstaUploadState.Configured;
                        progress?.Invoke(upProgress);
                        upProgress.UploadState = InstaUploadState.Completed;
                        progress?.Invoke(upProgress);
                        return(Result.Success(editedMedia.Value));
                    }
                }
                upProgress.UploadState = InstaUploadState.Configured;
                progress?.Invoke(upProgress);
                upProgress.UploadState = InstaUploadState.Completed;
                progress?.Invoke(upProgress);
                return(Result.Success(obj));
            }
            catch (Exception exception)
            {
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                _logger?.LogException(exception);
                return(Result.Fail <InstaMedia>(exception));
            }
        }
        /// <summary>
        ///     Upload album (videos and photos)
        /// </summary>
        /// <param name="progress">Progress action</param>
        /// <param name="images">Array of photos to upload</param>
        /// <param name="videos">Array of videos to upload</param>
        /// <param name="caption">Caption</param>
        /// <param name="location">Location => Optional (get it from <seealso cref="LocationProcessor.SearchLocationAsync"/></param>
        public async Task <IResult <InstaMedia> > UploadAlbumAsync(Action <InstaUploaderProgress> progress, InstaImage[] images, InstaVideoUpload[] videos, string caption, InstaLocationShort location = null)
        {
            UserAuthValidator.Validate(_userAuthValidate);
            var upProgress = new InstaUploaderProgress
            {
                Caption     = caption ?? string.Empty,
                UploadState = InstaUploadState.Preparing
            };

            try
            {
                upProgress.Name = "Album upload";
                progress?.Invoke(upProgress);
                string[] imagesUploadIds = null;
                var      index           = 1;
                if (images != null && images.Any())
                {
                    imagesUploadIds = new string[images.Length];
                    foreach (var image in images)
                    {
                        var instaUri = UriCreator.GetUploadPhotoUri();
                        var uploadId = ApiRequestMessage.GenerateUploadId();
                        upProgress.UploadId    = uploadId;
                        upProgress.Name        = $"[Album] Photo uploading {index}/{images.Length}";
                        upProgress.UploadState = InstaUploadState.Uploading;
                        progress?.Invoke(upProgress);
                        var requestContent = new MultipartFormDataContent(uploadId)
                        {
                            { new StringContent(uploadId), "\"upload_id\"" },
                            { new StringContent(_deviceInfo.DeviceGuid.ToString()), "\"_uuid\"" },
                            { new StringContent(_user.CsrfToken), "\"_csrftoken\"" },
                            {
                                new StringContent("{\"lib_name\":\"jt\",\"lib_version\":\"1.3.0\",\"quality\":\"87\"}"),
                                "\"image_compression\""
                            },
                            { new StringContent("1"), "\"is_sidecar\"" }
                        };
                        byte[] fileBytes;
                        if (image.ImageBytes == null)
                        {
                            fileBytes = File.ReadAllBytes(image.Uri);
                        }
                        else
                        {
                            fileBytes = image.ImageBytes;
                        }
                        var imageContent = new ByteArrayContent(fileBytes);
                        imageContent.Headers.Add("Content-Transfer-Encoding", "binary");
                        imageContent.Headers.Add("Content-Type", "application/octet-stream");
                        var progressContent = new ProgressableStreamContent(imageContent, 4096, progress)
                        {
                            UploaderProgress = upProgress
                        };
                        requestContent.Add(progressContent, "photo",
                                           $"pending_media_{ApiRequestMessage.GenerateUploadId()}.jpg");

                        var request = _httpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo);
                        request.Content = requestContent;
                        var response = await _httpRequestProcessor.SendAsync(request);

                        var json = await response.Content.ReadAsStringAsync();

                        if (response.IsSuccessStatusCode)
                        {
                            upProgress             = progressContent?.UploaderProgress;
                            upProgress.UploadState = InstaUploadState.Uploaded;
                            progress?.Invoke(upProgress);
                            imagesUploadIds[index++] = uploadId;
                        }
                        else
                        {
                            upProgress.UploadState = InstaUploadState.Error;
                            progress?.Invoke(upProgress);
                            return(Result.UnExpectedResponse <InstaMedia>(response, json));
                        }
                    }
                }

                var videosDic = new Dictionary <string, InstaVideo>();
                var vidIndex  = 1;
                if (videos != null && videos.Any())
                {
                    foreach (var video in videos)
                    {
                        var instaUri = UriCreator.GetUploadVideoUri();
                        var uploadId = ApiRequestMessage.GenerateUploadId();
                        upProgress.UploadId = uploadId;
                        upProgress.Name     = $"[Album] Video uploading {vidIndex}/{videos.Length}";

                        var requestContent = new MultipartFormDataContent(uploadId)
                        {
                            { new StringContent("0"), "\"upload_media_height\"" },
                            { new StringContent("1"), "\"is_sidecar\"" },
                            { new StringContent("0"), "\"upload_media_width\"" },
                            { new StringContent(_user.CsrfToken), "\"_csrftoken\"" },
                            { new StringContent(_deviceInfo.DeviceGuid.ToString()), "\"_uuid\"" },
                            { new StringContent("0"), "\"upload_media_duration_ms\"" },
                            { new StringContent(uploadId), "\"upload_id\"" },
                            { new StringContent("{\"num_step_auto_retry\":0,\"num_reupload\":0,\"num_step_manual_retry\":0}"), "\"retry_context\"" },
                            { new StringContent("2"), "\"media_type\"" },
                        };

                        var request = _httpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo);
                        request.Content = requestContent;
                        var response = await _httpRequestProcessor.SendAsync(request);

                        var json = await response.Content.ReadAsStringAsync();

                        var videoResponse = JsonConvert.DeserializeObject <VideoUploadJobResponse>(json);
                        if (videoResponse == null)
                        {
                            upProgress.UploadState = InstaUploadState.Error;
                            progress?.Invoke(upProgress);
                            return(Result.Fail <InstaMedia>("Failed to get response from instagram video upload endpoint"));
                        }

                        byte[] videoBytes;
                        if (video.Video.VideoBytes == null)
                        {
                            videoBytes = File.ReadAllBytes(video.Video.Uri);
                        }
                        else
                        {
                            videoBytes = video.Video.VideoBytes;
                        }
                        var first = videoResponse.VideoUploadUrls[0];
                        instaUri = new Uri(Uri.EscapeUriString(first.Url));


                        requestContent = new MultipartFormDataContent(uploadId)
                        {
                            { new StringContent(_user.CsrfToken), "\"_csrftoken\"" },
                            {
                                new StringContent("{\"lib_name\":\"jt\",\"lib_version\":\"1.3.0\",\"quality\":\"87\"}"),
                                "\"image_compression\""
                            }
                        };
                        var videoContent = new ByteArrayContent(videoBytes);
                        videoContent.Headers.Add("Content-Transfer-Encoding", "binary");
                        videoContent.Headers.Add("Content-Type", "application/octet-stream");
                        videoContent.Headers.Add("Content-Disposition", $"attachment; filename=\"{Path.GetFileName(video.Video.Uri ?? $"C:\\{13.GenerateRandomString()}.mp4")}\"");
                        var progressContent = new ProgressableStreamContent(videoContent, 4096, progress)
                        {
                            UploaderProgress = upProgress
                        };
                        requestContent.Add(progressContent);
                        request              = _httpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo);
                        request.Content      = requestContent;
                        request.Headers.Host = "upload.instagram.com";
                        request.Headers.Add("Cookie2", "$Version=1");
                        request.Headers.Add("Session-ID", uploadId);
                        request.Headers.Add("job", first.Job);
                        response = await _httpRequestProcessor.SendAsync(request);

                        json = await response.Content.ReadAsStringAsync();

                        upProgress             = progressContent?.UploaderProgress;
                        upProgress.UploadState = InstaUploadState.UploadingThumbnail;
                        progress?.Invoke(upProgress);
                        instaUri       = UriCreator.GetUploadPhotoUri();
                        requestContent = new MultipartFormDataContent(uploadId)
                        {
                            { new StringContent("1"), "\"is_sidecar\"" },
                            { new StringContent(uploadId), "\"upload_id\"" },
                            { new StringContent(_deviceInfo.DeviceGuid.ToString()), "\"_uuid\"" },
                            { new StringContent(_user.CsrfToken), "\"_csrftoken\"" },
                            {
                                new StringContent("{\"lib_name\":\"jt\",\"lib_version\":\"1.3.0\",\"quality\":\"87\"}"),
                                "\"image_compression\""
                            },
                            { new StringContent("{\"num_step_auto_retry\":0,\"num_reupload\":0,\"num_step_manual_retry\":0}"), "\"retry_context\"" },
                            { new StringContent("2"), "\"media_type\"" },
                        };
                        byte[] imageBytes;
                        if (video.VideoThumbnail.ImageBytes == null)
                        {
                            imageBytes = File.ReadAllBytes(video.VideoThumbnail.Uri);
                        }
                        else
                        {
                            imageBytes = video.VideoThumbnail.ImageBytes;
                        }
                        var imageContent = new ByteArrayContent(imageBytes);
                        imageContent.Headers.Add("Content-Transfer-Encoding", "binary");
                        imageContent.Headers.Add("Content-Type", "application/octet-stream");
                        requestContent.Add(imageContent, "photo", $"cover_photo_{uploadId}.jpg");
                        request         = _httpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo);
                        request.Content = requestContent;
                        response        = await _httpRequestProcessor.SendAsync(request);

                        json = await response.Content.ReadAsStringAsync();

                        var imgResp = JsonConvert.DeserializeObject <ImageThumbnailResponse>(json);
                        videosDic.Add(uploadId, video.Video);

                        upProgress.UploadState = InstaUploadState.Uploaded;
                        progress?.Invoke(upProgress);
                        vidIndex++;
                    }
                }
                var config = await ConfigureAlbumAsync(progress, upProgress, imagesUploadIds, videosDic, caption, location);

                return(config);
            }
            catch (Exception exception)
            {
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                _logger?.LogException(exception);
                return(Result.Fail <InstaMedia>(exception));
            }
        }
        private async Task <IResult <InstaMedia> > ConfigureVideoAsync(Action <InstaUploaderProgress> progress, InstaUploaderProgress upProgress, InstaVideo video, string uploadId, string caption, InstaLocationShort location)
        {
            try
            {
                upProgress.UploadState = InstaUploadState.Configuring;
                progress?.Invoke(upProgress);
                var instaUri = UriCreator.GetMediaConfigureUri();
                var data     = new JObject
                {
                    { "caption", caption ?? string.Empty },
                    { "upload_id", uploadId },
                    { "source_type", "3" },
                    { "camera_position", "unknown" },
                    {
                        "extra", new JObject
                        {
                            { "source_width", 0 },
                            { "source_height", 0 }
                        }
                    },
                    {
                        "clips", new JArray {
                            new JObject
                            {
                                { "length", 0 },
                                { "creation_date", DateTime.Now.ToString("yyyy-dd-MMTh:mm:ss-0fff") },
                                { "source_type", "3" },
                                { "camera_position", "back" }
                            }
                        }
                    },
                    { "poster_frame_index", 0 },
                    { "audio_muted", false },
                    { "filter_type", "0" },
                    { "video_result", "" },
                    { "_csrftoken", _user.CsrfToken },
                    { "_uuid", _deviceInfo.DeviceGuid.ToString() },
                    { "_uid", _user.LoggedInUser.UserName }
                };
                if (location != null)
                {
                    data.Add("location", location.GetJson());
                    data.Add("date_time_digitalized", DateTime.Now.ToString("yyyy:dd:MM+h:mm:ss"));
                }
                var request = _httpHelper.GetSignedRequest(HttpMethod.Post, instaUri, _deviceInfo, data);
                request.Headers.Host = "i.instagram.com";
                var response = await _httpRequestProcessor.SendAsync(request);

                var json = await response.Content.ReadAsStringAsync();

                if (!response.IsSuccessStatusCode)
                {
                    upProgress.UploadState = InstaUploadState.Error;
                    progress?.Invoke(upProgress);
                    return(Result.UnExpectedResponse <InstaMedia>(response, json));
                }
                upProgress.UploadState = InstaUploadState.Configured;
                progress?.Invoke(upProgress);
                var success = await ExposeVideoAsync(uploadId, caption, location);

                if (success.Succeeded)
                {
                    upProgress.UploadState = InstaUploadState.Completed;
                    progress?.Invoke(upProgress);
                    return(success);
                }

                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                return(Result.Fail <InstaMedia>("Cannot expose media"));
            }
            catch (Exception exception)
            {
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                _logger?.LogException(exception);
                return(Result.Fail <InstaMedia>(exception));
            }
        }
        private async Task <IResult <bool> > UploadVideoThumbnailAsync(Action <InstaUploaderProgress> progress, InstaUploaderProgress upProgress, InstaImage image, string uploadId)
        {
            try
            {
                var instaUri = UriCreator.GetUploadPhotoUri();
                upProgress.UploadState = InstaUploadState.UploadingThumbnail;
                progress?.Invoke(upProgress);
                var requestContent = new MultipartFormDataContent(uploadId)
                {
                    { new StringContent(uploadId), "\"upload_id\"" },
                    { new StringContent(_deviceInfo.DeviceGuid.ToString()), "\"_uuid\"" },
                    { new StringContent(_user.CsrfToken), "\"_csrftoken\"" },
                    {
                        new StringContent("{\"lib_name\":\"jt\",\"lib_version\":\"1.3.0\",\"quality\":\"87\"}"),
                        "\"image_compression\""
                    }
                };
                byte[] fileBytes;
                if (image.ImageBytes == null)
                {
                    fileBytes = File.ReadAllBytes(image.Uri);
                }
                else
                {
                    fileBytes = image.ImageBytes;
                }

                var imageContent = new ByteArrayContent(fileBytes);
                imageContent.Headers.Add("Content-Transfer-Encoding", "binary");
                imageContent.Headers.Add("Content-Type", "application/octet-stream");
                requestContent.Add(imageContent, "photo", $"pending_media_{uploadId}.jpg");
                var request = _httpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo);
                request.Content = requestContent;
                var response = await _httpRequestProcessor.SendAsync(request);

                var json = await response.Content.ReadAsStringAsync();

                var imgResp = JsonConvert.DeserializeObject <ImageThumbnailResponse>(json);
                if (imgResp.Status.ToLower() == "ok")
                {
                    upProgress.UploadState = InstaUploadState.ThumbnailUploaded;
                    progress?.Invoke(upProgress);
                    return(Result.Success(true));
                }

                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                return(Result.Fail <bool>("Could not upload thumbnail"));
            }
            catch (Exception exception)
            {
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                _logger?.LogException(exception);
                return(Result.Fail <bool>(exception));
            }
        }
        /// <summary>
        ///     Upload video with progress
        /// </summary>
        /// <param name="progress">Progress action</param>
        /// <param name="video">Video and thumbnail to upload</param>
        /// <param name="caption">Caption</param>
        /// <param name="location">Location => Optional (get it from <seealso cref="LocationProcessor.SearchLocationAsync"/></param>
        public async Task <IResult <InstaMedia> > UploadVideoAsync(Action <InstaUploaderProgress> progress, InstaVideoUpload video, string caption, InstaLocationShort location = null)
        {
            UserAuthValidator.Validate(_userAuthValidate);
            var upProgress = new InstaUploaderProgress
            {
                Caption     = caption ?? string.Empty,
                UploadState = InstaUploadState.Preparing
            };

            try
            {
                var instaUri = UriCreator.GetUploadVideoUri();
                var uploadId = ApiRequestMessage.GenerateUploadId();
                upProgress.UploadId = uploadId;
                progress?.Invoke(upProgress);
                var requestContent = new MultipartFormDataContent(uploadId)
                {
                    { new StringContent("2"), "\"media_type\"" },
                    { new StringContent(uploadId), "\"upload_id\"" },
                    { new StringContent(_deviceInfo.DeviceGuid.ToString()), "\"_uuid\"" },
                    { new StringContent(_user.CsrfToken), "\"_csrftoken\"" },
                    {
                        new StringContent("{\"lib_name\":\"jt\",\"lib_version\":\"1.3.0\",\"quality\":\"87\"}"),
                        "\"image_compression\""
                    }
                };

                var request = _httpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo);
                request.Content = requestContent;
                var response = await _httpRequestProcessor.SendAsync(request);

                var json = await response.Content.ReadAsStringAsync();

                var videoResponse = JsonConvert.DeserializeObject <VideoUploadJobResponse>(json);
                if (videoResponse == null)
                {
                    upProgress.UploadState = InstaUploadState.Error;
                    progress?.Invoke(upProgress);
                    return(Result.Fail <InstaMedia>("Failed to get response from instagram video upload endpoint"));
                }

                byte[] fileBytes;
                if (video.Video.VideoBytes == null)
                {
                    fileBytes = File.ReadAllBytes(video.Video.Uri);
                }
                else
                {
                    fileBytes = video.Video.VideoBytes;
                }
                var first = videoResponse.VideoUploadUrls[0];
                instaUri = new Uri(Uri.EscapeUriString(first.Url));


                requestContent = new MultipartFormDataContent(uploadId)
                {
                    { new StringContent(_user.CsrfToken), "\"_csrftoken\"" },
                    {
                        new StringContent("{\"lib_name\":\"jt\",\"lib_version\":\"1.3.0\",\"quality\":\"87\"}"),
                        "\"image_compression\""
                    }
                };


                var videoContent = new ByteArrayContent(fileBytes);
                videoContent.Headers.Add("Content-Transfer-Encoding", "binary");
                videoContent.Headers.Add("Content-Type", "application/octet-stream");
                videoContent.Headers.Add("Content-Disposition", $"attachment; filename=\"{Path.GetFileName(video.Video.Uri ?? $"C:\\{13.GenerateRandomString()}.mp4")}\"");
                var progressContent = new ProgressableStreamContent(videoContent, 4096, progress)
                {
                    UploaderProgress = upProgress
                };
                requestContent.Add(progressContent);
                request              = _httpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo);
                request.Content      = requestContent;
                request.Headers.Host = "upload.instagram.com";
                request.Headers.Add("Cookie2", "$Version=1");
                request.Headers.Add("Session-ID", uploadId);
                request.Headers.Add("job", first.Job);
                response = await _httpRequestProcessor.SendAsync(request);

                json = await response.Content.ReadAsStringAsync();

                upProgress = progressContent.UploaderProgress;
                await UploadVideoThumbnailAsync(progress, upProgress, video.VideoThumbnail, uploadId);

                return(await ConfigureVideoAsync(progress, upProgress, video.Video, uploadId, caption, location));
            }
            catch (Exception exception)
            {
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                _logger?.LogException(exception);
                return(Result.Fail <InstaMedia>(exception));
            }
        }
        private async Task <IResult <bool> > SendDirectPhoto(Action <InstaUploaderProgress> progress, string recipients, string threadId, InstaImage image)
        {
            var upProgress = new InstaUploaderProgress
            {
                Caption     = string.Empty,
                UploadState = InstaUploadState.Preparing
            };

            try
            {
                var instaUri      = UriCreator.GetDirectSendPhotoUri();
                var uploadId      = ApiRequestMessage.GenerateRandomUploadId();
                var clientContext = Guid.NewGuid();
                upProgress.UploadId = uploadId;
                progress?.Invoke(upProgress);
                var requestContent = new MultipartFormDataContent(uploadId)
                {
                    { new StringContent("send_item"), "\"action\"" },
                    { new StringContent(clientContext.ToString()), "\"client_context\"" },
                    { new StringContent(_user.CsrfToken), "\"_csrftoken\"" },
                    { new StringContent(_deviceInfo.DeviceGuid.ToString()), "\"_uuid\"" }
                };
                if (!string.IsNullOrEmpty(recipients))
                {
                    requestContent.Add(new StringContent($"[[{recipients}]]"), "recipient_users");
                }
                else
                {
                    requestContent.Add(new StringContent($"[{threadId}]"), "thread_ids");
                }
                byte[] fileBytes;
                if (image.ImageBytes == null)
                {
                    fileBytes = File.ReadAllBytes(image.Uri);
                }
                else
                {
                    fileBytes = image.ImageBytes;
                }
                var imageContent = new ByteArrayContent(fileBytes);
                imageContent.Headers.Add("Content-Transfer-Encoding", "binary");
                imageContent.Headers.Add("Content-Type", "application/octet-stream");
                var progressContent = new ProgressableStreamContent(imageContent, 4096, progress)
                {
                    UploaderProgress = upProgress
                };
                requestContent.Add(progressContent, "photo",
                                   $"direct_temp_photo_{ApiRequestMessage.GenerateUploadId()}.jpg");
                var request = _httpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo);
                request.Content = requestContent;
                var response = await _httpRequestProcessor.SendAsync(request);

                var json = await response.Content.ReadAsStringAsync();

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    upProgress.UploadState = InstaUploadState.Error;
                    progress?.Invoke(upProgress);
                    return(Result.UnExpectedResponse <bool>(response, json));
                }

                var obj = JsonConvert.DeserializeObject <InstaDefault>(json);
                if (obj.Status.ToLower() == "ok")
                {
                    upProgress.UploadState = InstaUploadState.Completed;
                    progress?.Invoke(upProgress);
                    return(Result.Success(true));
                }

                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                return(Result.UnExpectedResponse <bool>(response, json));
            }
            catch (Exception exception)
            {
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                _logger?.LogException(exception);
                return(Result.Fail <bool>(exception));
            }
        }