1
1

00:00:00,830  -->  00:00:01,970
[Jose] Hi and welcome back.
2

2

00:00:01,970  -->  00:00:03,990
In this video, we are going to send emails
3

3

00:00:03,990  -->  00:00:05,770
from within our app.
4

4

00:00:05,770  -->  00:00:09,540
We're going to start by creating a new folder in our project
5

5

00:00:09,540  -->  00:00:11,992
and I'm going to call it libs.
6

6

00:00:11,992  -->  00:00:14,399
This stands for libraries.
7

7

00:00:14,399  -->  00:00:16,880
Here's where you'll normally put code
8

8

00:00:16,880  -->  00:00:21,510
that interacts with other services or other applications.
9

9

00:00:21,510  -->  00:00:24,140
Because we're going to be interacting with Mailgun,
10

10

00:00:24,140  -->  00:00:29,140
I'm going to put its code inside libs.mailgun.py.
11

11

00:00:29,540  -->  00:00:31,720
I've create a file called Mailgun.
12

12

00:00:31,720  -->  00:00:33,610
If we go back to Mailgun,
13

13

00:00:33,610  -->  00:00:37,023
you can see here that there is some Python sample code.
14

14

00:00:37,870  -->  00:00:40,521
Let's start by copying that.
15

15

00:00:40,521  -->  00:00:43,990
We're gonna try to make sure that our account is working
16

16

00:00:43,990  -->  00:00:45,453
before we do anything else.
17

17

00:00:46,566  -->  00:00:51,300
Copy that, come over here to this Mailgun.py file,
18

18

00:00:51,300  -->  00:00:52,233
and paste it in.
19

19

00:00:53,070  -->  00:00:54,940
Now you can see Python complains
20

20

00:00:54,940  -->  00:00:57,150
that there is an unresolved reference.
21

21

00:00:57,150  -->  00:01:01,403
We do have to import the requests module.
22

22

00:01:02,280  -->  00:01:04,950
Now if you don't have the requests module installed,
23

23

00:01:04,950  -->  00:01:08,200
open the PyCharm preferences, go to project interpreter,
24

24

00:01:08,200  -->  00:01:10,483
and then instal requests.
25

25

00:01:11,440  -->  00:01:12,811
Notice that I've got it here,
26

26

00:01:12,811  -->  00:01:15,140
but if it didn't, you could press the plus icon,
27

27

00:01:15,140  -->  00:01:17,513
find requests and instal it.
28

28

00:01:21,400  -->  00:01:24,470
Now what this is doing is it's sending a post request
29

29

00:01:24,470  -->  00:01:29,470
to this URL with this authentication information
30

30

00:01:29,660  -->  00:01:31,683
and this payload of data.
31

31

00:01:32,720  -->  00:01:35,560
With that information, we can go back to our account
32

32

00:01:35,560  -->  00:01:39,400
and fill in our details because these test details
33

33

00:01:39,400  -->  00:01:41,560
won't actually work, which is something
34

34

00:01:41,560  -->  00:01:43,900
that I have frequently complained about
35

35

00:01:43,900  -->  00:01:47,230
to Mailgun developers, but this won't actually work.
36

36

00:01:47,230  -->  00:01:51,560
It'll just give you a sample error, really.
37

37

00:01:51,560  -->  00:01:54,600
We do have to fill it in with our account details.
38

38

00:01:54,600  -->  00:01:57,070
If you go over to your domain information,
39

39

00:01:57,070  -->  00:01:59,480
make sure that you've selected your sandbox domain,
40

40

00:01:59,480  -->  00:02:02,110
I don't think you'll have any others just now,
41

41

00:02:02,110  -->  00:02:04,363
and copy your API key.
42

42

00:02:06,070  -->  00:02:08,640
And paste it in to the authentication field
43

43

00:02:09,870  -->  00:02:12,600
and replace the first part of the URL
44

44

00:02:14,530  -->  00:02:19,203
up until slash messages with the URL in your domain.
45

45

00:02:20,520  -->  00:02:22,910
From can be anything you like,
46

46

00:02:22,910  -->  00:02:27,910
but in this case, we're going to say do not reply.
47

47

