stefanzweifel / laravel-sends

A package to keep track of outgoing emails in your Laravel application.
MIT License
180 stars 8 forks source link

Attempt to read property "messageId" on null #20

Closed edikurniawan-dev closed 8 months ago

edikurniawan-dev commented 8 months ago

I got this error message Attempt to read property "messageId" on null. Is there anything to do with it because I use uuid as the primary key? then how to fix it?

stefanzweifel commented 8 months ago

Hi @edikurniawan-dev,

Can you please share more on how and when you got the error message? A full stack-trace of the error plus code example would be great.

edikurniawan-dev commented 8 months ago

i remove uuid and using id, but still get same error message this my code

// app\Mail\SampleEmail.php
<?php

namespace App\Mail;

use App\Models\Payroll;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
use Wnx\Sends\Support\StoreMailables;

class SampleEmail extends Mailable
{
    use Queueable, SerializesModels;
    use StoreMailables;

    /**
     * Create a new message instance.
     */
    public function __construct(public Payroll $payroll)
    {
        //
    }

    /**
     * Get the message envelope.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'Sample Email',
        );
    }

    /**
     * Get the message content definition.
     */
    public function content(): Content
    {
        return new Content(
            view: 'view.email',
        );
    }

    /**
     * Get the attachments for the message.
     *
     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
     */
    public function attachments(): array
    {
        return [];
    }

    public function headers()
    {
        $this->storeClassName();
    }
}
// app\Providers\EventServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event to listener mappings for the application.
     *
     * @var array<class-string, array<int, class-string>>
     */
    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
        \Illuminate\Mail\Events\MessageSent::class => [
            \Wnx\Sends\Listeners\StoreOutgoingMailListener::class,
        ],
    ];

    /**
     * Register any events for your application.
     */
    public function boot(): void
    {
        //
    }

    /**
     * Determine if events and listeners should be automatically discovered.
     */
    public function shouldDiscoverEvents(): bool
    {
        return false;
    }
}

and i use this in my controller Mail::to($payroll->email)->send(new SampleEmail($payroll));

and get this error

#message: "Attempt to read property "messageId" on null"
#code: 0
#file: "D:\Coding\esd-payroll\vendor\laravel\framework\src\Illuminate\Mail\Mailable.php"
#line: 1652
#severity: E_WARNING

Are there any further settings? I'am using laravel 10.10 Sorry, I'm new to using Laravel

stefanzweifel commented 8 months ago

@edikurniawan-dev You mention "i remove uuid and using id".

What exactly did you remove? Did you remove this column from the database migration? https://github.com/stefanzweifel/laravel-sends/blob/1d8c277abec4e3c07b8942a161ad3942c9586a70/database/migrations/create_sends_table.php.stub#L13

This will definitely lead to issues, as the package will try to fill the column in the Listener here: https://github.com/stefanzweifel/laravel-sends/blob/1d8c277abec4e3c07b8942a161ad3942c9586a70/src/Listeners/StoreOutgoingMailListener.php#L43

You have to re-add the column or update StoreOutgoingMailListener.php


But I think the issue is, that you don't return anything from the headers()-method in your mail. Can you update your mailable to have a headers method like this:

    /**
     * @return \Illuminate\Mail\Mailables\Headers
     */
    public function headers()
    {
        return new \Illuminate\Mail\Mailables\Headers(
            text: [
                // Merge the headers from laravel-sends to the Headers object
                ...$this->getMailClassHeader()->toArray(),
            ],
        );
    }

The "Attempt to read property "messageId" on null" error however is happening inside a Laravel core class: https://github.com/laravel/framework/blob/10.x/src/Illuminate/Mail/Mailable.php#L1652

It tries to read some headers, but as you override the headers method and don't return anything from that method, Laravel can't read the headers.

edikurniawan-dev commented 8 months ago

'What exactly did you remove? Did you remove this column from the database migration?' No, i not remove anything from laravel sends database migration, i removed uuid from the models I created such as user and payroll. I'm sorry i not clear in my statement

edikurniawan-dev commented 8 months ago

@stefanzweifel i already added ...$this->getMailClassHeader()->toArray(), but when will the delivered at, open, clicks and other columns be updated? I have tried to open the email received but none of the columns have been updated?

stefanzweifel commented 8 months ago

@edikurniawan-dev

i already added ...$this->getMailClassHeader()->toArray(),

So your Mailable code looks like this? (If not, please share the full code.)

<?php

namespace App\Mail;

use App\Models\Payroll;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
use Wnx\Sends\Support\StoreMailables;

class SampleEmail extends Mailable
{
    use Queueable, SerializesModels;
    use StoreMailables;

    /**
     * Create a new message instance.
     */
    public function __construct(public Payroll $payroll)
    {
        //
    }

    /**
     * Get the message envelope.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'Sample Email',
        );
    }

    /**
     * Get the message content definition.
     */
    public function content(): Content
    {
        return new Content(
            view: 'view.email',
        );
    }

    /**
     * Get the attachments for the message.
     *
     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
     */
    public function attachments(): array
    {
        return [];
    }

    /**
     * @return \Illuminate\Mail\Mailables\Headers
     */
    public function headers()
    {
        return new \Illuminate\Mail\Mailables\Headers(
            text: [
                // Merge the headers from laravel-sends to the Headers object
                ...$this->getMailClassHeader()->toArray(),
            ],
        );
    }
}

Did this resolve your issue? You still get an error message? If yes, can we close the issue?

but when will the delivered at, open, clicks and other columns be updated? I have tried to open the email received but none of the columns have been updated?

This feature doesn't come automatically with the package. It's impossible to ship this in a package, as this all depends on how you send your emails. (Depends if you use AWS, SMTP, Mailgun, Postmark, or any other driver)

For example, to track if an email has been opened you must have an image inside your email, that makes a request to your app.

I haven't written a full tutorial on how to do this. But you can find more information about this in the README: https://github.com/stefanzweifel/laravel-sends?tab=readme-ov-file#further-usage-of-the-sends-table

edikurniawan-dev commented 8 months ago

Yes this code resolve my issue i already added ...$this->getMailClassHeader()->toArray()

Thank you very much for your help