DevGang
Авторизоваться

Изучаем 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, чтобы вы легко могли скачать или склонировать его!

Другие статьи из цикла:

#Golang
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу