Skip to content

Commit 9cc3fd1

Browse files
committed
add uploadFile method. Update several tutorials
1 parent fc76298 commit 9cc3fd1

12 files changed

Lines changed: 164 additions & 34 deletions

File tree

README.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,33 @@ main = do
3939
Right me -> print me
4040
```
4141

42+
### Upload File
43+
44+
```haskell
45+
{-# LANGUAGE OverloadedStrings #-}
46+
47+
module Main where
48+
49+
import Network.HTTP.Client
50+
import Network.HTTP.Client.TLS (tlsManagerSettings)
51+
52+
import qualified Data.ByteString.Lazy.Char8 as BC
53+
54+
import Aitu.Bot
55+
56+
main :: IO ()
57+
main = do
58+
let token = "<YOUR_BOT_TOKEN>"
59+
60+
manager <- newManager tlsManagerSettings
61+
response <- runAituBotClient token manager $ do
62+
uploadFile "cat.png" "images/cat.png"
63+
64+
case response of
65+
Left (code, errMsg) -> BC.putStrLn errMsg
66+
Right me -> print me
67+
```
68+
4269
### UI
4370

4471
Simple Form with Button, that open url by click
@@ -148,7 +175,7 @@ where
148175
- [x] [setWebhook](https://btsdigital.github.io/bot-api-contract/setwebhook.html)
149176
- [x] [deleteWebhook](https://btsdigital.github.io/bot-api-contract/deletewebhook.html)
150177
- [x] [getWebhookInfo](https://btsdigital.github.io/bot-api-contract/getwebhookinfo.html)
151-
- [ ] uploadMedia
178+
- [x] uploadMedia
152179
- [ ] downloadMedia
153180

154181
## Updates
@@ -202,4 +229,5 @@ where
202229
- [x] [Text](https://github.com/avatar29A/hs-aitubots-api/blob/master/src/Aitu/Bot/Forms/Content/TextWidget.hs)
203230
- [x] [TextArea](https://github.com/avatar29A/hs-aitubots-api/blob/master/src/Aitu/Bot/Forms/Content/TextArea.hs)
204231
- [x] [UserInfo](https://github.com/avatar29A/hs-aitubots-api/blob/master/src/Aitu/Bot/Forms/Content/UserInfo.hs)
205-
- [ ] Typed Resource Library
232+
- [ ] Typed Resource Library
233+
- [ ] Applicative Form Builder

hs-aitubots-api.cabal

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ cabal-version: 1.12
44
--
55
-- see: https://github.com/sol/hpack
66
--
7-
-- hash: 4898caec675424a16affcf31fc3ca014386ee5b112cd117023ca4a9460451ff8
7+
-- hash: 3865539b4c858b77c3cffde6fbc910d5d6b80b6d6bb1a71e44d2885a74225f94
88

99
name: hs-aitubots-api
10-
version: 0.2.0.0
10+
version: 0.3.0.0
1111
description: Please see the README on GitHub at <https://github.com/avatar29A/hs-aitubots-api/READMME.md>
1212
homepage: https://github.com/avatar29A/hs-aitubots-api#readme
1313
bug-reports: https://github.com/avatar29A/hs-aitubots-api/issues
@@ -91,6 +91,7 @@ library
9191
Aitu.Bot.Types.ReplyCommand
9292
Aitu.Bot.Types.UIState
9393
Aitu.Bot.Types.Updates
94+
Aitu.Bot.Types.UploadFiles
9495
Aitu.Bot.Types.User
9596
Aitu.Bot.Types.Video
9697
Aitu.Bot.Types.WebHookInfo

package.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ dependencies:
2828
- mtl
2929
- base >= 4.7 && < 5
3030
name: hs-aitubots-api
31-
version: 0.2.0.0
31+
version: 0.3.0.0
3232
extra-source-files:
3333
- README.md
3434
- ChangeLog.md

src/Aitu/Bot.hs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module Aitu.Bot
1515
, setWebhook
1616
, getWebhook
1717
, deleteWebhook
18+
, uploadFile
1819
)
1920
where
2021

@@ -25,6 +26,7 @@ import Control.Exception
2526

2627
import Network.HTTP.Client
2728
import Network.HTTP.Types.Status ( statusCode )
29+
import Network.HTTP.Client.MultipartFormData
2830

2931
import Data.Aeson
3032
import Data.UUID.Types as UUID
@@ -51,6 +53,7 @@ type Url = String
5153
type Token = String
5254
type Method = BS.ByteString
5355
type JSON = BC.ByteString
56+
type FileName = T.Text
5457

5558
type AituBotClient a = ReaderT AituBotConfig IO (Either ClientError a)
5659

@@ -150,6 +153,38 @@ get' url = do
150153
post :: Url -> BC.ByteString -> AituBotClient BC.ByteString
151154
post = invoke "POST"
152155

156+
uploadFile :: FileName -> FilePath -> AituBotClient UploadFiles
157+
uploadFile filename filepath = do
158+
response <- uploadFiles filename filepath
159+
pure (response >>= mkFromJSON)
160+
161+
-- uploadFile uploads file to Aitu server
162+
uploadFiles :: FileName -> FilePath -> AituBotClient JSON
163+
uploadFiles filename filepath = do
164+
t <- asks token
165+
baseUrl <- asks apiUrl
166+
m <- asks manager
167+
let url = baseUrl <> "upload"
168+
169+
initReq <- liftIO $ parseRequest url
170+
let request = initReq
171+
{ method = "POST"
172+
, requestHeaders = [ ("x-bot-token" , (encodeUtf8 . T.pack) t)
173+
, ("content-type", "application/octet-stream")
174+
]
175+
}
176+
177+
response <-
178+
liftIO
179+
$ flip httpLbs m
180+
=<< formDataBody [partFileSource filename filepath] request
181+
182+
let httpCode = statusCode $ responseStatus response
183+
body = responseBody response
184+
185+
pure $ if httpCode /= 200 then Left (httpCode, body) else Right body
186+
187+
153188
-- invoke does http request to Aitu Bot Platform and returns raw data or Error.
154189
invoke :: Method -> Url -> JSON -> AituBotClient JSON
155190
invoke method endpoint json = do

src/Aitu/Bot/Types.hs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,31 @@
1-
module Aitu.Bot.Types (module Types) where
1+
module Aitu.Bot.Types
2+
( module Types
3+
)
4+
where
25

36
-- Types
4-
import Aitu.Bot.Types.Audio as Types
5-
import Aitu.Bot.Types.Avatar as Types
6-
import Aitu.Bot.Types.Bot as Types
7-
import Aitu.Bot.Types.Contact as Types
8-
import Aitu.Bot.Types.Document as Types
9-
import Aitu.Bot.Types.Errors as Types
10-
import Aitu.Bot.Types.ForwardMetadata as Types
11-
import Aitu.Bot.Types.Image as Types
12-
import Aitu.Bot.Types.InputMedia as Types
13-
import Aitu.Bot.Types.Media as Types
14-
import Aitu.Bot.Types.Peer as Types
15-
import Aitu.Bot.Types.UIState as Types
16-
import Aitu.Bot.Types.User as Types
17-
import Aitu.Bot.Types.Video as Types
18-
import Aitu.Bot.Types.WebHookInfo as Types
19-
import Aitu.Bot.Types.InlineCommand as Types
20-
import Aitu.Bot.Types.QuickButtonCommand as Types
21-
import Aitu.Bot.Types.ReplyCommand as Types
22-
import Aitu.Bot.Types.InputContact as Types
7+
import Aitu.Bot.Types.Audio as Types
8+
import Aitu.Bot.Types.Avatar as Types
9+
import Aitu.Bot.Types.Bot as Types
10+
import Aitu.Bot.Types.Contact as Types
11+
import Aitu.Bot.Types.Document as Types
12+
import Aitu.Bot.Types.Errors as Types
13+
import Aitu.Bot.Types.ForwardMetadata
14+
as Types
15+
import Aitu.Bot.Types.Image as Types
16+
import Aitu.Bot.Types.InputMedia as Types
17+
import Aitu.Bot.Types.Media as Types
18+
import Aitu.Bot.Types.Peer as Types
19+
import Aitu.Bot.Types.UIState as Types
20+
import Aitu.Bot.Types.User as Types
21+
import Aitu.Bot.Types.Video as Types
22+
import Aitu.Bot.Types.WebHookInfo as Types
23+
import Aitu.Bot.Types.InlineCommand as Types
24+
import Aitu.Bot.Types.QuickButtonCommand
25+
as Types
26+
import Aitu.Bot.Types.ReplyCommand as Types
27+
import Aitu.Bot.Types.InputContact as Types
2328
-- Updates
24-
import Aitu.Bot.Types.Updates as Types
29+
import Aitu.Bot.Types.Updates as Types
30+
-- Files
31+
import Aitu.Bot.Types.UploadFiles as Types

src/Aitu/Bot/Types/UploadFiles.hs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{-# LANGUAGE DuplicateRecordFields #-}
2+
{-# LANGUAGE OverloadedStrings #-}
3+
4+
module Aitu.Bot.Types.UploadFiles
5+
( File(..)
6+
, UploadFiles(..)
7+
)
8+
where
9+
10+
import Data.Aeson
11+
import Data.Text
12+
13+
data File = File {
14+
fileId :: Text
15+
, fileName :: Text
16+
} deriving (Show)
17+
18+
instance FromJSON File where
19+
parseJSON (Object v) = File <$> v .: "fileId" <*> v .: "fileName"
20+
21+
newtype UploadFiles = UploadFiles {
22+
files :: [File]
23+
} deriving (Show)
24+
25+
instance FromJSON UploadFiles where
26+
parseJSON (Object v) = UploadFiles <$> v .: "uploadedFiles"

tutorials/.DS_Store

6 KB
Binary file not shown.

tutorials/simpleui/.DS_Store

6 KB
Binary file not shown.

tutorials/simpleui/app/FormCustomContainer.hs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
module FormCustomContainer where
55

66
import Aitu.Bot
7-
import Aitu.Bot.Types
7+
import Aitu.Bot.Types hiding ( Image(..)
8+
, InputMediaType(..)
9+
)
810
import Aitu.Bot.Forms
911
import Aitu.Bot.Commands
1012
import Aitu.Bot.Widgets
@@ -94,9 +96,38 @@ open peer = do
9496
}
9597
}
9698

99+
image1 = Image
100+
{ contentId = "image1"
101+
, options = Just defaultOptions
102+
{ width = Just 37
103+
, height = Just 6
104+
, flexOptions = Just defaultFlexOptions
105+
{ alignSelf = Just ALIGN_CENTER
106+
}
107+
}
108+
, fileMetadata = FileMetadata
109+
"435fa9e6-9e74-11ea-bfb9-82ed4a7ce3ac"
110+
IMAGE
111+
"cat.jpg"
112+
, formAction = Nothing
113+
}
114+
115+
imageContainer = CustomContainer
116+
{ contentId = "imageContainer"
117+
, content = [C.Content image1]
118+
, options = Just defaultOptions
119+
{ width = Just 62
120+
, flexOptions = Just defaultFlexOptions
121+
{ flexDirection = Just COLUMN
122+
, alignItems = Just ALIGN_CENTER
123+
}
124+
}
125+
}
126+
97127
parentCustomContainer = CustomContainer
98128
{ contentId = "parentContainer"
99-
, content = [ C.Content titleText
129+
, content = [ C.Content imageContainer
130+
, C.Content titleText
100131
, C.Content subtitleText
101132
, C.Content divider
102133
, C.Content contactTitleText
@@ -125,4 +156,4 @@ open peer = do
125156
}
126157

127158

128-
sendCustomContainer peer [mainCustomContainer]
159+
sendCustomContainer peer [mainCustomContainer, mainCustomContainer]

tutorials/simpleui/app/FormImage.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ open peer = do
2222
, formAction = Nothing
2323
}
2424

25-
fileMetadata = FileMetadata "image_id" IMAGE "file_name.jpg"
25+
fileMetadata = FileMetadata "435fa9e6-9e74-11ea-bfb9-82ed4a7ce3ac"
26+
IMAGE
27+
"cat.jpg"
2628

27-
image1 = Image
29+
image1 = Image
2830
"image_id"
2931
fileMetadata
3032
(Just defaultOptions { width = Just 100, height = Just 100 })

0 commit comments

Comments
 (0)