Remove @ from description + try fix BMP characters issue
All checks were successful
Push image to registry / build-image (push) Successful in 4m46s

This commit is contained in:
2025-06-06 16:48:25 +02:00
parent 66c4752203
commit ea2f21f8bf
5 changed files with 139 additions and 3 deletions

View File

@ -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}');
}
");
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Browser\Jobs\InstagramRepost\DescriptionPipeline;
/**
* Interface for Instagram description pipeline steps.
*/
interface IInstagramDescriptionPipelineStep
{
/**
* Process the description.
* @param string $description
* @return string
*/
public function process(string $description): string;
}

View File

@ -0,0 +1,42 @@
<?php
// Pipeline for processing Instagram post descriptions
namespace App\Browser\Jobs\InstagramRepost\DescriptionPipeline;
class InstagramDescriptionPipeline
{
/**
* @var array of IInstagramDescriptionPipelineStep
*/
private array $steps;
/**
* InstagramDescriptionPipeline constructor.
*
* @param array $steps
*/
public function __construct(array $steps)
{
$this->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;
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace App\Browser\Jobs\InstagramRepost\DescriptionPipeline;
/**
* Step to remove account references from the description.
*/
class RemoveAccountsReferenceStep implements IInstagramDescriptionPipelineStep
{
/**
* Process the description to remove account references.
*
* @param string $description
* @return string
*/
public function process(string $description): string
{
// Regular expression to match Instagram account references
$pattern = '/@([a-zA-Z0-9._]+)/';
// Split by lines
$lines = explode("\n", $description);
// Remove lines that contain account references
$lines = array_filter($lines, function ($line) use ($pattern) {
// Check if the line does not match the account reference pattern
return !preg_match($pattern, $line);
});
// Join the remaining lines back into a single string
$cleanedDescription = implode("\n", $lines);
// Trim whitespace from the beginning and end of the description
return trim($cleanedDescription);
}
}

View File

@ -4,6 +4,7 @@ namespace App\Browser\Jobs\InstagramRepost;
use App\Browser\BrowserJob;
use App\Browser\JobDebugScreenshot;
use App\Browser\Jobs\InstagramRepost\DescriptionPipeline\InstagramDescriptionPipeline;
use App\Models\InstagramRepost;
use App\Models\InstagramAccount;
use App\Models\Job;
@ -50,12 +51,25 @@ class InstagramRepostJob extends BrowserJob implements ShouldBeUniqueUntilProces
protected string $downloadFolder = "app/Browser/downloads/InstagramRepost/";
/**
* Pipeline for processing Instagram post descriptions.
* This pipeline can be used to modify the description before reposting.
* For example, it can remove account references or add hashtags.
*
* @var InstagramDescriptionPipeline
*/
protected InstagramDescriptionPipeline $descriptionPipeline;
public function __construct($jobId = 4)
{
parent::__construct($jobId);
$this->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