00:02:29,110  -->  00:02:33,100
This is gonna be do not reply at
48

48

00:02:35,230  -->  00:02:36,550
all of this.
49

49

00:02:36,550  -->  00:02:38,030
We're just gonna do that to keep things safe.
50

50

00:02:38,030  -->  00:02:39,300
Instead of do not reply,
51

51

00:02:39,300  -->  00:02:42,230
I'm gonna call it pricing service in fact.
52

52

00:02:42,230  -->  00:02:43,710
Pricing service and the email address
53

53

00:02:43,710  -->  00:02:47,620
is do-not-reply@sandbox blah blah blah.
54

54

00:02:47,620  -->  00:02:49,690
Let's not forget the G at the end.
55

55

00:02:49,690  -->  00:02:51,523
To is going to be me.
56

56

00:02:52,700  -->  00:02:54,700
That is one of our email addresses.
57

57

00:02:54,700  -->  00:02:56,140
Subject is gonna be hello.
58

58

00:02:56,140  -->  00:02:58,713
The text, testing some Mailgun awesomeness.
59

59

00:03:02,159  -->  00:03:03,330
Let's run it.
60

60

00:03:03,330  -->  00:03:05,690
If you press play, remember you're gonna run
61

61

00:03:05,690  -->  00:03:08,970
this run configuration here, which is app.py.
62

62

00:03:08,970  -->  00:03:13,010
Do right-click Mailgun and run the Mailgun file.
63

63

00:03:13,010  -->  00:03:14,130
That's what we want to do.
64

64

00:03:14,130  -->  00:03:15,160
Finished.
65

65

00:03:15,160  -->  00:03:16,820
No information given to us.
66

66

00:03:16,820  -->  00:03:18,260
Now we just have to wait for an email,
67

67

00:03:18,260  -->  00:03:20,070
which I hope will arrive.
68

68

00:03:20,070  -->  00:03:22,430
But if you do want to see some information,
69

69

00:03:22,430  -->  00:03:25,550
you can, actually this one, actually do anything.
70

70

00:03:25,550  -->  00:03:28,290
The key, I may have noticed
71

71

00:03:29,190  -->  00:03:30,670
we didn't actually run the function.
72

72

00:03:30,670  -->  00:03:32,580
So, it won't have done anything.
73

73

00:03:32,580  -->  00:03:34,730
We can try again now actually running the function
74

74

00:03:34,730  -->  00:03:36,683
and printing its result.
75

75

00:03:39,010  -->  00:03:41,610
We have ourselves a response for 400.
76

76

00:03:41,610  -->  00:03:42,930
That means that it was an error
77

77

00:03:42,930  -->  00:03:47,720
because this is not one of my approved receivers.
78

78

00:03:47,720  -->  00:03:49,270
Let's try with a different one.
79

79

00:03:50,290  -->  00:03:51,880
Now we have response 200,
80

80

00:03:51,880  -->  00:03:55,220
which means all good, this is okay.
81

81

00:03:55,220  -->  00:03:57,720
I should receive an email momentarily,
82

82

00:03:57,720  -->  00:04:01,973
but this is the main part of sending email with Mailgun.
83

83

00:04:02,830  -->  00:04:04,670
We are going to make it a little bit nicer
84

84

00:04:04,670  -->  00:04:08,010
because we don't want to just send a simple message,
85

85

00:04:08,010  -->  00:04:12,500
we want to send a more complicated message I guess
86

86

00:04:12,500  -->  00:04:17,010
where we include some information about our pricing service
87

87

00:04:17,010  -->  00:04:21,260
and about the item that has just broken the limit
88

88

00:04:21,260  -->  00:04:22,260
that the user wants.
89

89

00:04:23,254  -->  00:04:24,563
We're going to import os.
90

90

00:04:25,910  -->  00:04:29,230
We're gonna import List from the typing module.
91

91

00:04:29,230  -->  00:04:31,010
You'll see why in just a moment.
92

92

00:04:31,010  -->  00:04:35,160
From requests, we're gonna import Response and post.
93

93

00:04:35,160  -->  00:04:37,970
We're gonna just remove this here and just use the post
94

94

