/// <summary> /// Send link address to direct thread /// </summary> /// <param name="text">Text to send</param> /// <param name="link">Link to send</param> /// <param name="threadIds">Thread ids</param> /// <param name="recipients">Recipients ids</param> private async Task <Result <ItemAckPayloadResponse> > SendDirectLink(string text, IEnumerable <string> link, string[] threadIds, long[] recipients) { ValidateLoggedIn(); try { var instaUri = UriCreator.GetSendDirectLinkUri(); var clientContext = Guid.NewGuid().ToString(); var data = new Dictionary <string, string> { { "link_text", text ?? string.Empty }, { "link_urls", JsonConvert.SerializeObject(link, Formatting.None) }, { "action", "send_item" }, { "client_context", clientContext }, { "_csrftoken", Session.CsrfToken }, { "_uuid", Device.Uuid.ToString() } }; if (threadIds?.Length > 0) { data.Add("thread_ids", JsonConvert.SerializeObject(threadIds, Formatting.None)); } if (recipients?.Length > 0) { var recipientString = string.Join(",", recipients); data.Add("recipient_users", $"[[{recipientString}]]"); } var response = await _httpClient.PostAsync(instaUri, new HttpFormUrlEncodedContent(data)); var json = await response.Content.ReadAsStringAsync(); _logger?.LogResponse(response); if (response.StatusCode != HttpStatusCode.Ok) { return(Result <ItemAckPayloadResponse> .Fail(json, response.ReasonPhrase)); } var obj = JsonConvert.DeserializeObject <ItemAckResponse>(json); return(obj.IsOk() ? Result <ItemAckPayloadResponse> .Success(obj.Payload, json, obj.Message) : Result <ItemAckPayloadResponse> .Fail(json, obj.Message)); } catch (Exception exception) { _logger?.LogException(exception); return(Result <ItemAckPayloadResponse> .Except(exception)); } }
public async Task <Result <ItemAckPayloadResponse> > SendReelReactAsync(long reelId, string mediaId, string threadId, string text) { ValidateLoggedIn(); try { var uri = UriCreator.GetDirectReelReactUri(); var clientContext = Guid.NewGuid().ToString(); var jsonObject = new JObject { { "action", "send_item" }, { "client_context", clientContext }, { "mutation_token", clientContext }, { "reel_id", reelId.ToString() }, { "media_id", mediaId }, { "thread_ids", $"[{threadId}]" }, { "text", text }, { "reaction_emoji", text }, { "entry", "reel" }, { "device_id", Device.DeviceId }, { "_csrftoken", Session.CsrfToken }, { "_uuid", Device.Uuid.ToString() }, { "_uid", Session.LoggedInUser.Pk.ToString() } }; var signature = $"SIGNATURE.{jsonObject.ToString(Formatting.None)}"; var data = new Dictionary <string, string> { { "signed_body", signature } }; var response = await _httpClient.PostAsync(uri, new HttpFormUrlEncodedContent(data)); var json = await response.Content.ReadAsStringAsync(); DebugLogger.LogResponse(response); if (response.StatusCode != HttpStatusCode.Ok) { return(Result <ItemAckPayloadResponse> .Fail(json, response.ReasonPhrase)); } var obj = JsonConvert.DeserializeObject <ItemAckResponse>(json); return(obj.IsOk() ? Result <ItemAckPayloadResponse> .Success(obj.Payload, json, obj.Message) : Result <ItemAckPayloadResponse> .Fail(json, obj.Message)); } catch (Exception exception) { DebugLogger.LogException(exception); return(Result <ItemAckPayloadResponse> .Except(exception)); } }
public async Task <Result <Dictionary <long, Reel> > > GetReels(ICollection <long> userIds) { ValidateLoggedIn(); try { if (userIds == null || userIds.Count == 0) { throw new ArgumentException("user ids is empty", nameof(userIds)); } var uri = UriCreator.GetReelsMediaUri(); var data = new JObject { { "supported_capabilities_new", ReelsCapabilities }, { "source", "reel_feed_timeline" }, { "_csrftoken", Session.CsrfToken }, { "_uid", Session.LoggedInUser.Pk.ToString() }, { "_uuid", Device.Uuid.ToString() }, { "user_ids", new JArray(userIds.Select(x => x.ToString()).ToArray()) } }; var body = new Dictionary <string, string> { { "signed_body", $"SIGNATURE.{data.ToString(Formatting.None)}" } }; var response = await _httpClient.PostAsync(uri, new HttpFormUrlEncodedContent(body)); var json = await response.Content.ReadAsStringAsync(); DebugLogger.LogResponse(response); if (response.StatusCode != HttpStatusCode.Ok) { return(Result <Dictionary <long, Reel> > .Fail(json, response.ReasonPhrase)); } var payload = JsonConvert.DeserializeObject <JObject>(json); if (payload["status"]?.ToString() != "ok") { return(Result <Dictionary <long, Reel> > .Fail(json)); } var reels = payload["reels"].ToObject <Dictionary <long, Reel> >(); return(Result <Dictionary <long, Reel> > .Success(reels, json)); } catch (Exception e) { DebugLogger.LogException(e); return(Result <Dictionary <long, Reel> > .Except(e)); } }
public async Task <Result <GiphyMedia[]> > SearchAnimatedImageAsync(string query, AnimatedImageType type) { ValidateLoggedIn(); try { string typeString; switch (type) { case AnimatedImageType.Sticker: typeString = "giphy"; break; case AnimatedImageType.Gif: typeString = "giphy_gifs"; break; default: typeString = "giphy"; break; } var uri = UriCreator.GetAnimatedImageSearchUri(query, typeString); var response = await _httpClient.GetAsync(uri); var json = await response.Content.ReadAsStringAsync(); DebugLogger.LogResponse(response); if (!response.IsSuccessStatusCode) { return(Result <GiphyMedia[]> .Fail(json, response.ReasonPhrase)); } var obj = JsonConvert.DeserializeObject <JObject>(json); if (obj["status"]?.ToString() != "ok" || !obj.ContainsKey("results")) { return(Result <GiphyMedia[]> .Fail(json)); } var giphyResults = obj["results"]?[typeString]?.ToObject <GiphyMedia[]>(); return(Result <GiphyMedia[]> .Success(giphyResults, json)); } catch (Exception exception) { DebugLogger.LogException(exception); return(Result <GiphyMedia[]> .Except(exception)); } }
/// <summary> /// UnLike direct message in a thread /// </summary> /// <param name="threadId">Thread id</param> /// <param name="itemId">Item id (message id)</param> public async Task <Result <ItemAckResponse> > UnlikeItemAsync(string threadId, string itemId) { ValidateLoggedIn(); try { var instaUri = UriCreator.GetLikeUnlikeDirectMessageUri(); var data = new Dictionary <string, string> { { "item_type", "reaction" }, { "reaction_type", "like" }, { "action", "send_item" }, { "_csrftoken", Session.CsrfToken }, { "_uuid", Device.Uuid.ToString() }, { "thread_ids", $"[{threadId}]" }, { "client_context", Guid.NewGuid().ToString() }, { "node_type", "item" }, { "reaction_status", "deleted" }, { "item_id", itemId } }; var response = await _httpClient.PostAsync(instaUri, new HttpFormUrlEncodedContent(data)); var json = await response.Content.ReadAsStringAsync(); _logger?.LogResponse(response); if (response.StatusCode != HttpStatusCode.Ok) { return(Result <ItemAckResponse> .Fail(json, response.ReasonPhrase)); } var obj = JsonConvert.DeserializeObject <ItemAckResponse>(json); return(obj.IsOk() ? Result <ItemAckResponse> .Success(obj, json, obj.Message) : Result <ItemAckResponse> .Fail(json, obj.Message)); } catch (Exception exception) { _logger?.LogException(exception); return(Result <ItemAckResponse> .Except(exception)); } }
public async Task <Result <DirectThread[]> > SendAnimatedImageAsync(string mediaId, bool isSticker, string threadId) { ValidateLoggedIn(); try { var uri = UriCreator.GetSendAnimatedImageUri(); var clientContext = Guid.NewGuid().ToString(); var data = new Dictionary <string, string> { { "thread_ids", $"[{threadId}]" }, { "client_context", clientContext }, { "is_sticker", isSticker.ToString().ToLower() }, { "_csrftoken", Session.CsrfToken }, { "id", mediaId }, { "device_id", Device.DeviceId }, { "mutation_token", clientContext }, { "_uuid", Device.Uuid.ToString() }, }; var response = await _httpClient.PostAsync(uri, new HttpFormUrlEncodedContent(data)); var json = await response.Content.ReadAsStringAsync(); DebugLogger.LogResponse(response); if (!response.IsSuccessStatusCode) { return(Result <DirectThread[]> .Fail(json, response.ReasonPhrase)); } var obj = JsonConvert.DeserializeObject <ItemAddedResponse>(json); return(obj.IsOk() ? Result <DirectThread[]> .Success(obj.Threads, json) : Result <DirectThread[]> .Fail(json)); } catch (Exception exception) { DebugLogger.LogException(exception); return(Result <DirectThread[]> .Except(exception)); } }
/// <summary> /// Mark direct message as seen /// </summary> /// <param name="threadId">Thread id</param> /// <param name="itemId">Message id (item id)</param> public async Task <Result <bool> > MarkItemSeenAsync(string threadId, string itemId) { ValidateLoggedIn(); try { var instaUri = UriCreator.GetDirectThreadSeenUri(threadId, itemId); var data = new Dictionary <string, string> { { "thread_id", threadId }, { "action", "mark_seen" }, { "_csrftoken", Session.CsrfToken }, { "_uuid", Device.Uuid.ToString() }, { "item_id", itemId }, { "use_unified_inbox", "true" }, }; var response = await _httpClient.PostAsync(instaUri, new HttpFormUrlEncodedContent(data)); var json = await response.Content.ReadAsStringAsync(); _logger?.LogResponse(response); if (response.StatusCode != HttpStatusCode.Ok) { return(Result <bool> .Fail(json, response.ReasonPhrase)); } var obj = JsonConvert.DeserializeObject <DefaultResponse>(json); return(obj.IsOk() ? Result <bool> .Success(true, json, obj.Message) : Result <bool> .Fail(json, obj.Message)); } catch (Exception exception) { _logger?.LogException(exception); return(Result <bool> .Except(exception)); } }
private async Task <Result <InboxContainer> > GetDirectInbox(string maxId = null) { try { var directInboxUri = UriCreator.GetDirectInboxUri(maxId); var response = await _httpClient.GetAsync(directInboxUri); var json = await response.Content.ReadAsStringAsync(); _logger?.LogResponse(response); if (response.StatusCode != HttpStatusCode.Ok) { return(Result <InboxContainer> .Fail(json, response.ReasonPhrase)); } var inbox = JsonConvert.DeserializeObject <InboxContainer>(json); return(Result <InboxContainer> .Success(inbox)); } catch (Exception exception) { _logger?.LogException(exception); return(Result <InboxContainer> .Except(exception)); } }
public async Task <Result <UserPresenceResponse> > GetPresence() { ValidateLoggedIn(); try { var instaUri = UriCreator.GetDirectUserPresenceUri(); var response = await _httpClient.GetAsync(instaUri); var json = await response.Content.ReadAsStringAsync(); DebugLogger.LogResponse(response); if (response.StatusCode != HttpStatusCode.Ok) { return(Result <UserPresenceResponse> .Fail(json, response.ReasonPhrase)); } var obj = JsonConvert.DeserializeObject <UserPresenceResponse>(json); return(obj.IsOk() ? Result <UserPresenceResponse> .Success(obj, json) : Result <UserPresenceResponse> .Fail(json)); } catch (Exception exception) { DebugLogger.LogException(exception); return(Result <UserPresenceResponse> .Except(exception)); } }
private async Task <Result <bool> > ConfigureVideo(Action <UploaderProgress> progress, UploaderProgress upProgress, string uploadId, bool isDirectVideo, bool isDisappearingVideo, string caption, VisualMediaViewMode viewMode, InstaStoryType storyType, string recipients, string threadId, Uri uri, StoryUploadOptions uploadOptions = null) { try { upProgress.UploadState = InstaUploadState.Configuring; progress?.Invoke(upProgress); var instaUri = UriCreator.GetDirectConfigVideoUri(); var retryContext = GetRetryContext(); var clientContext = Guid.NewGuid().ToString(); if (isDirectVideo) { var data = new Dictionary <string, string> { { "action", "send_item" }, { "client_context", clientContext }, { "_csrftoken", Session.CsrfToken }, { "video_result", "" }, { "_uuid", Device.Uuid.ToString() }, { "upload_id", uploadId } }; if (!string.IsNullOrEmpty(recipients)) { data.Add("recipient_users", $"[[{recipients}]]"); } else { data.Add("thread_ids", $"[{threadId}]"); } instaUri = UriCreator.GetDirectConfigVideoUri(); var request = new HttpRequestMessage(HttpMethod.Post, instaUri); request.Content = new HttpFormUrlEncodedContent(data); request.Headers.Add("retry_context", retryContext); var response = await _httpClient.SendRequestAsync(request); var json = await response.Content.ReadAsStringAsync(); DebugLogger.LogResponse(response); if (response.StatusCode != HttpStatusCode.Ok) { upProgress.UploadState = InstaUploadState.Error; progress?.Invoke(upProgress); return(Result <bool> .Fail(json, response.ReasonPhrase)); } var obj = JsonConvert.DeserializeObject <DefaultResponse>(json); if (obj.Status.ToLower() == "ok") { upProgress.UploadState = InstaUploadState.Configured; progress?.Invoke(upProgress); } else { upProgress.UploadState = InstaUploadState.Completed; progress?.Invoke(upProgress); } return(obj.IsOk() ? Result <bool> .Success(true, json, obj.Message) : Result <bool> .Fail(json, obj.Message)); } else { var rnd = new Random(); var data = new JObject { { "filter_type", "0" }, { "timezone_offset", "16200" }, { "_csrftoken", Session.CsrfToken }, { "client_shared_at", (DateTimeOffset.UtcNow.ToUnixTimeSeconds() - rnd.Next(25, 55)).ToString() }, { "story_media_creation_date", (DateTimeOffset.UtcNow.ToUnixTimeSeconds() - rnd.Next(50, 70)).ToString() }, { "media_folder", "Camera" }, { "source_type", "4" }, { "video_result", "" }, { "_uid", Session.LoggedInUser.Pk.ToString() }, { "_uuid", Device.Uuid.ToString() }, { "caption", caption ?? string.Empty }, { "date_time_original", DateTimeOffset.Now.ToString("yyyy-dd-MMTh:mm:ss-0fffZ") }, { "capture_type", "normal" }, { "mas_opt_in", "NOT_PROMPTED" }, { "upload_id", uploadId }, { "client_timestamp", DateTimeOffset.UtcNow.ToUnixTimeSeconds() }, { "device", new JObject { { "manufacturer", Device.HardwareManufacturer }, { "model", Device.HardwareModel }, { "android_release", Device.AndroidVersion.VersionNumber }, { "android_version", Device.AndroidVersion.APILevel } } }, { "length", 0 }, { "extra", new JObject { { "source_width", 0 }, { "source_height", 0 } } }, { "audio_muted", false }, { "poster_frame_index", 0 }, }; if (isDisappearingVideo) { data.Add("view_mode", viewMode.ToString().ToLower()); data.Add("configure_mode", "2"); data.Add("recipient_users", "[]"); data.Add("thread_ids", $"[{threadId}]"); } else { switch (storyType) { case InstaStoryType.SelfStory: default: data.Add("configure_mode", "1"); break; case InstaStoryType.Direct: data.Add("configure_mode", "2"); data.Add("view_mode", "replayable"); data.Add("recipient_users", "[]"); data.Add("thread_ids", $"[{threadId}]"); break; case InstaStoryType.Both: data.Add("configure_mode", "3"); data.Add("view_mode", "replayable"); data.Add("recipient_users", "[]"); data.Add("thread_ids", $"[{threadId}]"); break; } if (uri != null) { var webUri = new JArray { new JObject { { "webUri", uri.ToString() } } }; var storyCta = new JArray { new JObject { { "links", webUri } } }; data.Add("story_cta", storyCta.ToString(Formatting.None)); } if (uploadOptions != null) { if (uploadOptions.Hashtags?.Count > 0) { var hashtagArr = new JArray(); foreach (var item in uploadOptions.Hashtags) { hashtagArr.Add(item.ToJson()); } data.Add("story_hashtags", hashtagArr.ToString(Formatting.None)); } if (uploadOptions.Locations?.Count > 0) { var locationArr = new JArray(); foreach (var item in uploadOptions.Locations) { locationArr.Add(item.ToJson()); } data.Add("story_locations", locationArr.ToString(Formatting.None)); } if (uploadOptions.Slider != null) { var sliderArr = new JArray { uploadOptions.Slider.ToJson() }; data.Add("story_sliders", sliderArr.ToString(Formatting.None)); if (uploadOptions.Slider.IsSticker) { data.Add("story_sticker_ids", $"emoji_slider_{uploadOptions.Slider.Emoji}"); } } else { if (uploadOptions.Polls?.Count > 0) { var pollArr = new JArray(); foreach (var item in uploadOptions.Polls) { pollArr.Add(item.ToJson()); } data.Add("story_polls", pollArr.ToString(Formatting.None)); } if (uploadOptions.Questions?.Count > 0) { var questionArr = new JArray(); foreach (var item in uploadOptions.Questions) { questionArr.Add(item.ToJson()); } data.Add("story_questions", questionArr.ToString(Formatting.None)); } } if (uploadOptions.Countdown != null) { var countdownArr = new JArray { uploadOptions.Countdown.ToJson() }; data.Add("story_countdowns", countdownArr.ToString(Formatting.None)); data.Add("story_sticker_ids", "countdown_sticker_time"); } } } instaUri = UriCreator.GetVideoStoryConfigureUri(true); var request = GetSignedRequest(instaUri, data); request.Headers.Add("retry_context", retryContext); var response = await _httpClient.SendRequestAsync(request); var json = await response.Content.ReadAsStringAsync(); DebugLogger.LogResponse(response); if (response.IsSuccessStatusCode) { var mediaResponse = JsonConvert.DeserializeObject <DefaultResponse>(json); if (mediaResponse.IsOk()) { upProgress.UploadState = InstaUploadState.Configured; progress?.Invoke(upProgress); } else { upProgress.UploadState = InstaUploadState.Completed; progress?.Invoke(upProgress); } return(mediaResponse.IsOk() ? Result <bool> .Success(true) : Result <bool> .Fail(json, mediaResponse.Message)); } upProgress.UploadState = InstaUploadState.Error; progress?.Invoke(upProgress); return(Result <bool> .Fail(json, response.ReasonPhrase)); } } catch (Exception exception) { upProgress.UploadState = InstaUploadState.Error; progress?.Invoke(upProgress); DebugLogger.LogException(exception); return(Result <bool> .Except(exception)); } }
public async Task <Result <ItemAckPayloadResponse> > SendDirectPhotoAsync(InstaImage image, string threadId, long uploadId, Action <UploaderProgress> progress = null) { var upProgress = new UploaderProgress { Caption = string.Empty, UploadState = InstaUploadState.Preparing }; try { var entityName = "direct_" + uploadId; var uri = UriCreator.GetDirectSendPhotoUri(entityName); upProgress.UploadId = uploadId.ToString(); progress?.Invoke(upProgress); var ruploadParams = new JObject( new JProperty("media_type", 1), new JProperty("upload_id", uploadId.ToString()), new JProperty("upload_media_height", image.Height), new JProperty("upload_media_width", image.Width)); var requestMessage = new HttpRequestMessage(HttpMethod.Post, uri); requestMessage.Headers.Add("X-Entity-Name", entityName); requestMessage.Headers.Add("X-Instagram-Rupload-Params", ruploadParams.ToString(Formatting.None)); requestMessage.Headers.Add("Offset", "0"); var uploadBuffer = image.UploadBuffer; var content = new HttpBufferContent(uploadBuffer); content.Headers.ContentType = HttpMediaTypeHeaderValue.Parse("image/jpeg"); requestMessage.Headers.Add("X-Entity-Length", uploadBuffer.Length.ToString()); requestMessage.Content = content; upProgress.UploadState = InstaUploadState.Uploading; progress?.Invoke(upProgress); var response = await _httpClient.SendRequestAsync(requestMessage); var json = await response.Content.ReadAsStringAsync(); DebugLogger.LogResponse(response); var ruploadResp = JsonConvert.DeserializeObject <RuploadResponse>(json); if (response.StatusCode != HttpStatusCode.Ok || !ruploadResp.IsOk()) { upProgress.UploadState = InstaUploadState.Error; progress?.Invoke(upProgress); return(Result <ItemAckPayloadResponse> .Fail(json)); } var uploadIdResp = ruploadResp.UploadId; upProgress.UploadState = InstaUploadState.Uploaded; progress?.Invoke(upProgress); var configUri = UriCreator.GetDirectConfigPhotoUri(); var config = new Dictionary <string, string>(7) { ["action"] = "send_item", ["allow_full_aspect_ratio"] = "1", ["content_type"] = "photo", ["mutation_token"] = Guid.NewGuid().ToString(), ["sampled"] = "1", ["thread_id"] = threadId, ["upload_id"] = uploadIdResp }; response = await _httpClient.PostAsync(configUri, new HttpFormUrlEncodedContent(config)); json = await response.Content.ReadAsStringAsync(); DebugLogger.LogResponse(response); var obj = JsonConvert.DeserializeObject <ItemAckResponse>(json); if (response.StatusCode != HttpStatusCode.Ok || !obj.IsOk()) { upProgress.UploadState = InstaUploadState.Error; progress?.Invoke(upProgress); return(Result <ItemAckPayloadResponse> .Fail(json, obj.Message)); } upProgress.UploadState = InstaUploadState.Completed; progress?.Invoke(upProgress); return(Result <ItemAckPayloadResponse> .Success(obj.Payload, json, obj.Message)); } catch (Exception exception) { upProgress.UploadState = InstaUploadState.Error; progress?.Invoke(upProgress); DebugLogger.LogException(exception); return(Result <ItemAckPayloadResponse> .Except(exception)); } }
/// <summary> /// Send video story, direct video, disappearing video /// </summary> /// <param name="isDirectVideo">Direct video</param> /// <param name="isDisappearingVideo">Disappearing video</param> private async Task <Result <bool> > SendVideoAsync(Action <UploaderProgress> progress, bool isDirectVideo, bool isDisappearingVideo, string caption, VisualMediaViewMode viewMode, InstaStoryType storyType, string recipients, string threadId, InstaVideoUpload video, Uri uri = null, StoryUploadOptions uploadOptions = null) { var upProgress = new UploaderProgress { Caption = caption ?? string.Empty, UploadState = InstaUploadState.Preparing }; try { var uploadId = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(); var videoHashCode = video.Video.Url?.GetHashCode() ?? $"C:\\{GenerateRandomString(13)}.mp4".GetHashCode(); var waterfallId = Guid.NewGuid().ToString(); var videoEntityName = $"{uploadId}_0_{videoHashCode}"; var videoUri = UriCreator.GetStoryUploadVideoUri(uploadId, videoHashCode); var retryContext = GetRetryContext(); HttpRequestMessage request; HttpResponseMessage response; string videoUploadParams = null; string json = null; upProgress.UploadId = uploadId; progress?.Invoke(upProgress); var videoUploadParamsObj = new JObject(); if (isDirectVideo) { videoUploadParamsObj = new JObject { { "upload_media_height", "0" }, { "direct_v2", "1" }, { "upload_media_width", "0" }, { "upload_media_duration_ms", "0" }, { "upload_id", uploadId }, { "retry_context", retryContext }, { "media_type", "2" } }; videoUploadParams = JsonConvert.SerializeObject(videoUploadParamsObj); request = new HttpRequestMessage(HttpMethod.Get, videoUri); request.Headers.Add("X_FB_VIDEO_WATERFALL_ID", waterfallId); request.Headers.Add("X-Instagram-Rupload-Params", videoUploadParams); response = await _httpClient.SendRequestAsync(request); json = await response.Content.ReadAsStringAsync(); DebugLogger.LogResponse(response); if (response.StatusCode != HttpStatusCode.Ok) { upProgress.UploadState = InstaUploadState.Error; progress?.Invoke(upProgress); return(Result <bool> .Fail(json, response.ReasonPhrase)); } } else { videoUploadParamsObj = new JObject { { "_csrftoken", Session.CsrfToken }, { "_uid", Session.LoggedInUser.Pk }, { "_uuid", Device.Uuid.ToString() }, { "media_info", new JObject { { "capture_mode", "normal" }, { "media_type", 2 }, { "caption", caption ?? string.Empty }, { "mentions", new JArray() }, { "hashtags", new JArray() }, { "locations", new JArray() }, { "stickers", new JArray() }, } } }; request = GetSignedRequest(UriCreator.GetStoryMediaInfoUploadUri(), videoUploadParamsObj); response = await _httpClient.SendRequestAsync(request); json = await response.Content.ReadAsStringAsync(); DebugLogger.LogResponse(response); videoUploadParamsObj = new JObject { { "upload_media_height", "0" }, { "upload_media_width", "0" }, { "upload_media_duration_ms", "0" }, { "upload_id", uploadId }, { "retry_context", "{\"num_step_auto_retry\":0,\"num_reupload\":0,\"num_step_manual_retry\":0}" }, { "media_type", "2" } }; if (isDisappearingVideo) { videoUploadParamsObj.Add("for_direct_story", "1"); } else { switch (storyType) { case InstaStoryType.SelfStory: default: videoUploadParamsObj.Add("for_album", "1"); break; case InstaStoryType.Direct: videoUploadParamsObj.Add("for_direct_story", "1"); break; case InstaStoryType.Both: videoUploadParamsObj.Add("for_album", "1"); videoUploadParamsObj.Add("for_direct_story", "1"); break; } } videoUploadParams = JsonConvert.SerializeObject(videoUploadParamsObj); request = new HttpRequestMessage(Windows.Web.Http.HttpMethod.Get, videoUri); request.Headers.Add("X_FB_VIDEO_WATERFALL_ID", waterfallId); request.Headers.Add("X-Instagram-Rupload-Params", videoUploadParams); response = await _httpClient.SendRequestAsync(request); json = await response.Content.ReadAsStringAsync(); DebugLogger.LogResponse(response); if (response.StatusCode != HttpStatusCode.Ok) { upProgress.UploadState = InstaUploadState.Error; progress?.Invoke(upProgress); return(Result <bool> .Fail(json, response.ReasonPhrase)); } } // video part IBuffer videoUploadBuffer; if (video.Video.UploadBuffer == null) { if (video.Video.Url == null) { throw new NullReferenceException("No upload buffer or file path are provided for video upload."); } var videoFile = await StorageFile.GetFileFromPathAsync(video.Video.Url.AbsolutePath); videoUploadBuffer = await FileIO.ReadBufferAsync(videoFile); } else { videoUploadBuffer = video.Video.UploadBuffer; } var videoContent = new HttpBufferContent(videoUploadBuffer); request = new HttpRequestMessage(Windows.Web.Http.HttpMethod.Post, videoUri) { Content = videoContent }; upProgress.UploadState = InstaUploadState.Uploading; progress?.Invoke(upProgress); var vidExt = Path.GetExtension(video.Video.Url?.AbsolutePath ?? $"C:\\{GenerateRandomString(13)}.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", videoUploadBuffer.Length.ToString()); request.Headers.Add("X_FB_VIDEO_WATERFALL_ID", waterfallId); response = await _httpClient.SendRequestAsync(request); json = await response.Content.ReadAsStringAsync(); if (response.StatusCode != HttpStatusCode.Ok) { upProgress.UploadState = InstaUploadState.Error; progress?.Invoke(upProgress); return(Result <bool> .Fail(json, response.ReasonPhrase)); } upProgress.UploadState = InstaUploadState.Uploaded; progress?.Invoke(upProgress); //upProgress = progressContent?.UploaderProgress; if (!isDirectVideo) { upProgress.UploadState = InstaUploadState.UploadingThumbnail; progress?.Invoke(upProgress); var photoHashCode = video.VideoThumbnail.Url?.GetHashCode() ?? $"C:\\{GenerateRandomString(13)}.jpg".GetHashCode(); var photoEntityName = $"{uploadId}_0_{photoHashCode}"; var photoUri = UriCreator.GetStoryUploadPhotoUri(uploadId, photoHashCode); var photoUploadParamsObj = new JObject { { "retry_context", retryContext }, { "media_type", "2" }, { "upload_id", uploadId }, { "image_compression", "{\"lib_name\":\"moz\",\"lib_version\":\"3.1.m\",\"quality\":\"95\"}" }, }; var photoUploadParams = JsonConvert.SerializeObject(photoUploadParamsObj); IBuffer thumbnailUploadBuffer; if (video.VideoThumbnail.UploadBuffer == null) { if (video.VideoThumbnail.Url == null) { throw new NullReferenceException("No upload buffer or file path are provided for video thumbnail upload."); } var videoFile = await StorageFile.GetFileFromPathAsync(video.VideoThumbnail.Url.AbsolutePath); thumbnailUploadBuffer = await FileIO.ReadBufferAsync(videoFile); } else { thumbnailUploadBuffer = video.VideoThumbnail.UploadBuffer; } var imageContent = new HttpBufferContent(thumbnailUploadBuffer); imageContent.Headers.Add("Content-Transfer-Encoding", "binary"); imageContent.Headers.Add("Content-Type", "application/octet-stream"); request = new HttpRequestMessage(HttpMethod.Post, photoUri); 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", thumbnailUploadBuffer.Length.ToString()); request.Headers.Add("X_FB_PHOTO_WATERFALL_ID", waterfallId); response = await _httpClient.SendRequestAsync(request); json = await response.Content.ReadAsStringAsync(); DebugLogger.LogResponse(response); upProgress.UploadState = InstaUploadState.ThumbnailUploaded; progress?.Invoke(upProgress); } return(await ConfigureVideo(progress, upProgress, uploadId, isDirectVideo, isDisappearingVideo, caption, viewMode, storyType, recipients, threadId, uri, uploadOptions)); } catch (Exception exception) { upProgress.UploadState = InstaUploadState.Error; progress?.Invoke(upProgress); DebugLogger.LogException(exception); return(Result <bool> .Except(exception)); } }