Изучаем Go - Повторная отправка электронной почты через API
Список рассылки сообщений
Ранее мы рассмотрели, как можем использовать шаблоны Go для быстрого использования размеченного текста. На этот раз используем новые навыки форматирования с пользой! Для этого мы притянем пакет mailgunner, который собрали несколько недель назад. Видите, я же говорил вам, что у меня были на него планы.
Сразу же приступим к созданию того, что мы делали в двух предыдущих постах, поэтому, возможно, если вы их еще не читали, захотите уделить время их прочтению.
Еще раз начнем с начала! Если вы до сих пор следили за моей серией постов, вы не удивитесь, что в примерах кода мы снова начнем с текущих импортов. Но, наверное, заметите новую стандартную библиотеку, которую на этот раз мы будем использовать чтобы избавиться от ошибок. Думаю, вы заметите, что на этот раз мы обрезали большинство ненужных структурных частей и просто оставили []Users с записями name, username и email. Как я уже говорил в прошлый раз, сейчас я использую это только для демонстрационных целей, поэтому я просто выбросил эту часть.
Обратите внимание, что импорт из пакета mailgunner, которого на самом деле нет на GitHub, немного отличается. Наличие сокращения c позволяет нам использовать импорт как просто букву «c» - так, что мы можем напечатать c.SomeFunc () вместо использования client. После следующего поста, я немного подправлю код mailgunner и размещу его на GitHub.
package main import ( "bytes" "encoding/json" "errors" "fmt" "io/ioutil" "net/http" "text/template" "github.com/shindakun/envy" c "github.com/shindakun/mailgunner/client" ) const apiurl = "https://api.mailgun.net/v3/youremaildomain.com" type Users []struct { Name string `json:"name"` Username string `json:"username"` Email string `json:"email"` }
Наконец-то мы подошли к первому реальному куску нового кода. checkStatusCode() - это небольшая служебная (или вспомогательная) функция, которую мы используем для проверки, ответа HTTP-кода (200 или нет). Удаленные сервера, которые мы используем, должны отвечать на наш код только 200 OK, если мы не собираемся возвращать ошибку. Вы можете спросить, почему мы возвращаем ошибку, а не просто выкидываем варнинги здесь? Это потому что мы хотим, чтобы код начинал выбрасывать варнинги и выходил из блока кода, из которого он вызывается, так, что вам не нужно специально отслеживать его. Вскоре мы с вами рассмотрим вариант изящной обработки ошибок. В любом случае, всегда проверять коды ответов- это очень хорошая идея. Мы пропустили проверки в предыдущих примерах, но с этого момента я постараюсь не забывать о них. Возможно, мы даже соберем специальный пакет «utilities» для всего, что можно использовать повторно.
func checkStatusCode(s int) error { if s != 200 { err := fmt.Sprintf("unexpected status code: %d", s) return errors.New(err) } return nil }
Метод sendEmail() немного похож на код, который мы написали для отправки нашего тестового сообщения в посте mailgunner. В этот раз мы будем передавать значения в bytes.Buffer, который будет содержать заполненный шаблон электронной почты и адрес электронной почты. Обратите пристальное внимание на то, что я меняю поля «from» и «to» в mgc.FormatEmailRequest(), так что я могу отправлять электронные письма, но только на работающие электронные письма - пожалуйста, не пытайтесь отправлять варианты из примера. Наверное они все фейковые, но спам все еще недоработан.
func sendEmail(buf bytes.Buffer, email string) { mgKey, err := envy.Get("MGKEY") if err != nil { panic(err) } mgc := c.NewMgClient(apiurl, mgKey) req, err := mgc.FormatEmailRequest(email, "youremailaddress@", "Test email", buf.String()) if err != nil { panic(err) } res, err := mgc.Client.Do(req) if err != nil { panic(err) } defer res.Body.Close()
Используем наш помощник (helper), чтобы проверить возвращенный код состояния и запаниковать (выбросить варнинги), если код не такой, как нужно. Мы выводим наши результаты в стандартном формате, как и в каждом из примеров.
if err = checkStatusCode(res.StatusCode); err != nil { panic(err) } body, err := ioutil.ReadAll(res.Body) if err != nil { panic(err) } fmt.Println(string(body)) }
Хорошо, а теперь давайте окунемся в наш дорогой метод main ()! Если вы читали мои предыдущие статьи, то многое уже будет вам знакомо. Надеюсь, что эта итерация поможет вложить мне и вам в голову самые основы.
func main() { APIURL := "https://jsonplaceholder.typicode.com/users" req, err := http.NewRequest(http.MethodGet, APIURL, nil) if err != nil { panic(err) } client := http.DefaultClient resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() if err = checkStatusCode(resp.StatusCode); err != nil { panic(err) } body, err := ioutil.ReadAll(resp.Body) if err != nil { panic(err) } var u Users json.Unmarshal(body, &u)
Наше сообщение с полнофункциональным приложением списка рассылок, позволит легко загружать пользовательские сообщения и т. д. Мы, как всегда, пытаемся с вами узнать что-нибудь новенькое. Если хорошо попрактиковаться, можно легко написать полноценное приложение за один день. Итак, напоследок, рассмотрим наших пользователей и передадим результаты заполненного шаблона в метод sendEmail(), который будет выполнять фактическую отправку.
msgText := "Hi {{.Name}}! Or should I call you, {{.Username}}? There is a new post!\n\n" t := template.Must(template.New("msg").Parse(msgText)) for _, v := range u { var buf bytes.Buffer err := t.Execute(&buf, v) if err != nil { panic(err) } sendEmail(buf, v.Email) } }
Вот и все! В следующий раз мы немного улучшим наш пакет mailgunner и запушим его на GitHub, чтобы вы легко могли скачать или склонировать его!
Другие статьи из цикла:
- Изучаем Go - создание загрузчика (часть 1)
- Изучаем Go - создание загрузчика (часть 2)
- Изучаем Go - создание загрузчика (часть 3)
- Изучаем Go - создание загрузчика (часть 4)
- Изучаем Go - создание загрузчика (часть 5)
- Изучаем Go - Использование REST API
- Изучаем Go - Продолжаем работать с REST API
- Изучаем Go - Отправка REST-запросов
- Изучаем Go - Используем REST API в паре с шаблонами проектирования
- Изучаем Go - Повторная отправка электронной почты через API
Изучаем Go - Давайте станем модульными!скороИзучаем Go - Давайте станем модульными снова!скороИзучаем Go - Сборка DevLog Часть 01скороИзучаем Go - Сборка DevLog Часть 02скоро