DEV Community

Cover image for How to receive inbound email with PHP
Alex Yatsenko
Alex Yatsenko

Posted on • Edited on

How to receive inbound email with PHP

Hey,

It's Alex, the solo founder of ProxiedMail.
ProxiedMail is a tool that brings the email experience to a new level because it was built around the privacy first concept that enhances using a unique email each time which makes it a second password, but also allows you more control over your correspondence.
Additionally, it gives you the advantage of moving to another email provider just in a few seconds.
Because we have this kind of system we also aim to bring more into the experience of development using emails.

At some point, we want to receive an email straight into our application. It can be a system that doesn't provide any API but provides email notifications or we want to receive emails from our users as part of our functionality. There are dozens of use cases for receiving and handling emails in your applications. In this article, I'll explain how you're going to do it with PHP.

How it works

You can create an email address on ProxiedMail with a specific name or use an autogenerated one. Normally we also forward incoming emails to some kind of real email. Real email is some kind of old-fashioned mailbox on Gmail, ProtonMail, etc.
So, usually, it looks like that abc@proxiedmail.com -> blabla@protonmail.com.
Meanwhile, if you set up a webhook email we also send you a webhook to the specified email. You can disable forwarding to your real email using one of the internal forwarding emails like *@proxiedmail-int.int (i.e testingadw@proxiedmail-int.int)

API Features

  1. Creating endless proxy emails with one of ProxiedMail domains (i.e abc@proxiedmail.com, abcd@pxdmail.com, abcde@pxdmail.net)
  2. Setting up forwarding email or disabling forwarding
  3. Setting up a callback to your URL
  4. Browsing received emails on the received emails endpoint
  5. Setting up custom domains. You can do everything using your domain as well.
  6. Domain-to-domain forwarding. Just in case you need it we can forward emails by mask, like *@domainhostedatproxiedmail.com -> *someotherdomain.com. In this case, the MX of the first domain should be pointed to ProxiedMail and the second domain should be verified by TXT record.

Let's start

Follow this easy instruction to start receiving emails into your application.

  1. Sign up on ProxiedMail
  2. Create your API Key
  3. Install the composer library into your application.

composer require proxiedmail/php-client

Start coding/webhook implementation.

Let's say we've created t.php file with the following contents:

<?php

use ProxiedMail\Client\Config\Config;
use ProxiedMail\Client\Entities\ResponseEntity\OauthAccessTokenEntity;
use ProxiedMail\Client\Entrypoint\PxdMailApinitializer;
use ProxiedMail\Client\Facades\ApiFacade;

require 'vendor/autoload.php';


// put here your ProxiedMail credentials
$email = 'example.com';
$pass = '1';

/**
 * @var ApiFacade $facade
 */
$facade = PxdMailApinitializer::init();
/**
 * @var OauthAccessTokenEntity $r
 */
$r = $facade->login($email, $pass);

//settings bearer token. 
$config = (new Config())->setBearerToken('Bearer ' . $r->getBearerToken());
$facade = PxdMailApinitializer::init($config);

//receiving API token by bearer token
$apiToken = $facade->getApiToken();

$config = new Config();

//setting API token. You can start from here if you obtained API token.
$config->setApiToken($apiToken->getApiToken());

$api = PxdMailApinitializer::init($config);

$wh = $api->createWebhook(); //creating webhook-receiver
$proxyEmail  = $api->createProxyEmail(
    [],
    null,
    $wh->getCallUrl() //specifying webhook url
);



// while (true) with 100 seconds limit
foreach(range(0, 100) as $non) {
    echo "PROXY-EMAIL: " . $proxyEmail->getProxyAddress() . "\n";
    echo "Send the email to this proxy-email to get email payload printed here";

    //checking webhook receiver 
    $whStatus = $api->statusWebhook($wh->getId());

    echo "Webhook STATUS: \n";
    echo "Received: " . ($whStatus->isReceived() ? 'yes' : 'no') . "\n"; //printing webhook status

    //printing payload if received
    if ($whStatus->isReceived()) {
        echo "WEBHOOK PAYLOAD: \n";
        echo json_encode($whStatus->getPayload());
        break;
    }


    echo "\n";

    sleep(1);
}
Enter fullscreen mode Exit fullscreen mode

Also if you prefer you can use it without callback if you want the ability to catch more than one email:

<?php

use ProxiedMail\Client\Config\Config;
use ProxiedMail\Client\Entities\ResponseEntity\OauthAccessTokenEntity;
use ProxiedMail\Client\Entrypoint\PxdMailApinitializer;
use ProxiedMail\Client\Facades\ApiFacade;

require 'vendor/autoload.php';


// put here your ProxiedMail credentials
$email = 'example@example.com';
$pass = '1';

/**
 * @var ApiFacade $facade
 */
$facade = PxdMailApinitializer::init();
/**
 * @var OauthAccessTokenEntity $r
 */
$r = $facade->login($email, $pass);

//settings bearer token
$config = (new Config())->setBearerToken('Bearer ' . $r->getBearerToken());
$facade = PxdMailApinitializer::init($config);

//receiving API token by bearer token
$apiToken = $facade->getApiToken();

$config = new Config();

//setting API token
$config->setApiToken($apiToken->getApiToken());

$api = PxdMailApinitializer::init($config);