00:04:37,970  -->  00:04:40,010
that has been imported from request.
95

95

00:04:40,010  -->  00:04:43,180
And then what we're gonna do is we're gonna create a class.
96

96

00:04:43,180  -->  00:04:45,990
We're gonna put this inside a Mailgun class
97

97

00:04:45,990  -->  00:04:48,940
so that interacting with the method is a little bit easier.
98

98

00:04:50,540  -->  00:04:52,563
We're gonna create a class method send_mail.
99

99

00:04:53,830  -->  00:04:56,820
This is gonna take in four things:
100

100

00:04:56,820  -->  00:04:59,620
an email, which is gonna be a list of strings,
101

101

00:04:59,620  -->  00:05:03,360
a subject, some text, and some HTML.
102

102

00:05:03,360  -->  00:05:06,203
The HTML really is gonna be optional for the most part.
103

103

00:05:07,060  -->  00:05:09,890
This is gonna return a response.
104

104

00:05:09,890  -->  00:05:12,750
Notice that the response that is being returned
105

105

00:05:12,750  -->  00:05:14,790
is a requests object
106

106

00:05:14,790  -->  00:05:16,820
so something from this requests library.
107

107

00:05:16,820  -->  00:05:17,700
That's totally fine.
108

108

00:05:17,700  -->  00:05:18,543
You can do that.
109

109

00:05:20,690  -->  00:05:23,770
Next, we're going to grab all of this
110

110

00:05:24,650  -->  00:05:29,650
and say response equal the result of calling all of that.
111

111

00:05:30,210  -->  00:05:31,940
Now we can delete this thing here
112

112

00:05:31,940  -->  00:05:33,490
and we can delete that as well.
113

113

00:05:36,580  -->  00:05:41,350
Now here we may want to reformat this a little bit.
114

114

00:05:41,350  -->  00:05:43,900
So, you can select it all and then go to code
115

115

00:05:43,900  -->  00:05:46,100
and press reformat code.
116

116

00:05:46,100  -->  00:05:48,110
That will reformat it for you.
117

117

00:05:48,110  -->  00:05:49,060
If you don't like the format,
118

118

00:05:49,060  -->  00:05:51,930
you can play around with it a little bit as well.
119

119

00:05:51,930  -->  00:05:55,443
Now that we've got our response, we're gonna say
120

120

00:05:55,443  -->  00:06:00,443
if the response status code is not 200,
121

121

00:06:04,200  -->  00:06:08,290
then we will raise a Mailgun exception.
122

122

00:06:08,290  -->  00:06:12,323
We're gonna say an error occurred while sending email.
123

123

00:06:14,200  -->  00:06:16,260
Otherwise we're gonna return response.
124

124

00:06:16,260  -->  00:06:18,270
Now as you may have guessed, Mailgun exception
125

125

00:06:18,270  -->  00:06:19,353
doesn't yet exist.
126

126

00:06:25,260  -->  00:06:26,960
But now it does.
127

127

00:06:26,960  -->  00:06:27,910
There we have that.
128

128

00:06:29,010  -->  00:06:31,380
Next, we have to make sure that we are using
129

129

00:06:31,380  -->  00:06:33,347
the arguments to our send_mail.
130

130

00:06:34,430  -->  00:06:37,410
Instead of to and hard-coding an email address,
131

131

00:06:37,410  -->  00:06:39,440
we can use email.
132

132

00:06:39,440  -->  00:06:42,850
Instead of subject hello, we can use subject.
133

133

00:06:42,850  -->  00:06:45,480
Instead of text, we can use text.
134

134

00:06:45,480  -->  00:06:48,213
The final HTML argument is just HTML.
135

135

00:06:49,073  -->  00:06:52,810
That can include some option HTML on the email,
136

136

00:06:52,810  -->  00:06:55,210
which will be shown instead of the text
137

137

00:06:55,210  -->  00:06:57,510
if the recipient's viewer,
138

138

00:06:57,510  -->  00:07:01,273
HTML viewer or email viewer accepts HTML.
139

139

00:07:03,270  -->  00:07:04,103
That's about it.
140

140

00:07:04,103  -->  00:07:06,520
This is everything we need to actually send email.
141

