Временная почта
на Go.
Одноразовая почта для Go — в один HTTP-запрос.
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("POST",
"https://evilmail.pro/api/temp-email",
bytes.NewBufferString(`{"ttlMinutes": 30}`))
req.Header.Set("X-API-Key", os.Getenv("EVILMAIL_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var r struct {
Data struct {
Email string `json:"email"`
SessionToken string `json:"sessionToken"`
} `json:"data"`
}
json.NewDecoder(resp.Body).Decode(&r)
fmt.Println("Inbox ready:", r.Data.Email)
}Поднимите временную почту в Go всего в несколько строк: API одноразовой почты EvilMail позволяет создавать временные ящики, опрашивать входящие сообщения и извлекать OTP-коды прямо из ваших тестов или CI-конвейера. Вместо того чтобы возиться с настоящим почтовым ящиком или парсить веб-интерфейс, вы обращаетесь к обычным HTTP-эндпоинтам через net/http и декодируете JSON — без сторонних SDK и headless-браузера. Решение создано для тестирования проверки email в Go, дымовых тестов регистрации и любых сценариев, где нужен настоящий работающий адрес по требованию.
Зачем использовать временную почту на Go
Автотесты регистрации
Регистрируйте свежую одноразовую почту в Go для каждого сквозного прогона тестов, чтобы аккаунты никогда не пересекались. Каждый ящик реален и принимает письма, поэтому ваш процесс регистрации ведёт себя ровно так же, как в продакшене.
OTP и проверка email
Опросите ящик, возьмите письмо с подтверждением и извлеките 6-значный код регулярным выражением — всё в одной горутине Go. Идеально для тестирования подтверждения и двухфакторных сценариев без участия человека.
CI/CD-конвейеры
Поскольку это всего лишь net/http и ключ API из переменной окружения, один и тот же код работает локально и в GitHub Actions или GitLab CI. Никакого SMTP-сервера и учётных данных почтового ящика, которые нужно ротировать.
Нагрузочные и многоаккаунтные тесты
Создавайте множество независимых ящиков одновременно с помощью горутин, чтобы смоделировать сотни одновременно регистрирующихся пользователей. Каждый токен сессии изолирует один ящик, поэтому параллельные тесты остаются чистыми.
Процесс — временная почта Go за 3 вызова
Создать одноразовый ящик
// createInbox spins up a disposable EvilMail inbox and
// returns its address plus the session token used to poll it.
func createInbox(key string) (email, token string, err error) {
body := bytes.NewBufferString(`{"ttlMinutes": 30}`)
req, err := http.NewRequest("POST",
"https://evilmail.pro/api/temp-email", body)
if err != nil {
return "", "", err
}
req.Header.Set("X-API-Key", key)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", "", err
}
defer resp.Body.Close()
var r struct {
Data struct {
Email string `json:"email"`
SessionToken string `json:"sessionToken"`
} `json:"data"`
}
if err := json.NewDecoder(resp.Body).Decode(&r); err != nil {
return "", "", err
}
return r.Data.Email, r.Data.SessionToken, nil
}Опрашивать, пока письмо не придёт
// Message mirrors one row from the inbox listing.
type Message struct {
UID int `json:"uid"`
From string `json:"from"`
Subject string `json:"subject"`
}
// waitForMessage polls the inbox ~20 times, 3s apart, until at
// least one message lands, then returns the first one.
func waitForMessage(key, token string) (Message, error) {
url := "https://evilmail.pro/api/temp-email/" + token
for i := 0; i < 20; i++ {
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("X-API-Key", key)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return Message{}, err
}
var r struct {
Data struct {
Messages []Message `json:"messages"`
} `json:"data"`
}
json.NewDecoder(resp.Body).Decode(&r)
resp.Body.Close()
if len(r.Data.Messages) > 0 {
return r.Data.Messages[0], nil
}
time.Sleep(3 * time.Second) // wait, then retry
}
return Message{}, fmt.Errorf("timed out waiting for email")
}Прочитать сообщение и извлечь код
// otpRe matches a standalone 6-digit verification code.
var otpRe = regexp.MustCompile(`\b(\d{6})\b`)
// readCode fetches a message body and pulls the 6-digit OTP.
func readCode(key, token string, uid int) (string, error) {
url := fmt.Sprintf(
"https://evilmail.pro/api/message/%d?token=%s", uid, token)
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("X-API-Key", key)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
var r struct {
Data struct {
Text string `json:"text"`
HTML string `json:"html"`
} `json:"data"`
}
json.NewDecoder(resp.Body).Decode(&r)
// Regex over the plain-text body (fall back to HTML).
m := otpRe.FindStringSubmatch(r.Data.Text)
if m == nil {
return "", fmt.Errorf("no 6-digit code found")
}
return m[1], nil
}Временная почта Go — FAQ
Q1Как получить адрес временной почты в Go?−
Отправьте POST-запрос на https://evilmail.pro/api/temp-email с заголовком X-API-Key и JSON-телом вида {"ttlMinutes": 30}. В ответе будут data.email (адрес) и data.sessionToken (используется для опроса этого ящика). Функция createInbox выше делает именно это с помощью net/http и encoding/json — без всякого SDK.
Q2Можно ли использовать это для автотестов?+
Да, это основной сценарий. Весь процесс — это обычный HTTP, поэтому он легко встраивается в тестовые файлы Go, задачи CI или нагрузочные скрипты. Читайте ключ API из переменной окружения, например EVILMAIL_KEY, создавайте ящик под каждый тест и удаляйте его по истечении TTL. Вы можете создавать множество ящиков одновременно с помощью горутин для параллельных тестов.
Q3Как извлечь OTP из письма?+
После того как опрос вернёт сообщение, выполните GET https://evilmail.pro/api/message/{uid}?token={sessionToken}, чтобы получить его тело. Затем примените регулярное выражение к data.text (или data.html). Отдельно стоящий 6-значный код соответствует шаблону \b(\d{6})\b — скомпилируйте его один раз через regexp.MustCompile и используйте FindStringSubmatch для захвата цифр, как показано в readCode.
Q4Нужен ли ключ API и есть ли ограничения по частоте?+
Да — каждый запрос должен передавать ваш ключ в заголовке X-API-Key, и для чтения сообщений он тоже требуется. Никогда не зашивайте ключ в код; загружайте его из переменной окружения. Ограничения по частоте применяются к каждому ключу и достаточно щедры для обычного тестирования и использования в CI; если вы запускаете тяжёлые нагрузочные тесты, добавьте небольшую задержку между вызовами (цикл опроса уже спит 3 секунды между попытками).
Q5Сколько живёт ящик?+
Время жизни ящика задаётся значением ttlMinutes, которое вы передаёте при создании — например 30 минут. Как только TTL истекает, ящик и его сообщения удаляются, а токен сессии перестаёт возвращать письма, поэтому создавайте свежий ящик под каждый прогон, а не переиспользуйте старый токен.
Временная почта на других языках
Один API-ключ. Одноразовые ящики в масштабе.
Создавайте неограниченное число одноразовых адресов, опрашивайте их по HTTP и получайте коды подтверждения прямо в тесты и CI. Бесплатно на старте; собственные домены и повышенные лимиты на платных тарифах.