$proxyEmail  = $api->createProxyEmail(
    [],
    null,
    null,
    null,
    true
);



// while (true) with 100 seconds limit
foreach(range(0, 180) as $non) {
    echo "PROXY-EMAIL: " . $proxyEmail->getProxyAddress() . "\n";
    echo "Time limit is 3 mins \n";
    echo "Send the email to this proxy-email to get email payload printed here \n";

    //checking webhook receiver

    $receivedEmails = $api->getReceivedEmailsLinksByProxyEmailId($proxyEmail->getId())->getReceivedEmailLinks();
    echo "Amount of received emails: " . count($receivedEmails) . "\n";
    foreach ($receivedEmails as $receivedEmail) {
        echo "Have received email: \n";
        var_dump($receivedEmail); //you can also receive a payload here. Check out attributes

        echo "\n";
    }

    echo "\n";

    sleep(1);
}
Enter fullscreen mode Exit fullscreen mode

Payload example

All of our examples contain a payload. Example of email payload:

{
   "id":"EB442408-D500-0000-00003CC8",
   "payload":{
      "Content-Type":"multipart\/alternative; boundary=\"000000000000714564060f56f6c2\"",
      "Date":"Sat, 20 Jan 2024 02:00:25 +0000",
      "Dkim-Signature":"DKIM",
      "From":"Alex Yatsenko <sender@gmail.com>",
      "Message-Id":"<CAJj9C9dVhSJZDwRDM-H=vhzPttpg253biEvabFtEHiS4wriK8A@mail.gmail.com>",
      "Mime-Version":"1.0",
      "Received":"by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-40e9ffab5f2so10064475e9.1 for <4bd6c97b9@proxiedmail.com>; Fri, 19 Jan 2024 18:00:38 -0800 (PST)",
      "Subject":"hey mate",
      "To":"4bd6c97b9@proxiedmail.com",
      "X-Envelope-From":"sender@gmail.com",
      "X-Mailgun-Incoming":"Yes",
      "X-Received":"Received details",
      "body-html":"<div dir=\"ltr\">hey hey<\/div>\r\n",
      "body-plain":"hey hey\r\n",
      "domain":"proxiedmail.com",
      "from":"Alex Alex <sender@gmail.com>",
      "message-headers":"HEADERS JSON....",
      "recipient":"4bd6c97b9@proxiedmail.com",
      "sender":"sender@gmail.com",
      "signature":"....",
      "stripped-html":"<div dir=\"ltr\">hey hey<\/div>\n",
      "stripped-text":"hey hey",
      "subject":"hey mate",
      "timestamp":"1705716046",
      "token":"..."
   },
   "attachments":[

   ],
   "recipient":{
      "address":"4bd6c97b9@proxiedmail.com"
   },
   "receivedAt":"Sat Jan 20 2024 02:00:46 GMT+0000",
   "user":{
      "id":"1B3AAA43-11-0000-cc",
      "username":"username+t1@gmail.com",
      "token":"Bearer ...."
   }
}
Enter fullscreen mode Exit fullscreen mode

Summary

Summarizing our information you can use both ways to receive emails: via callback and also using browsing emails.
The payload contains all of the information about email and attachments.

If you have any questions please contact devphp@pxdmail.com.
Feel free to check out the documentation as well.

You can also check out our dedicated article for laravel

Top comments (6)

Collapse
 
xet7 profile image
Lauri Ojansivu

Real email is some kind of old-fashioned mailbox on Gmail, ProtonMail, etc.

Is there some examples of new-fashioned mailbox?

Collapse
 
yatsenkolesh profile image
Alex Yatsenko

Thank you for your comment.
Not really.
I call it old-fashioned because most people use email addresses straight from that services. This article is not about selling ProxiedMail as a new approach to mailing, but I'm not a fan of it. Using email addresses like @gmail.com and @protonmail.com makes it impossible to migrate fast and doesn't improve your privacy.
Meanwhile, using ProxiedMail as your email address that forwards all your incoming emails to the old-fashioned email:

  1. Make your a second password. Because it's unique and has the same strength as a password if it was generated automatically.
  2. Make your way of migrating to another real email provider much easier as you going to just change the forwarding address.

ProxiedMail is a perfect tool to be in the middle as we committed to never be affiliated with any email provider. Also, we never block your accounts as Google does for example.
After 4 years of using ProxiedMail, I feel naked and insecure when for some reason I have to provide my gmail address somewhere.

Collapse
 
xet7 profile image
Lauri Ojansivu

When managing my own domains at CloudFlare, it's possible to setup forwarding addresses.

Thread Thread
 
yatsenkolesh profile image
Alex Yatsenko

Yeah, but I don't know if you can create as many proxy emails as you want and if it's easy to access and search by as we provide on ProxiedMail.
Unfortunately, I don't know how to convince a lot of people to use it but I like the approach of creating a dedicated email for a special requestor(i.e. website). Then you can access it easily on your device and search by description or where it was used.
Not sure if we're still talking about receiving emails in PHP haha

Thread Thread
 
xet7 profile image
Lauri Ojansivu

What is URL to public repo of serverside PHP code?

Thread Thread
 
yatsenkolesh profile image
Alex Yatsenko

Unfortunately, It's not open source yet. I have to do some work before it goes to be public. The estimated release for the public is September 2024.