From ea2f21f8bf3833abbc97e56bf6b8c0ba8a790b49 Mon Sep 17 00:00:00 2001 From: Matthias Guillitte Date: Fri, 6 Jun 2025 16:48:25 +0200 Subject: [PATCH] Remove @ from description + try fix BMP characters issue --- app/Browser/BrowserJob.php | 14 +++++++ .../IInstagramDescriptionPipelineStep.php | 17 ++++++++ .../InstagramDescriptionPipeline.php | 42 +++++++++++++++++++ .../RemoveAccountsReferenceStep.php | 37 ++++++++++++++++ .../InstagramRepost/InstagramRepostJob.php | 32 ++++++++++++-- 5 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 app/Browser/Jobs/InstagramRepost/DescriptionPipeline/IInstagramDescriptionPipelineStep.php create mode 100644 app/Browser/Jobs/InstagramRepost/DescriptionPipeline/InstagramDescriptionPipeline.php create mode 100644 app/Browser/Jobs/InstagramRepost/DescriptionPipeline/RemoveAccountsReferenceStep.php diff --git a/app/Browser/BrowserJob.php b/app/Browser/BrowserJob.php index af5b7e8..91fac36 100644 --- a/app/Browser/BrowserJob.php +++ b/app/Browser/BrowserJob.php @@ -286,4 +286,18 @@ abstract class BrowserJob implements ShouldQueue return null; } } + + public function typeText(Browser $browser, string $text, string $querySelector): void + { + $browser->script(" + let element = document.querySelector('{$querySelector}'); + if (element) { + element.focus(); + element.value = '{$text}'; + element.dispatchEvent(new Event('input', { bubbles: true })); + } else { + console.error('Element not found: {$querySelector}'); + } + "); + } } diff --git a/app/Browser/Jobs/InstagramRepost/DescriptionPipeline/IInstagramDescriptionPipelineStep.php b/app/Browser/Jobs/InstagramRepost/DescriptionPipeline/IInstagramDescriptionPipelineStep.php new file mode 100644 index 0000000..072df11 --- /dev/null +++ b/app/Browser/Jobs/InstagramRepost/DescriptionPipeline/IInstagramDescriptionPipelineStep.php @@ -0,0 +1,17 @@ +steps = $steps; + } + + /** + * Process the description through the pipeline. + * + * @param string $description + * @return string + */ + public function process(string $description): string + { + foreach ($this->steps as $step) { + if (!$step instanceof IInstagramDescriptionPipelineStep) { + throw new \InvalidArgumentException('All steps must implement IInstagramDescriptionPipelineStep interface.'); + } + + $description = $step->process($description); + } + + return $description; + } +} diff --git a/app/Browser/Jobs/InstagramRepost/DescriptionPipeline/RemoveAccountsReferenceStep.php b/app/Browser/Jobs/InstagramRepost/DescriptionPipeline/RemoveAccountsReferenceStep.php new file mode 100644 index 0000000..cf6a58d --- /dev/null +++ b/app/Browser/Jobs/InstagramRepost/DescriptionPipeline/RemoveAccountsReferenceStep.php @@ -0,0 +1,37 @@ +downloadFolder = base_path($this->downloadFolder); $this->videoDownloader = new YTDLPDownloader(); + $this->descriptionPipeline = new InstagramDescriptionPipeline([ + // Add steps to the pipeline here + new DescriptionPipeline\RemoveAccountsReferenceStep(), + ]); } public function run(Browser $browser): ?JobRun @@ -317,8 +331,20 @@ class InstagramRepostJob extends BrowserJob implements ShouldBeUniqueUntilProces $this->clickNext($browser); // Skip cover photo and trim // Add a caption - $captionInput = $browser->driver->findElement(WebDriverBy::xpath('//div[@contenteditable]')); - $captionInput->sendKeys($videoInfo->getDescription()); + $captionText = $this->descriptionPipeline->process($videoInfo->getDescription()); + $browser->script(" + var el = document.querySelector('div[contenteditable]'), text = '{$captionText}'; + const dataTransfer = new DataTransfer(); + dataTransfer.setData('text', text); + const event = new ClipboardEvent('paste', { + clipboardData: dataTransfer, + bubbles: true + }); + document.querySelector('div[contenteditable]').dispatchEvent(event) + "); + //$this->typeText($browser, $captionText, 'div[contenteditable]'); + //$captionInput = $browser->driver->findElement(WebDriverBy::xpath('//div[@contenteditable]')); + //$captionInput->sendKeys($this->descriptionPipeline->process($videoInfo->getDescription())); sleep(2); // Wait for the caption to be added @@ -341,11 +367,11 @@ class InstagramRepostJob extends BrowserJob implements ShouldBeUniqueUntilProces try { $browser->waitForText("Your post was shared", 60, true); $closeButton = $browser->driver->findElement(WebDriverBy::xpath('//div[./div/*[local-name() = "svg"][@aria-label="Close"]]')); + $closeButton->click(); } catch (\Exception $e) { Log::error("Failed to repost reel: {$reel->reel_id} - " . $e->getMessage()); $browser->screenshot(JobDebugScreenshot::getFileName($this->jobId)); AllNotification::send(new JobDebugNotification($this->jobId, "Failed to repost reel: {$reel->reel_id} - " . $e->getMessage())); - $closeButton->click(); return false; } return true; // Reel reposted successfully, no error message found