141

00:07:06,520  -->  00:07:07,930
We're gonna do a couple more things
142

142

00:07:07,930  -->  00:07:09,960
just to make it more resilient.
143

143

00:07:09,960  -->  00:07:14,903
We're going to read the API key from os.environ.
144

144

00:07:15,810  -->  00:07:20,540
We're gonna see MAILGUN_API_KEY defaulting to none
145

145

00:07:20,540  -->  00:07:24,610
and MAILGUN_DOMAIN which is also gonna come
146

146

00:07:24,610  -->  00:07:26,523
from the MAILGUN.
147

147

00:07:29,060  -->  00:07:29,893
There we go.
148

148

00:07:32,380  -->  00:07:36,183
Then we're gonna hard-code from title to be pricing service
149

149

00:07:37,762  -->  00:07:42,017
and the from email to be this one.
150

150

00:07:46,320  -->  00:07:47,260
Why do this?
151

151

00:07:47,260  -->  00:07:49,660
It just makes things a little bit more readable.
152

152

00:07:50,570  -->  00:07:54,350
Next, the API key is going to be replacing that
153

153

00:07:54,350  -->  00:07:58,180
and the domain is going to be replacing that.
154

154

00:08:02,360  -->  00:08:04,830
But we're gonna use an f-string for it.
155

155

00:08:04,830  -->  00:08:07,573
Now these do require cls in front of them.
156

156

00:08:10,210  -->  00:08:12,370
In here, we're also gonna put an f-string.
157

157

00:08:12,370  -->  00:08:14,917
Instead of this, we're gonna have FROM_TITLE.
158

158

00:08:17,490  -->  00:08:19,923
Instead of this,
159

159

00:08:23,560  -->  00:08:24,970
we're gonna have FROM_EMAIL.
160

160

00:08:24,970  -->  00:08:25,803
There we go.
161

161

00:08:25,803  -->  00:08:27,160
That's just a little bit cleaner.
162

162

00:08:27,160  -->  00:08:28,850
The constants that are never gonna change,
163

163

00:08:28,850  -->  00:08:31,380
it extracted it to the top of the class.
164

164

00:08:31,380  -->  00:08:33,970
Because they don't need to be inside self,
165

165

00:08:33,970  -->  00:08:36,250
we can just put them as class variables
166

166

00:08:36,250  -->  00:08:37,800
and this can be a class method.
167

167

00:08:38,830  -->  00:08:40,300
The next thing is to make sure
168

168

00:08:40,300  -->  00:08:43,663
that the API key and the domain do exist.
169

169

00:08:44,744  -->  00:08:48,379
If cls.MAILGUN_API_KEY is none,
170

170

00:08:48,379  -->  00:08:51,670
then we're gonna raise a Mailgun exception
171

171

00:08:51,670  -->  00:08:53,150
and we're gonna say something
172

172

00:08:53,150  -->  00:08:57,063
like failed to load Mailgun API key.
173

173

00:08:59,160  -->  00:09:02,210
If the MAILGUN_DOMAIN is none,
174

174

00:09:02,210  -->  00:09:04,940
we're gonna raise a Mailgun exception
175

175

00:09:04,940  -->  00:09:08,913
saying something like failed to load Mailgun domain.
176

176

00:09:10,900  -->  00:09:12,630
If you did want some more information
177

177

00:09:12,630  -->  00:09:15,380
regarding the problem, while you develop,
178

178

00:09:15,380  -->  00:09:17,980
you can do something like print response.json.
179

179

00:09:18,920  -->  00:09:19,960
That'll give you a bit more information
180

180

00:09:19,960  -->  00:09:21,210
about what's going wrong.
181

181

00:09:22,100  -->  00:09:23,166
All right.
182

182

00:09:23,166  -->  00:09:26,567
Let's try out this by typing Mailgun.send_mail.
183

183

00:09:28,660  -->  00:09:31,323
We're gonna send it to once again me.
184

184

00:09:33,000  -->  00:09:36,970
The subject is gonna be that.
185

185

00:09:36,970  -->  00:09:39,923
The text is gonna be that.
186

186

