You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Extend webwatch codelab with Slack part. Make the codelabs 'timeless' (i.e., remove the year reference :D). Update webwatch codelab to reflect the current state of the code
Copy file name to clipboardexpand all lines: webwatch/codelab/webwatch_codelab.md
+153-34
Original file line number
Diff line number
Diff line change
@@ -1,22 +1,25 @@
1
-
#### ZuriHac 2017 Beginner Track Exercise
1
+
#### ZuriHac Beginner Track Exercise
2
2
3
-
**Description:** A command-line tool which watches a certain webpage
4
-
for links with keywords (e.g. search http://news.ycombinator.com for "Haskell").
5
-
When such a link is found, it sends you an email.
3
+
**Description:** A command-line tool which watches a certain webpage for links
4
+
with keywords (e.g. search http://news.ycombinator.com for "Haskell"). When
5
+
such a link is found, it sends a message to the [Slack](https://slack.com/)
6
+
channel.
6
7
7
8
**Learning goals:**
8
9
* How to write a basic command-line application
9
10
* How to load configuration from a config-file
10
11
* How to fetch and parse a HTML page
11
-
* How to use AWS SES to send emails
12
+
* How to write HTTP client for REST API
12
13
* How to use the Reader/State monad transformers
13
14
14
15
Let's start!
15
16
16
17
17
18
## Development environment
18
19
19
-
The only tool you need to build this project is [Stack](http://haskellstack.org/) – The Haskell Tool Stack. Follow the install instructions on its homepage.
20
+
The only tool you need to build this project is
21
+
[Stack](http://haskellstack.org/) – The Haskell Tool Stack. Follow the install
@@ -267,10 +267,10 @@ You can exit ghci by pressing CTRL-D or writing `:q` followed by the enter key.
267
267
268
268
## The main watch function
269
269
270
-
We write the main watch function such that it fetches the links, sends
271
-
the emails, then sleeps for some time and then it is done. It runs inside
272
-
our `WebWatchM` monad, which gives it (read-only) access to the `Config`
273
-
object and the ability to update the `LinkSet`.
270
+
We write the main watch function such that it fetches the links, sends the
271
+
message, then sleeps for some time and then it is done. It runs inside our
272
+
`WebWatchM` monad, which gives it (read-only) access to the `Config` object and
273
+
the ability to update the `LinkSet`.
274
274
275
275
The function is aptly named `watchOnce` because it runs the checks once
276
276
and then is done.
@@ -287,7 +287,7 @@ watchOnce = do
287
287
288
288
-- TODO: Fetch the links
289
289
290
-
-- TODO: Send emails
290
+
-- TODO: Send message
291
291
292
292
slog $"Sleeping "++show cInterval ++" minute(s)"
293
293
liftIO $ threadDelay (cInterval *60*1000*1000)
@@ -332,7 +332,7 @@ and then sleep for 5 minutes:
332
332
```
333
333
$ stack build
334
334
$ stack exec webwatch -- webwatch.conf
335
-
Getting links from http://news.ycombinator.com/newest
335
+
Getting links from http://news.ycombinator.com/
336
336
Sleeping 5 minute(s)
337
337
```
338
338
@@ -348,7 +348,7 @@ you need to use `threadDelay (5 * 1000 * 1000)`.
348
348
Now that we have the main loop ready, there are two parts missing:
349
349
350
350
- fetching the links from the webpage
351
-
- sending the emails
351
+
- sending the message
352
352
353
353
Let's tackle the first one.
354
354
@@ -385,10 +385,10 @@ getMatchingLinks patterns uri = do
385
385
and register it in the cabal file:
386
386
387
387
```
388
-
executabe
388
+
Executable webwatch
389
389
…
390
390
391
-
other-modules:
391
+
Other-modules:
392
392
WebWatch.GetLinks
393
393
```
394
394
@@ -491,7 +491,7 @@ see which links it has found:
491
491
```
492
492
$ stack build
493
493
$ stack exec webwatch -- webwatch.conf
494
-
Getting links from http://news.ycombinator.com/newest
494
+
Getting links from http://news.ycombinator.com/
495
495
[Link {lTitle = "Amazon reportedly working on proper Android \8216Ice\8217 smartphones with Google\8217s apps", lHref = "https://www.theverge.com/circuitbreaker/2017/6/5/15739540/amazon-android-ice-smartphones-google-apps-services-fire-phone-report"}]
496
496
Sleeping 5 minute(s)
497
497
```
@@ -563,15 +563,15 @@ watchOnce = do
563
563
```
564
564
$ stack build
565
565
$ stack exec webwatch -- webwatch.conf
566
-
Getting links from http://news.ycombinator.com/newest
566
+
Getting links from http://news.ycombinator.com/
567
567
All links: [Link {lTitle = "Apple, Amazon to back Foxconn on Toshiba chip bid, Gou says", lHref = "http://asia.nikkei.com/Business/Deals/Apple-Amazon-to-back-Foxconn-on-Toshiba-chip-bid-Gou-says"}]
568
568
New links: [Link {lTitle = "Apple, Amazon to back Foxconn on Toshiba chip bid, Gou says", lHref = "http://asia.nikkei.com/Business/Deals/Apple-Amazon-to-back-Foxconn-on-Toshiba-chip-bid-Gou-says"}]
569
569
570
-
Getting links from http://news.ycombinator.com/newest
570
+
Getting links from http://news.ycombinator.com/
571
571
All links: [Link {lTitle = "Apple, Amazon to back Foxconn on Toshiba chip bid, Gou says", lHref = "http://asia.nikkei.com/Business/Deals/Apple-Amazon-to-back-Foxconn-on-Toshiba-chip-bid-Gou-says"}]
572
572
New links: []
573
573
574
-
Getting links from http://news.ycombinator.com/newest
574
+
Getting links from http://news.ycombinator.com/
575
575
All links: [Link {lTitle = "Apple, Amazon to back Foxconn on Toshiba chip bid, Gou says", lHref = "http://asia.nikkei.com/Business/Deals/Apple-Amazon-to-back-Foxconn-on-Toshiba-chip-bid-Gou-says"}]
576
576
New links: []
577
577
```
@@ -581,3 +581,122 @@ That looks good, the list of all links remains the same, and the new link is con
581
581
and thus ignored in the later iterations.
582
582
583
583
584
+
## Sending the messages
585
+
586
+
Now that we have found the interesting articles, we should send them to the
587
+
[Slack](https://slack.com) channel. We can do that through REST API provided by
588
+
Slack. Consuming REST API means sending HTTP POST request. For that we'll use
589
+
`http-client` and `http-client-tls` packages. Add them to the project's cabal
590
+
file.
591
+
592
+
Create the file `src/WebWatch/Slack.hs`:
593
+
594
+
```haskell
595
+
--| This module contains code for sending messages to the Slack channel.
596
+
{-# LANGUAGE OverloadedStrings #-}
597
+
moduleWebWatch.Slack
598
+
( sendLinks
599
+
) where
600
+
601
+
importqualifiedData.TextasT
602
+
importWebWatch.GetLinks
603
+
604
+
sendLinks
605
+
::T.Text--^ Special access URL
606
+
-> [Link] --^ Links
607
+
->IO()
608
+
sendLinks webhookUrl links =do
609
+
return()
610
+
```
611
+
612
+
and register it in the cabal file:
613
+
614
+
```
615
+
Executable webwatch
616
+
…
617
+
618
+
Other-modules:
619
+
WebWatch.GetLinks
620
+
WebWatch.Slack
621
+
```
622
+
623
+
Now you have all that's needed to finish the `watchOnce` function:
0 commit comments