I am using the following working code in Laravel:
Mail::to('mail#example.com')->send(new \App\Mail\CheckinInfo([
'client' => $client,
]));
when I use an email address from the environment, it stopped working:
Mail::to(env('MAIL_FROM_ADDRESS'))->send(new \App\Mail\CheckinInfo([
'client' => $client,
]));
In .env I got:
MAIL_FROM_ADDRESS=mail#example.com
and I tried
MAIL_FROM_ADDRESS="mail#example.com"
The cache and config are cleared.
The error message is:
[2022-07-29 18:44:26] production.ERROR: An email must have a "To", "Cc", or "Bcc" header. {"exception":"[object] (Symfony\\Component\\Mime\\Exception\\LogicException(code: 0): An email must have a \"To\", \"Cc\", or \"Bcc\" header. at /www/htdocs/app/laravel/vendor/symfony/mime/Message.php:128)
As a note when you do a config:cache the settings will not be grabbed from your .env anymore.
You should create a config/settings.php or similar file and store your env vars there, ie:
config/settings.php
return [
'mail_from_address' => env('MAIL_FROM_ADDRESS'),
]
and you should reference it as so
config('settings.mail_from_address')
No your mistake on the first line, maybe you didn't close the bracket
Try this way
Mail::to(env('MAIL_FROM_ADDRESS'))->send(new \App\Mail\CheckinInfo([
'client' => $client,
])); //Notice I added the closing parenthesis for To()
You are trying to access the functions of the env methods. This is not possible
I hope this is just the problem
You can see the documentation for the framework,
about this queueing-mail laravel documentation
Related
Good morning, everyone,
As part of the development of demonstration APIs, I realized two APIs :
HelloWorld
Notify
The first one allows to ask for a HelloWorld to be performed, the second one allows to send e-mails according to defined templates.
In my demonstration I make from Postman (or from a React application) an API call to HelloWorld which then makes an API call to Notifier to send the message.
If from Postman I call directly my Notifier API to send an email, I do not encounter any problem (the .env file is well configured for sending emails in this API).
On the other hand if I call my API from HelloWorld to Notifier (the .env file of HelloWorld is not configured for sending e-mails), I encounter an error:
Expected response code 250 but got code "530", with message "530 5.7.1
Authentication required
On the other hand if I configure the .env file of the HelloWorld API (which does not send an e-mail at any time), I do not have any more error and my e-mail is well sent by Notifier.
This is the API Call in HelloWorld :
$client = new Client();
$response = $client->post("http://vhost-url.local/api/notifier/sendmail", [
'json' => [
'to' => $to,
'template' => $template,
'parameters' => $parameters
],
]);
And this is the action called in Notifier API :
public function sendmail(Request $request)
{
$params = json_decode($request->getContent(), true);
try{
switch ($params['template']) {
case 'HELLO_WORLD':
Mail::to($params['to'])
->send(new HelloWorld([
'message' => $params['parameters']['message']
]));
break;
default:
throw new \Exception("Ce template n'existe pas");
break;
}
} catch(\Exception $e) {
return response()
->json([
'message' => $e->getMessage(),
], 500);
}
return response()
->json([
'message' => 'Le mail a bien été envoyé'
], 200);
}
My question is: During an API call (with Guzzle in my case), is the environment file of the source API used instead of the environment file of the destination API? And if so, how to fix this problem?
I'm not sure if this helps but I have had similar problems. The .env files get messed up when cross-communicating Laravel projects (on Windows only I believe).
See for instance https://github.com/laravel/framework/issues/19454 .
The solution is to run php artisan config:cache to create a cached version of your .env variables. Note that you should never use env('...') in your code, instead you should refer to them using a config file like config('app.env'). .env variables can not be dynamic for this reason.
For custom env variables, I usually create a config/project.php file like so:
return [
'my_custom_var' => env('PROJECT_MY_CUSTOM_VAR')
];
That way you can cache it and call the variable using config('project.my_custom_var');
I need to set admin email in many place. so I created constants.php in config folder.
<?php
return array(
'admin_email' =>'joe#doe.com',
'admin_name' =>'Admin',
);
I was able to access this in my routes.php
dd(Config::get('constants.admin_email'));
However, when I try to access it in mail.php by
'from' => [
'address' => Config::get('constants.admin_email'),
'name' => Config::get('constants.admin_name')
],
I got Class 'Config' not found in mail.php.
Any suggestions? Thanks.
After some testing, I've found you can't use Config, \Config or config() in any files in your config folder. I believe they are not available to any of these files, but I'm not 100% sure why this is.
Regardless, to solve this issue and still have them available in other parts of your application, use env or environment variables. In your .env file, add the following:
ADMIN_EMAIL=joe#doe.com
ADMIN_NAME=Admin
Then, in your mail.php and anywhere else you want to use them, access them using:
'from' => [
'address' => env('ADMIN_EMAIL'),
'name' => env('ADMIN_NAME')
],
You can actually see them already in use in your mail.php and other config files, so it makes sense to use what already works. Hope that helps!
Use
config('constants.admin_email');
I'm trying to send an email to all the users in the database, but I'm getting the following error: [GuzzleHttp\Exception\ClientException] Client error: 400.
Here's my code:
$users = App\User::all();
foreach($users as $user) {
$code = new App\Code();
$code->code = str_random(10);
$code->save();
Mail::send('emails.code', ['code' => $code], function($message) use ($user)
{
$message->to($user->email)->from('foo.bar#gmail.com', 'Foo Bar')->subject('New code, new chances!');
});
}
[GuzzleHttp\Exception\ClientException] Client error: 400
is for URL not found
Check for host url in config/mail.php, host url might be wrong
Not sure if you have got it working but I had the exact same problem today and I had no idea what went wrong as I did the exact same implementation just in my previous Laravel project with mailgun. Then I found the issue in the configuration.
So, here is the glitch..I don't know in which version it was changed, but in config/services.php the mailgun config is now like this,
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
],
where it was like this before as far as I can remember,
'mailgun' => [
'domain' => env('MAIL_DOMAIN'),
'secret' => env('MAIL_SECRET'),
],
so in my .env file, I was only referencing MAIL_DOMAIN and MAIL_SECRET environment variables but I just realised in the services.php file, it's actually referencing different environment variables - MAILGUN_DOMAIN and MAILGUN_SECRET.
So I've just added these environment variables, cleared the config cache and it is working perfectly now.
(I am working with Laravel 5.1.23 version BTW)
Hope this helps. Thanks.
I'm using the Mailgun service when sending mail with Laravel. However, i've set this up today and it's just stopped working. I have entered all the correct info in .env, config/services.php and config/mail.php. However i'm still getting the below error:
ClientException in Middleware.php line 69:
Client error: 404
It looks like the domain is not getting passed through somehow, even though in my config/services.php file I have:
'mailgun' => [
'domain' => env('mydomain.com'),
'secret' => env('<my-mailgun-key>'),
],
I have hidden the above credentials for safety, but in my real application they are the proper values.
Please help.
I was having a very similar 404 issue and tried the solution mentioned by Rogério. I thought I was doing it right, but gave it a try anyway. But misuse of the env() function wasn't my problem.
I set the config/services.php back to look like so:
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN',''),
'secret' => env('MAILGUN_SECRET',''),
],
This will provide empty strings if the values named MAILGUN_DOMAIN and MAILGUN_SECRET are not found in the .env file. Then, in my .env file, I included the API Base URL and API Key from the Mailgun domain information page. So the .env looked something like this:
MAILGUN_DOMAIN=https://api.mailgun.net/v3/sandbox123abc.mailgun.org
MAILGUN_SECRET=key-123456abcdef
The values were passing along as they should, but still 404. Looking at How do I start sending email documentation at Mailgun, I saw that their API URL included "messages" on the end - which I tried manually adding to the .env setting:
MAILGUN_DOMAIN=https://api.mailgun.net/v3/sandbox123abc.mailgun.org/messages
That didn't work either, but lead me to look more carefully at the stack trace spit out by Laravel. That's when I noticed that the URL it was trying to connect with was:
https://api.mailgun.net/v3https://api.mailgun.net/v3/sandbox123abc.mailgun.org/messages/messages.mime
Ah-ha! Using Mailgun's Base API URL was incorrect! That was made obvious by the repetition of the "https://api.mailgun.net/v3" portion. So the aptly named MAILGUN_DOMAIN setting really just needed to be:
MAILGUN_DOMAIN=sandbox123abc.mailgun.org
Seems obvious now, but I spent way too much time figuring it out. Thought I'd put it out there in case anyone else happened to miss that detail
I hade the same problem as you and solved it by removing the env() call.
Thats because env will return the value of the env variable in the first argument (not the value of the argument) and otherwise return the second argument.
So:
'mailgun' => [
'domain' => 'mydomain.com',
'secret' => '<my-mailgun-key>',
],
Try that.
I wrote an API using Yii2 and following the REST guide. My API is working and I want to write some tests for it, so I once again followed the guide on how to run tests and got unit tests working. I then looked around Codeception documentation about testing WebServices and got this working too.
My problem is that API calls are not using my test database. I have two databases, one called db and the other testdb. Here is my config.php file in tests/codeception/config/:
return [
'components' => [
'db' => [
'dsn' => 'mysql:host=localhost;port=8889;dbname=testdb;unix_socket=/Applications/MAMP/tmp/mysql/mysql.sock',
],
'mailer' => [
'useFileTransport' => true,
],
'urlManager' => [
'showScriptName' => true,
],
],
];
I wrote a simple test that send a GET request to an endpoint to retrieve data. My test database is empty so I am expecting to receive an empty response, but I get the content of my other database instead.
I then tried to set YII_ENV to test as described in the Environment Constant section here so that I could test against the env variable YII_ENV_TEST and change the db configuration accordingly. I tried to set this variable in the _bootstrap.php file in the tests/codeception/ folder:
defined('YII_ENV') or define('YII_ENV', 'test');
I then logged the value of YII_ENV in the web/index.php file (index-test.php is not called, might be a problem too), and it is undefined.
What am I doing wrong? I tried including the Yii2 module in my api.suite.yml file but requests don't have return code anymore if I do that, it returns N/A. Is there another way to change which database Yii should use?
You can make an test_config.php file and at the end of the config place this
if (file_exists('protected/config/test_config.php'))
{
include 'test_config.php';
}
the file will be included if it exists. And the file test_config.php should contain the overwritten value for the db connection.
Hope this helps!
Keep on coding!
Ares.
Well I found a "solution" by using this other app template: https://github.com/githubjeka/yii2-rest
The file organization fits my needs better and I can easily configure which database to use.