00:09:41,080  -->  00:09:43,860
The HTML is gonna be
187

187

00:09:48,400  -->  00:09:49,233
that.
188

188

00:09:51,040  -->  00:09:53,210
Once again, we can run this file
189

189

00:09:54,600  -->  00:09:57,730
and then we get our first exception, which is excellent,
190

190

00:09:57,730  -->  00:10:00,053
failed to load Mailgun API key.
191

191

00:10:00,930  -->  00:10:04,120
That means that we don't have an environment variable
192

192

00:10:04,120  -->  00:10:07,073
called MAILGUN_API_KEY currently set.
193

193

00:10:08,040  -->  00:10:10,850
We can go into our dotenv
194

194

00:10:10,850  -->  00:10:13,773
and define them here, MAILGUN_API_KEY, MAILGUN_DOMAIN.
195

195

00:10:17,570  -->  00:10:18,403
Okay.
196

196

00:10:18,403  -->  00:10:19,236
Those two there.
197

197

00:10:20,590  -->  00:10:22,710
Once again, we go back here.
198

198

00:10:22,710  -->  00:10:23,893
We copy them.
199

199

00:10:30,280  -->  00:10:31,823
Now we try to run it again.
200

200

00:10:33,100  -->  00:10:35,423
But alas, we get the same error.
201

201

00:10:37,260  -->  00:10:38,787
Why?
202

202

00:10:38,787  -->  00:10:40,650
Remember I mentioned earlier on
203

203

00:10:40,650  -->  00:10:43,310
when we first created our dotenv files
204

204

00:10:43,310  -->  00:10:47,000
that Flask is the one that automatically loads them
205

205

00:10:47,000  -->  00:10:49,893
if you have the library Python dotenv installed.
206

206

00:10:50,790  -->  00:10:53,685
But we are running mailgun.py,
207

207

00:10:53,685  -->  00:10:55,380
which has actually nothing to do with Flask.
208

208

00:10:55,380  -->  00:10:57,930
There is no Flask anywhere here.
209

209

00:10:57,930  -->  00:11:01,570
There's no Flask at being created or anything like that.
210

210

00:11:01,570  -->  00:11:04,360
So, you cannot run this file like that
211

211

00:11:04,360  -->  00:11:06,350
unless you first load the MAILGUN_API_KEY
212

212

00:11:06,350  -->  00:11:10,700
and MAILGUN_DOMAIN into your environment variables
213

213

00:11:10,700  -->  00:11:12,743
or somehow load the dotenv file.
214

214

00:11:14,340  -->  00:11:16,120
We can do this just now.
215

215

00:11:16,120  -->  00:11:20,230
But what we can do is we can do a little pack of a test.
216

216

00:11:20,230  -->  00:11:22,630
We can go into app.py
217

217

00:11:22,630  -->  00:11:26,893
and say from libs.mailgun import Mailgun.
218

218

00:11:26,893  -->  00:11:31,700
And then just down here somewhere, we can type this out.
219

219

00:11:31,700  -->  00:11:33,690
Maybe we can even print the result
220

220

00:11:33,690  -->  00:11:36,290
to make sure that it is a response 200.
221

221

00:11:36,290  -->  00:11:38,903
Now we can right-click app.py and run it,
222

222

00:11:40,590  -->  00:11:42,550
but it's happening again.
223

223

00:11:42,550  -->  00:11:44,080
We get the Mailgun exception:
224

224

00:11:44,080  -->  00:11:47,120
failed to load Mailgun API key.
225

225

00:11:47,120  -->  00:11:50,650
The reason for that is that Flask actually loads this file
226

226

00:11:50,650  -->  00:11:54,598
or Python loads this file before Flask runs.
227

227

00:11:54,598  -->  00:11:59,210
It's also when Flask runs that it loads the dotenv file.
228

228

00:11:59,210  -->  00:12:01,400
The first time that the file loads,
229

229

00:12:01,400  -->  00:12:04,024
we don't have the dotenv file loaded.
230

230

00:12:04,024  -->  00:12:07,570
Therefore, this cannot run.
231

231

00:12:07,570  -->  00:12:09,010
You can verify that very easily
232

232

