Answers.Body: <p>Yes, you can pass through the customer ID to your queue job, then the job itself can look up the customer and send the email.</p>
  <p>Here's a super-simple example console controller action method that passes through a user ID to a queue job class called <code>SendEmail</code>:</p>
  <pre><code>public function actionSend()
  {
      $userIds = User::find()
          -&gt;status(User::STATUS_ACTIVE)
          -&gt;ids();
      
      foreach ($userIds as $userId) {
          Craft::$app-&gt;getQueue()-&gt;delay(0)-&gt;push(new SendEmail([
              'userId' =&gt; $userId
          ])); 
      }
  }
  </code></pre>
  <p>Then here's the <code>SendEmail</code> job class. This has a property called <code>userId</code> which represents the variable that's passed in when the new instance of the <code>SendEmail</code> class is created in the code example above. You can use that <code>userId</code> property to fetch the User object, and then send an email:</p>
  <pre><code>class SendEmail extends BaseJob
  {
      // Public Properties
      // =========================================================================
  
      /**
       * @var string
       */
      public $userId;
  
      // Public Methods
      // =========================================================================
  
      /**
       * @param QueueInterface|Queue $queue
       * @return void
       */
      public function execute($queue)
      {  
          $user = Craft::$app-&gt;getUsers()-&gt;getUserById($this-&gt;userId);
  
          if ($user) {
              Craft::$app-&gt;getMailer()
                  -&gt;composeFromKey('my-plugin_email_key, [
                      'firstName' =&gt; $user-&gt;firstName,
                  ])
                  -&gt;setTo($user)
                  -&gt;send();
          }
  
          $this-&gt;setProgress($queue, 1);
      }
  
      // Protected Methods
      // =========================================================================
  
      /**
       * @return string
       */
      protected function defaultDescription(): string
      {
          return Craft::t(
              'my-plugin',
              'Sending email for user Id {userId}',
              [
                  'userId' =&gt; $this-&gt;userId,
              ]
          );
      }
  }
  </code></pre>
  <p>I've left out the <code>namespace</code> and <code>use</code> statements etc., but hopefully that gives you an idea of how this works.</p>
  <p>You'll need to register the email you want to send in your plugin/module's base class. I do this via a <code>_registerEmailMessages</code> class called from the plugin/module's <code>init</code> method:</p>
  <pre><code>public function init()
  {
      parent::init();
      self::$plugin = $this;
  
      // Do a bunch of init stuff
      $this-&gt;_registerEmailMessages();
  }
  
  private function _registerEmailMessages()
  {
      Event::on(
          SystemMessages::class,
          SystemMessages::EVENT_REGISTER_MESSAGES,
          function(RegisterEmailMessagesEvent $event) {
              $event-&gt;messages = array_merge($event-&gt;messages, [
                  [
                      'key' =&gt; 'my-plugin_email_key',
                      'heading' =&gt; Craft::t('my-plugin', 'my-plugin_email_key_heading'),
                      'subject' =&gt; Craft::t('my-plugin', 'my-plugin_email_key_subject'),
                      'body' =&gt; Craft::t('my-plugin', 'my-plugin_email_key_body'),
                  ],
             ]);
          }
      );
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-06-23T15:36:07.110Z
Answers.Text: I just came on to post my own answer, but your's is definitely better presented!
    
  Can I check the line:
  `Craft::$app->getQueue()->delay(0)->push(new SendEmail([ 'userId' => $userId ]));`
    Would this process the job when it's added?
Answers.UserDisplayName: Jaytrix
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-06-24T07:29:13.443Z
Answers.Text: That depends on how you have your queue set up. I use the Async Queue plugin from Oliver Stark (https://github.com/ostark/craft-async-queue) to run the queue using background processes, so in my setup it wouldn't run straight away. In a stock setup, I believe it would be processed as soon as the next request (i.e. page load) to Craft was made.
Answers.UserDisplayName: Martin Spain
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-06-22T08:56:39.220Z
Answers.LastActivityDate: 2021-06-24T07:29:55.037Z
Answers.LastEditDate: 2021-06-24T07:29:55.037Z
Answers.UserDisplayName: Martin Spain
Body: <p>Is there a way to parse a variable to a queue job? I want to re-send some Craft commerce emails via a cron job, so have created a console controller for the cron job to run a command against. This then will get all the customers to email and create a queued job (I'd like the jobs to run automatically somehow).
  To save having one big job to email 100's of customers, I thought to create 1 job per customer ... only way I can think is to have the controller parse the customer email through each new job it creates.</p>
  <p>I'm currently testing with sending a email to a sandbox email account in 1 queued job that loops through a <code>range</code> of 1-10. This method is becoming too unreliable where I might get emails 1-5 out of 10, or 1-5 then 15-20 in a loop of 20. The test I've just run only sent 18-20 out of 20.
  When I've tested with creating a job per email, I get a consistent amount of emails.</p>
  
Tags: <craft3><queue><console><commands>
Title: Parse variable to new queue job
ThreadText: # Parse variable to new queue job
  
  (Asked by: username_0 on 2021-06-21)
  
  Is there a way to parse a variable to a queue job? I want to re-send some Craft commerce emails via a cron job, so have created a console controller for the cron job to run a command against. This then will get all the customers to email and create a queued job (I'd like the jobs to run automatically somehow).
  To save having one big job to email 100's of customers, I thought to create 1 job per customer ... only way I can think is to have the controller parse the customer email through each new job it creates.
  
  I'm currently testing with sending a email to a sandbox email account in 1 queued job that loops through a `range` of 1-10. This method is becoming too unreliable where I might get emails 1-5 out of 10, or 1-5 then 15-20 in a loop of 20. The test I've just run only sent 18-20 out of 20.
  When I've tested with creating a job per email, I get a consistent amount of emails.
  
  **Tags:** craft3, queue, console, commands
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2021-06-22. Score: 2
  
  Yes, you can pass through the customer ID to your queue job, then the job itself can look up the customer and send the email.
  
  Here's a super-simple example console controller action method that passes through a user ID to a queue job class called `SendEmail`:
  
  ```
  public function actionSend()
  {
      $userIds = User::find()
          ->status(User::STATUS_ACTIVE)
          ->ids();
      
      foreach ($userIds as $userId) {
          Craft::$app->getQueue()->delay(0)->push(new SendEmail([
              'userId' => $userId
          ])); 
      }
  }
  
  ```
  
  Then here's the `SendEmail` job class. This has a property called `userId` which represents the variable that's passed in when the new instance of the `SendEmail` class is created in the code example above. You can use that `userId` property to fetch the User object, and then send an email:
  
  ```
  class SendEmail extends BaseJob
  {
      // Public Properties
      // =========================================================================
  
      /**
       * @var string
       */
      public $userId;
  
      // Public Methods
      // =========================================================================
  
      /**
       * @param QueueInterface|Queue $queue
       * @return void
       */
      public function execute($queue)
      {  
          $user = Craft::$app->getUsers()->getUserById($this->userId);
  
          if ($user) {
              Craft::$app->getMailer()
                  ->composeFromKey('my-plugin_email_key, [
                      'firstName' => $user->firstName,
                  ])
                  ->setTo($user)
                  ->send();
          }
  
          $this->setProgress($queue, 1);
      }
  
      // Protected Methods
      // =========================================================================
  
      /**
       * @return string
       */
      protected function defaultDescription(): string
      {
          return Craft::t(
              'my-plugin',
              'Sending email for user Id {userId}',
              [
                  'userId' => $this->userId,
              ]
          );
      }
  }
  
  ```
  
  I've left out the `namespace` and `use` statements etc., but hopefully that gives you an idea of how this works.
  
  You'll need to register the email you want to send in your plugin/module's base class. I do this via a `_registerEmailMessages` class called from the plugin/module's `init` method:
  
  ```
  public function init()
  {
      parent::init();
      self::$plugin = $this;
  
      // Do a bunch of init stuff
      $this->_registerEmailMessages();
  }
  
  private function _registerEmailMessages()
  {
      Event::on(
          SystemMessages::class,
          SystemMessages::EVENT_REGISTER_MESSAGES,
          function(RegisterEmailMessagesEvent $event) {
              $event->messages = array_merge($event->messages, [
                  [
                      'key' => 'my-plugin_email_key',
                      'heading' => Craft::t('my-plugin', 'my-plugin_email_key_heading'),
                      'subject' => Craft::t('my-plugin', 'my-plugin_email_key_subject'),
                      'body' => Craft::t('my-plugin', 'my-plugin_email_key_body'),
                  ],
             ]);
          }
      );
  }
  
  ```
  
  > **Comments:**
  > **username_0**: I just came on to post my own answer, but your's is definitely better presented!    Can I check the line: `Craft::$app->getQueue()->delay(0)->push(new SendEmail([ 'userId' => $userId ]));`   Would this process the job when it's added?  
  > **username_1**: That depends on how you have your queue set up. I use the Async Queue plugin from Oliver Stark (https://github.com/ostark/craft-async-queue) to run the queue using background processes, so in my setup it wouldn't run straight away. In a stock setup, I believe it would be processed as soon as the next request (i.e. page load) to Craft was made.  
  
  ---
  
  