Formularz kontaktowy powiązany z Google Gmail SMTP

Pokażę jak można stworzyć prosty formularz kontaktowy na naszej stronie domowej obsługujący SMTP Google Gmaila, PHPMailer bazujący na hostingu lub początkowo na własnym serwerze Apache z obsługą PHP.
Czyli, formularz kontaktowy, który stworzymy będzie przy pomocy PHPMailer-a wysyłał nam na konto Google Gmail dane z tego formularza w postaci nowych emaili.

Zanim opiszę kolejne kroki wykonania, krótka finalna prezentacja.

Oraz wygląd wysłanej wiadomości:

To już wiemy czego możemy oczekiwać, a teraz środowisko w którym będziemy pracować.
Wszystko będzie postawione na serwerze Apache z PHP. Skorzystać można z gotowego zestawu XAMPP lub też samemu oddzielnie postawić serwer z PHP.

Dobrze, teraz tworzymy jakiś katalog w folderze publicznym www, a wewnątrz plik index.html, css, js oraz konfigurujemy w utworzonym pliku html formularz kontaktowy. Tu z polami: name, email, message. Można dodawać inne lub też dowolnie konfigurować.
Załączam plik webowy:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Contact form</title>
    <!-- Bootstrap CSS -->
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
    <!-- Custom CSS -->
    <link href="styles.css" rel="stylesheet">
</head>
<body>

    
<!-- Contact Section -->
<section id="contact" class="bg-light py-5">
    <div class="container">
        <h2 class="text-center mb-4">Contact</h2>
        <form action="contact.php" method="post">
          <div class="form-group">
              <label for="name">Name</label>
              <input type="text" class="form-control" id="name" name="name" placeholder="Your Name" required>
          </div>
          <div class="form-group">
              <label for="email">Email address</label>
              <input type="email" class="form-control" id="email" name="email" placeholder="Your Email" required>
          </div>
          <div class="form-group">
              <label for="message">Message</label>
              <textarea class="form-control" id="message" name="message" rows="3" placeholder="Your Message" required></textarea>
          </div>
          <button type="submit" class="btn btn-primary">Send</button>
      </form>
      
    </div>
</section>

<!-- Bootstrap and JavaScript -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="scripts.js"></script>
</body>
</html>

W znajdującym się obecnie katalogu instalujemy composer z linii poleceń:

sudo apt get install composer

W końcowym rezultacie utworzony plik composer.json musi mieć odpowiednio taką zawartość jak poniżej:

{
    "require": {
        "phpmailer/phpmailer": "^6.9",
        "google/apiclient": "^2.17",
        "league/oauth2-client": "^2.7",
        "league/oauth2-google": "^4.0"
    }
}

Teraz tworzymy poprzez konto Gmail nowy Google Cloud Project.
I tak:
stan publikacji – ustawiamy na wersję produkcyjną
Musimy pamiętać, żeby zaznaczyć dane logowania OAuth 2.0 jako Web application
URI przekierowania powinny być następujące:
-http://localhost/callback.php
-http://127.0.0.1/callback.php
Otrzymujemy w wyniku procesu utworzenia projektu:
-identyfikator klienta
-tajny klucz klienta
-stan powinien być włączony

Powinniśmy również zainstalować:

composer require phpmailer/phpmailer

composer require google/apiclient

W celu otrzymania refresh-tokenu wywołujemy plik get_refresh_token.php:

php get_refresh_token.php

Niezbędne będzie utworzenie następujących dwóch plików php:

// get_refresh_token.php
<?php
require 'vendor/autoload.php';

$client = new Google_Client();
$client->setClientId('tu wstawiamy id klienta z cloud projektu');
$client->setClientSecret('tutaj wstawiamy tajny klucz klienta');
$client->setRedirectUri('http://localhost/callback.php');
$client->addScope('https://mail.google.com/');
$client->setAccessType('offline');
$client->setPrompt('consent');

// Generate the URL for the consent screen
$authUrl = $client->createAuthUrl();
echo "Please visit this URL to authorize the application: " . $authUrl . "\n";

// After authorization, Google will redirect to your callback URL with a code
// You need to exchange this code for tokens
echo "Enter the code you received: ";
$authCode = trim(fgets(STDIN));

// Exchange the auth code for tokens
$token = $client->fetchAccessTokenWithAuthCode($authCode);

if (isset($token['refresh_token'])) {
    echo "Refresh Token: " . $token['refresh_token'] . "\n";
} else {
    echo "No refresh token received. Make sure you've set access type to offline and prompted for consent.\n";
}
?>

Oraz:

// callback.php
<?php
require 'vendor/autoload.php';

$client = new Google_Client();
$client->setClientId('nasz identyfikator klienta');
$client->setClientSecret('tajny klucz klienta');
$client->setRedirectUri('http://localhost/callback.php');

if (isset($_GET['code'])) {
    $token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
    $client->setAccessToken($token);

    // Check if we have a refresh token
    if (isset($token['refresh_token'])) {
        $refresh_token = $token['refresh_token'];
        echo "Refresh Token: " . $refresh_token;
        // Here you would typically save this refresh token securely for future use
    } else {
        echo "No refresh token received.";
    }
} else {
    echo "No authorization code received.";
}
?>

Będzie nam jeszcze potrzebny refresh_token. A to oto sposób na jego uzyskanie:

php get_refresh_token.php

Wszystkie pliki powinny znajdować się w tej samej lokalizacji.

Teraz możemy zająć się tworzeniem głównego pliku PHP – > contact.php odpowiedzialnego za korzystanie z providera Google, PHPMailera i wysyłanie emaila na nasze konto pocztowe.