00:12:09,010  -->  00:12:12,910
by doing something like print os.environ
233

233

00:12:12,910  -->  00:12:14,050
and then running it again.
234

234

00:12:14,050  -->  00:12:16,060
You'll see that it gets printed out.
235

235

00:12:16,060  -->  00:12:18,290
Oh you do have to remove this of course
236

236

00:12:18,290  -->  00:12:19,770
because it causes an error.
237

237

00:12:19,770  -->  00:12:22,060
You'll see it gets printed out twice.
238

238

00:12:22,060  -->  00:12:24,860
The first time when the file gets imported
239

239

00:12:24,860  -->  00:12:27,224
and then when Flask runs.
240

240

00:12:27,224  -->  00:12:30,840
So, we cannot put it there.
241

241

00:12:30,840  -->  00:12:32,870
Or can we?
242

242

00:12:32,870  -->  00:12:35,960
The thing is, by the time that we send mail,
243

243

00:12:35,960  -->  00:12:39,200
the environment variables have already been used
244

244

00:12:39,200  -->  00:12:41,760
or you will be able to access them.
245

245

00:12:41,760  -->  00:12:44,153
That's because when the class loads,
246

246

00:12:45,270  -->  00:12:48,163
i.e., when the file gets imported,
247

247

00:12:49,110  -->  00:12:51,430
that is when this gets calculated.
248

248

00:12:51,430  -->  00:12:55,240
If we calculate this when the method gets used,
249

249

00:12:55,240  -->  00:12:57,053
then we will have a chance.
250

250

00:12:57,965  -->  00:13:00,260
Actually this optimization here
251

251

00:13:00,260  -->  00:13:05,260
of moving stuff into constants may be a bit of an issue.
252

252

00:13:06,890  -->  00:13:10,460
We are going to cut those and put them in here
253

253

00:13:18,600  -->  00:13:19,433
just like that.
254

254

00:13:20,730  -->  00:13:23,493
Then if we go back to app.py, we can try again.
255

255

00:13:26,480  -->  00:13:28,568
Same problem happens.
256

256

00:13:28,568  -->  00:13:32,170
But again that's because this runs
257

257

00:13:32,170  -->  00:13:35,040
before the dotenv is loaded.
258

258

00:13:35,040  -->  00:13:38,290
We've got an easier way to check that that is the problem
259

259

00:13:38,290  -->  00:13:41,370
if we load the dotenv ourselves
260

260

00:13:41,370  -->  00:13:45,453
just by doing load dotenv from the dotenv package.
261

261

00:13:48,970  -->  00:13:51,690
There you have it, a response 200.
262

262

00:13:51,690  -->  00:13:55,150
Do note that putting this here means it gets sent twice
263

263

00:13:55,150  -->  00:13:57,620
because the first time when this all loads,
264

264

00:13:57,620  -->  00:14:01,110
the second time when Flask runs through it.
265

265

00:14:01,110  -->  00:14:02,930
So, this is not what we want.
266

266

00:14:02,930  -->  00:14:06,030
But that was the cause of the problem.
267

267

00:14:06,030  -->  00:14:10,050
We're gonna need to do this later on in our alert_updater.
268

268

00:14:11,619  -->  00:14:14,837
Let's go over to our alert model.
269

269

00:14:16,730  -->  00:14:20,420
What we're gonna do is we're gonna send the user an email
270

270

00:14:20,420  -->  00:14:22,330
when the price has been reached.
271

271

00:14:22,330  -->  00:14:24,800
So, we're gonna do send_mail.
272

272

00:14:24,800  -->  00:14:28,040
Here, we're gonna put some slightly nicer text, of course.
273

273

00:14:28,040  -->  00:14:30,130
I've gone ahead and typed out the text for you
274

274

00:14:30,130  -->  00:14:32,240
just so you don't have to watch do it.
275

275

00:14:32,240  -->  00:14:34,760
We're gonna notification for self.name,
276

276

00:14:34,760  -->  00:14:36,140
which is the alert's name,
277

277

00:14:36,140  -->  00:14:38,450
and then a nice string that says your alert has reached
278

278

00:14:38,450  -->  00:14:41,950
the price under the limit, the latest price is blah,
279

