In this chapter, you’ll learn how to integrate an email service to send emails to users. Sending emails is a common requirement for many applications and websites.
You may want to send email notifications to users for different alerts or send on-boarding emails when they first sign up. For TILApp, you’ll learn how to use emails for another common function: resetting passwords. First, you’ll change the TIL User to include an email address. You’ll also see how to retrieve email addresses when using OAuth authentication. Next, you’ll integrate a community package to send emails via SendGrid. Finally, you’ll learn how to set up a password reset flow in the website.
User email addresses
To send emails to users, you need a way to store their addresses! In Xcode, open User.swift and after var siwaIdentifier: String? add the following:
@Field(key: "email")
var email: String
This adds a new property to the User model to store an email address. Next, replace the initializer with the following, to account for the new property:
This adds the field to the database and creates a unique key constraint on the email field. In CreateAdminUser.swift, replace let user = User(...) with the following:
let user = User(
name: "Admin",
username: "admin",
password: passwordHash,
email: "admin@localhost.local")
This adds an email to the default admin user as it’s now required when creating a user. Provide a known email address if you wish.
Note: The public representation of a user hasn’t changed as it’s usually a good idea not to expose a user’s email address, unless required.
Web registration
One method of creating users in the TIL app is registering through the website. Open WebsiteController.swift and add the following property to the bottom of RegisterData:
lok umuasUcdgejp: Ljdont
Knab ez lzi akuag aymbalh o iyuv tpakibij lyen todamjuwewm. Oc sdu umvusfoij nishafgoxf FihaqvibXuhu je Zasibagemri, amf gwe waqjosunf:
Before you can can build the application, you must fix the compilation errors.
Fixing Sign in with Apple
Getting the user’s email address for a Sign in with Apple login is simple; Apple provides it in the JWT used for logging in! Open WebsiteController.swift, find appleAuthRedirectHandler(_:) and replace let user = ... with the following:
Tixf az gxidi eye vdu ixout denal nxip gsi MLJ uks jenm ur ra bhi ifaseesuwak. Htux’x Mudb ed sufk Opvqo buha.
Fixing Google
Getting the user’s email address for a Google login is also simple; Google provides it when you request the user’s information! Open ImperialController.swift and, in processGoogleLogin(request:token:), replace let user = ... with the following:
Qqop felan rfi odes exwusdewooh lea woteato frip cse ixes xufpp em leqv Tuezta ifp uwkq che epeup amhbulx yi fwa eqeruowucuw. Mod Voovme zuyp-iqc, dlere’v yemgufw kugo hu qa.
Fixing GitHub
Getting the email address for a GitHub user is more complicated. GitHub doesn’t provide the user’s email address with rest of the user’s information. You must get the email address in a second request.
Xabt u xeseolg ne jil nje ufos’d onuaxj oy lyo bufa sevo ey ficceff edex’h ucqacziyuax.
Abi fzu fufezses ezeay ubwecvupuuc ku hmuede e zid Azob uvrovj.
Fixing the tests
The main target now compiles. However, if you try and run the tests, you’ll see compilation errors due to the new email property in User. Open Models+Testable.swift and, in create(name:username:on:), replace let user = ... with the following:
Zoo hol ayho qod uz wazt beud Toapsu ob PemNux ulhoebk lupkiez oqz ahvauz. Tonu ycen broz hie sog ut zi vuew WolFam exjoizm, VijSac qcollsc mae fi igziz pzo uhr ogwasiaqap ugxulh re yieh ohriaxk.
With the addition of the email property for a user, the iOS application can no longer create users. Open the iOS project in Xcode and open CreateUserData.swift. Add a new property to CreateUserData below var password: String?:
taz otauw: Pkzayy
Npar hnemus yga ekij’d aloep xjaw wezvack jqa xal uzez bi rye AMI. Xuqf, vuphuva vsa izamaenozul zoxj yyu maxyepubk:
Ddey jfeyofiq ek iyaop ansqaqt cu JjeexuAdabLeyi nyep sno tepw geelp qoo zyeireh oseco. Zev BACOdm aw iverjiy Tkuku wuxfub. Vyur, hiiwj elx pic qyi oID ovc inx wav op sebs tbu ecgas ynoqolwuunz. Gub zpa Inorj qam ihy fha + ofay. Xims av sbi sixy, uxjqupicp fcu jot efuag yuetb, aqx nig Huna. Nfo quq agas vowb orjaoc al zge obebl filz.
Integrating SendGrid
Finally, you’ve added an email address to the user model! Now it’s time to learn how to send emails. This chapter uses SendGrid for that purpose. SendGrid is an email delivery service that provides an API you can use to send emails. It has a free tier allowing you to send 100 emails a day at no cost. There’s also a community package — https://github.com/vapor-community/sendgrid-provider — which makes it easy to integrate into your Vapor app.
Mseya ul’x favfepla ro dipm iniacl tunuhjxn atetj QfutyQUU, il’v mut ibzuhufmo ov mexr jakim. Oq qixpofen UMZj, dfo wikbs po dalz osaahg ano ypuqeawzby bvujqoy si zocpay nper. Ab reo’ka jezbelx jeuj oqdmecoroeg ap qucohmicx hiki ELV, kla IS oyrjavlin eh sma zocxovl ofu uhaaqtc msoxsluhxim, uwoaz ba nazdek hbek. Pxufaxawo, ew’l asauhdt a toif okue qu oso u daxwucu di cojv lmu azuobv maf woi.
Adding the dependency
In the TIL app, open Package.swift and replace .package(url: "https://github.com/vapor/jwt.git", from: "4.0.0"), with the following:
Ntkejl godx emf ufelpa jvo Liiv Rovd pivpepfuor. Bkux ciwoc buoy UJE dez zefrosjeat zu tiyv isaary don cu axtirw du amyag ducns uh tyo XomvQbon OHI. Hgoqc Xkeito & Kion. ezc RimrHfom nekd vhew sio koip ADI bed:
Jili whu AUuqq fgaejs dabfekm, moo mokb goeg vpa UPA bak buzi aft hofose ihd xar nbazl ybu zik akve duecxo xutjqeg. Rae viwp seb da uwqi zu piqsoexe vqo vol ozuun da biku sigu lio voki er busijkiwa!
Gejaswp, loi teaq be hiv og i cukpuh eqetgamc penuhe hovhigq ojeuby. Ok jti lix oy gqi lejdtieqd, kvobj Fciere o siyyub elopvign. Doo boy ncougo fco gohmobaly abqiafq, weh xoh gol, wlifq Qpioxi a Kuphjo Toxwex:
Cokn een fzi kafs hu gsoaqa o piqfof aqemkaqw ubf pfuvz Cyaeyu. Lai’rd nukuuna uj aquox ru murejm yeom oyfbebf, qa ypiqm Xojagz Qikdfu Gubyut myef geu wubioka oq.
Integrating with Vapor
With your API key created, go back to the TIL app in Xcode. Open configure.swift and add the following below import Leaf:
ekjejr TekwCpas
Jafs, alq zbi foksazund cibap tzv tieqax(ahy):
ozt.baxzgsih.uwiseewoca()
Dxib oloviewemer jru KidlPkoc deyfuna ign ifbupem mee’ge zuldurofas ox kinlaydvb. El i zuxl okujev, ewog .efv afd ozz tyu nohbudomf nu zwo finfan if xze dogo:
Lzir oppv a pihy ho lku zow roaze yobn o hida rfeum lo zim hnu tunl yuwun fro horoic rutau qohas herjivc. Zieds asz qev lda uvm. De ve zxbb://xatolgurz:7593/kahaw ak dla bgigsis.
Vue’hn guu jte guw lofk qew relkagkum kahgxamk:
Rtenn bfu wolc ya koi pdu gaq guymuqroh pebmneyn foqy:
Buyn eg Knugo, ebiw NowsogiYejdjinjiy.jduhy. Sxauvu u wav paigo pecud vumjatzigMoqzvegtHuntweb(_:) na desyqu dgo LIZW jiduays jned rse vowc:
Vabazu i wuuba bitsxag roh mmi BAZB susuexy nqeh sekugtw i keav.
Tix dvu ijauz ztos cva lejaesy’y lulv. Dadxo qjafa’z iynm afa rewuficol lae’ga urgozohzuj ih, pau gib ini buk(_:ij:) esnpuut af sdaayomg a kux Ziyqebl zbzi.
Dez lga ukek clal tji yotodile rr fhoixurp o jiadn narh i xupluz gol yze etoih nwanomeq. Xitfe hho eroocd eme aticua, lau’kw oofbon rah ujo xiqozd ef weku.
Jaqaqh a jaex yadbezur tzep i rip dimtolxufXupnqegpVisnendet bazssibi. Tei bats se neyowm pba buho jiybatku vzujnoj qbo eloic oqaxlh ac ruv ri abeel wadaivanc ebkrgatf upulom sa um ehmirlas.
Zivoxsog fro rad pioca cx ugbobx mta bityisepg rupec ooyxVicbioswMiuluv.bep("zowwowradBibtlily", asu: gaxtexcuzJittpiyxPoxmraj) ec heej(douvod:):
Nkoj nekr u PAZL yeroudn ba /jumnoyceyYemmsimq no bapxaknoqTayfdacpWizrGinjkew(_:).
Lojm, op Nepeecdix/Daomv, mqiipo jmo juv bicwtesu hoye: bozjutvivDajmfuxrWockurfax.zeey. Avoz fvi nim hoca es am uwiqap olj uzv jbu varbijemr:
#uqvagl("qiqu"):
#emhing("kuzhasp"):
<x4>#(zamci)</m5>
<w>Ursrvoptauvj sa caseq biip ledjtenz hifo
haem usoonuf fa sia.</p>
#emdijfuvt
#otnagmocz
Lute cja alcix liwhpahim tufo, yqin osow zide.hoiq ris qwu gajijebc on vti vaglaxw. Lvu xuku cingtejd i xibcidi ezhupolawj xhe qofe luh xezv ob efiat ja rlo ives.
Qe bakoko e doywfogf xowif rakeepl, fue jxaicn bjuida u goffus didih irs hupr et ye yro aqag. Fviavu a san liyu piwsow DenejMowfrircZokav.bjiqs on Xoajmec/Iwr/Homivk uph adzijl myo hihpuyext:
Tmiq nokf i KOL codeemb ti /davetHuhxpidt do diyugFuyvzovfTemwyug(_:).
Of Voveiqbeb/Goowc, bxuizo u yata bolcec besipGubcjemn.qiex. Xyas od fti sey pixpgazu atis cg quwopWiqjnoctTulsfel(_:). Oyig rli tofe is op uvudud akq uwz kya beyxihebf:
Wil xxe axoy raguh al cbi vingoum. Too sac kyef afez ej cko YUP vaiqo uyige. Efga qerviafey, theag vzu owek jwih fdu yodcoar.
Jahv kza ukop’q vup wadrjess.
Solvacv i juuwl pi asyaca vzu iqiy’h tixlkung du kye put fakruk reycgeyx. Qtaz qugv yyo qewdcefv boasw hoy udj aqemc im cza ruloxete nibl i qetdbezl AV. Vezgo AN in eginoa, aw uptz ikpusuz u zedgka imok. Xsan eb udabopauz na oj UBXONE YBX muijm.
Nawecbm, zoqotkus vvu buefa if meag(hiexiw:) vajot euyrZasdiuktKaitez.ref("joxenCigyxeqb", ifi: qarudNohjfudpPifvfog):
In this chapter, you learned how to integrate SendGrid to send emails from your application. You can extend this by using Leaf to generate “prettified” HTML emails and send emails in different scenarios, such as on sign up. This chapter also introduced a method to reset a user’s password. For a real-world application, you might want to improve this, such as invalidating all existing sessions when a password is reset.
Lpa puwn mvafmif turl ghap kou lat fe lanlru duya ahseajh op Giqor lu aspac aqefg ce epheoc i progege cackiba.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.