Poniżej plik contact.php:

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

require_once 'vendor/autoload.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\OAuth;
use League\OAuth2\Client\Provider\Google;

// Stała konfiguracja
$config = [
    'client_id' => 'tu umieszczamy nasze id klienta',
    'client_secret' => 'tajny klucz klienta',
    'refresh_token' => 'utworzony przez nas refresh_token',
    'gmail_address' => 'nasza nazwa konta gmail'
];

// Sprawdź, czy dane formularza zostały przesłane
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Pobierz dane z formularza
    $sender_name = $_POST['name'] ?? '';
    $sender_email = $_POST['email'] ?? '';
    $message = $_POST['message'] ?? '';

    $mail = new PHPMailer(true);

    try {
        // Konfiguracja OAuth2
        $provider = new Google([
            'clientId' => $config['client_id'],
            'clientSecret' => $config['client_secret'],
        ]);

        // Wyłącz wyświetlanie logów SMTP
        $mail->SMTPDebug = SMTP::DEBUG_OFF;
        $mail->isSMTP();
        $mail->Host = 'smtp.gmail.com';
        $mail->Port = 587;
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $mail->SMTPAuth = true;
        $mail->AuthType = 'XOAUTH2';

        $mail->setOAuth(
            new OAuth([
                'provider' => $provider,
                'clientId' => $config['client_id'],
                'clientSecret' => $config['client_secret'],
                'refreshToken' => $config['refresh_token'],
                'userName' => $config['gmail_address'],
            ])
        );

        // Konfiguracja wiadomości
        $mail->setFrom($config['gmail_address'], 'Contact form');
        $mail->addAddress($config['gmail_address'], 'Your name');
        $mail->Subject = "New message from $sender_name";
        $mail->Body    = "You received a new message from:\n\n";
        $mail->Body   .= "Name: $sender_name\n";
        $mail->Body   .= "Email: $sender_email\n\n";
        $mail->Body   .= "Message:\n$message";

        $mail->send();
        echo '<p style="color: green;">Your message has been sent successfully. Thank you for contacting us!</p>';
    } catch (Exception $e) {
        echo '<p style="color: red;">An error occurred while sending the message. Please try again later.</p>';
        error_log("Sending email failed: " . $mail->ErrorInfo . "\n" . $e->getMessage());
    }
} else {
    // Wyświetl formularz, jeśli nie został jeszcze przesłany
    include 'form.html';
}
?>

I na tym kończąc powinniśmy mieć rezultat jak pokazany na samym początku tego posta.

Postawienie strony/bloga WordPress na własnym komputerze

Będziemy potrzebowali systemu operacyjnego, tutaj będzie to Linux, dystrybucja Ubuntu 22.04. Serwerem na którym będą przechowywane pliki będzie Apache. Będzie potrzebna jeszcze baza danych, czyli MySQL i PHP, jako że WordPress jest m.in. napisany w tym języku.

Krok 1 – Instalacja Apache

Zainstaluj Apache z:
$ sudo apt install apache2

Po zatwierdzeniu instalacji, możemy sprawdzić działanie w przeglądarce pod adresem http://localhost:80.
Pliki będą znajdować się w lokalizacji /var/www/html
Możemy też z poziomu własnego komputera sprawdzić publiczny adres IP serwera:
$ curl http://icanhazip.com
Aby był widoczny z zewnątrz trzeba byłoby utworzyć odpowiednią regułę w domyślnym ufw (Uncomplicated firewall) firewall-u Ubuntu. Nie będziemy tego potrzebowali w celu roboczym działania WordPress-a tylko na własny użytek. Bloga możemy potem migrować na hosting za pomocą jednej z wielu darmowych dostępnych wtyczek.

Krok 2 – Instalacja MySQL

Instalujemy oprogramowanie:
$ sudo apt install mysql-server
Nadajemy hasło dla głównego użytkownika w celu bezpieczeństwa.
Najpierw uruchamiamy wywołanie MySQL:
$ sudo mysql
i nadajemy hasło:
> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
a następnie wychodzimy:
mysql> exit
Później za pomocą interaktywnego skryptu przypisujemy hasło root-a do zabezpieczenia bazy danych:
$ sudo mysql_secure_installation
i zatwierdzamy usunięcie wszelkich dalszych zależności do bazy.
Sprawdzamy działanie:
$ sudo mysql -u root -p
poproszeni o hasło wprowadzamy je.

Krok 3 – Instalowanie PHP

Do zainstalowania pakietów używamy:
$ sudo apt install php libapache2-mod-php php-mysql
Sprawdzamy zainstalowaną wersję:
$ php -v

Krok 4 – Zabezpieczenia plików serwera Apache

Najpierw tworzymy plik .htpasswd do zabezpieczenia:
$ sudo htpasswd -c /sciezka/do/.htpasswd username
Zostajemy zapytani o hasło i jego potwierdzenie.

Edytujemy plik konfiguracyjny serwera znajdujący się w /etc/apache2/apache2.conf
Pod koniec dodajemy:

<Directory /var/www/html/>
     AuthType Basic
     AuthUserFile /sciezka/do/.htpasswd
     Require valid-user
     Order Deny, Allow
     Deny from all
     Allow from localhost
</Directory>

Krok 5 – Utworzenie bazy danych

Wchodzimy do MySQL:
$ sudo mysql -u root -p
oraz tworzymy bazę:
mysql> CREATE DATABASE nazwa_bazy;

Krok 6 – Instalacja WordPress

Ściągamy najnowszą wersję WordPress-a z oryginalnej strony.
Uzupełniamy posiadane dane do instalacji, potem wymagane informacje i możemy już w pełni korzystać z aplikacji.