From 367f0371144f6add22f3824bcff117579a74fc6f Mon Sep 17 00:00:00 2001
From: Johann Fradj <fradj.johann@gmail.com>
Date: Fri, 20 Dec 2024 07:40:04 +0100
Subject: [PATCH] Allow a job to define a cloud task id and thus leverage the
 powerful Google Cloud Task deduplication mechanism

---
 src/CloudTasksQueue.php | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/src/CloudTasksQueue.php b/src/CloudTasksQueue.php
index c14458e..2967d0a 100644
--- a/src/CloudTasksQueue.php
+++ b/src/CloudTasksQueue.php
@@ -113,6 +113,23 @@ function ($payload, $queue) use ($job) {
         );
     }
 
+    protected function createPayloadArray($job, $queue, $data = '')
+    {
+        $payload = parent::createPayloadArray($job, $queue, $data);
+
+        $cloudTaskId = $this->getCloudTaskId($job);
+        if (!empty($cloudTaskId)) {
+            $payload['cloudTaskId'] = $cloudTaskId;
+        }
+
+        return $payload;
+    }
+
+    protected function getCloudTaskId($job)
+    {
+        return property_exists($job, 'cloudTaskId') ? $job->cloudTaskId : null;
+    }
+
     /**
      * Push a raw payload onto the queue.
      *
@@ -165,7 +182,11 @@ protected function pushToCloudTasks($queue, $payload, $delay, mixed $job)
 
         $payload = (array) json_decode($payload, true);
 
-        $task = tap(new Task)->setName($this->taskName($queue, $payload['displayName']));
+        if (isset($payload['cloudTaskId'])) {
+            $task = tap(new Task())->setName($this->taskNameWithId($queue, $payload['cloudTaskId']));
+        } else {
+            $task = tap(new Task())->setName($this->taskName($queue, $payload['displayName']));
+        }
 
         $payload = $this->enrichPayloadWithAttempts($payload);
 
@@ -199,6 +220,16 @@ private function taskName(string $queueName, string $displayName): string
         );
     }
 
+    private function taskNameWithId(string $queueName, string $taskId): string
+    {
+        return CloudTasksClient::taskName(
+            $this->config['project'],
+            $this->config['location'],
+            $queueName,
+            $taskId,
+        );
+    }
+
     private function enrichPayloadWithAttempts(
         array $payload,
     ): array {