279

00:14:41,950  -->  00:14:42,960
whatever that is,
280

280

00:14:42,960  -->  00:14:44,940
and then go this address to check your item.
281

281

00:14:44,940  -->  00:14:46,190
Because we're sending an email,
282

282

00:14:46,190  -->  00:14:48,390
we can now include the item URL and they can click it
283

283

00:14:48,390  -->  00:14:51,400
and they can go straight to buying the item that they want.
284

284

00:14:51,400  -->  00:14:53,380
In HTML terms, it's more or less the same,
285

285

00:14:53,380  -->  00:14:56,240
but now we do have to include the paragraph tags.
286

286

00:14:56,240  -->  00:14:58,090
But inside the last paragraph,
287

287

00:14:58,090  -->  00:15:01,670
we can actually do a click here to purchase your item
288

288

00:15:01,670  -->  00:15:05,343
because we can include anchor tags or a tags in there.
289

289

00:15:06,930  -->  00:15:09,110
We do have to import the library.
290

290

00:15:09,110  -->  00:15:12,763
From libs.mailgun, import the Mailgun library.
291

291

00:15:14,890  -->  00:15:17,155
Let me stop that app there.
292

292

00:15:17,155  -->  00:15:19,500
That's pretty much everything we have to do.
293

293

00:15:19,500  -->  00:15:23,310
Now whenever we run through the alert_updater,
294

294

00:15:23,310  -->  00:15:27,133
this will automatically send emails if the price is reached.
295

295

00:15:28,150  -->  00:15:31,300
Of course, the alert_updater does not have the API key.
296

296

00:15:31,300  -->  00:15:33,110
So, if you run alert_updater,
297

297

00:15:33,110  -->  00:15:34,640
you'll get the same error as before,
298

298

00:15:34,640  -->  00:15:37,080
failed to load Mailgun API key.
299

299

00:15:37,080  -->  00:15:41,130
You do have to do from dotenv import load_dotenv
300

300

00:15:41,130  -->  00:15:44,890
and load that manually because Flask is not working here.
301

301

00:15:44,890  -->  00:15:47,940
So, it doesn't load the dotenv for us.
302

302

00:15:47,940  -->  00:15:50,860
But if you do it like this, then it does.
303

303

00:15:50,860  -->  00:15:54,950
However, you'll get errors because not all users
304

304

00:15:54,950  -->  00:15:58,756
that have alerts are my authorised recipients.
305

305

00:15:58,756  -->  00:16:00,250
That's why the errors happen.
306

306

00:16:00,250  -->  00:16:02,130
But if you do have your authorised recipients
307

307

00:16:02,130  -->  00:16:04,963
creating alerts, you'll see that this all works.
308

308

00:16:06,710  -->  00:16:09,470
This is how to send email from Python.
309

309

00:16:09,470  -->  00:16:12,370
We've created a library that makes it even easier
310

310

00:16:12,370  -->  00:16:14,540
just by taking in a bunch of parameters
311

311

00:16:14,540  -->  00:16:17,890
and sending an email using Mailgun.
312

312

00:16:17,890  -->  00:16:22,644
Inside this library, we are using environment variables,
313

313

00:16:22,644  -->  00:16:26,590
which we are checking whenever we send email,
314

314

00:16:26,590  -->  00:16:30,445
and then we're just making a post request to Mailgun
315

315

00:16:30,445  -->  00:16:33,063
and finally we're doing some error checking as well.
316

316

00:16:34,720  -->  00:16:37,620
Do note that this is just how Mailgun works.
317

317

00:16:37,620  -->  00:16:39,420
If you want to use a different service,
318

318

00:16:39,420  -->  00:16:42,010
the API or the place that you make requests to
319

319

00:16:42,010  -->  00:16:43,140
may be slightly different,
320

320

00:16:43,140  -->  00:16:45,460
the data you have to send may be slightly different.
321

321

00:16:45,460  -->  00:16:48,843
But generally, it's going to be more or less like this.
322

322

00:16:49,890  -->  00:16:51,210
I hope you've learned something.
323

323

00:16:51,210  -->  00:16:52,823
I'll see you on the next video.
