Dans le cadre du cours «Golang Developer. Professionnel »a préparé la traduction d'un article utile.
Nous invitons les futurs étudiants et toutes les personnes souhaitant participer au webinaire ouvert sur le thème "Go-channels outside and inside". Dans la leçon, les participants recevront une simple abstraction en images pour comprendre les principes des canaux, en apprendre davantage sur la structure des canaux au niveau de la langue.
Aujourd'hui, nous allons apprendre à intégrer une application Slack en tant que backend sans serveur.
— FaaS ( ) . , , , ! serverless , , HTTP-. , Slack serverless () Go Azure Functions. Slack , , , Slack.
Giphy Slack. Giphy Slack . -, , () , Giphy Random API. Azure Functions Slack.
:
, ;
, Azure Functions Slack;
, , Slack !
- Go ( GitHub). , Azure Functions , Go , . (Custom Handlers) !
?
, - -, . , /, HTTP! , HTTP- - / (input/output bindings) .
, ( )
( HTTP, , . .) (Functions host). , : (payload) - () , , . , .
, (, , ) .
, .
.
├── cmd
│ └── main.go
├── funcy
│ └── function.json
├── go.mod
├── host.json
└── pkg
└── function
├── function.go
├── giphy.go
└── slack.go
{
"bindings": [
{
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
host.json
, , -, HTTP.customHandler.description.defaultExecutablePath
, ,go_funcy
— , -."enableForwardingHttpRequest": true
, HTTP - :
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
},
"customHandler": {
"description": {
"defaultExecutablePath": "go_funcy"
},
"enableForwardingHttpRequest": true
},
"logging": {
"logLevel": {
"default": "Trace"
}
}
}
cmd
pkg
Go. .
cmd/main.go
HTTP-. , /api/funcy — , HTTP- .
func main() {
port, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT")
if !exists {
port = "8080"
}
http.HandleFunc("/api/funcy", function.Funcy)
log.Fatal(http.ListenAndServe(":"+port, nil))
}
function/function.go
.
— ( Slack) , Slack.
signingSecret := os.Getenv("SLACK_SIGNING_SECRET")
apiKey := os.Getenv("GIPHY_API_KEY")
if signingSecret == "" || apiKey == "" {
http.Error(w, "Failed to process request. Please contact the admin", http.StatusUnauthorized)
return
}
slackTimestamp := r.Header.Get("X-Slack-Request-Timestamp")
b, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "Failed to process request", http.StatusBadRequest)
return
}
slackSigningBaseString := "v0:" + slackTimestamp + ":" + string(b)
slackSignature := r.Header.Get("X-Slack-Signature")
if !matchSignature(slackSignature, signingSecret, slackSigningBaseString) {
http.Error(w, "Function was not invoked by Slack", http.StatusForbidden)
return
}
, , Slack, — , (Slack).
vals, err := parse(b)
if err != nil {
http.Error(w, "Failed to process request", http.StatusBadRequest)
return
}
giphyTag := vals.Get("text")
GIF- , GIPHY REST API
giphyResp, err := http.Get("http://api.giphy.com/v1/gifs/random?tag=" + giphyTag + "&api_key=" + apiKey)
if err != nil {
http.Error(w, "Failed to process request", http.StatusFailedDependency)
return
}
resp, err := ioutil.ReadAll(giphyResp.Body)
if err != nil {
http.Error(w, "Failed to process request", http.StatusInternalServerError)
return
}
, GIPHY API, , Slack . !
var gr GiphyResponse
json.Unmarshal(resp, &gr)
title := gr.Data.Title
url := gr.Data.Images.Downsized.URL
slackResponse := SlackResponse{Text: slackResponseStaticText, Attachments: []Attachment{{Text: title, ImageURL: url}}}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(slackResponse)
fmt.Println("Sent response to Slack")
matchSignature
, , slack.go
giphy.go
( function
), , Go (JSON), . , .
! . ! , , .
Go, .
Azure functions Core Tools — ( ).
Slack, .
- API GIPHY, .
, Azure Function Slack - (Slash command).
Azure Functions
-
- (Function App) Azure (Add).
: (Custom Handler) (Runtime stack).
(Hosting ) Linux Consumption (Serverless) (Operating system) (Plan type) .
Application Insights ( ).
(Create), .
- :
App Service plan ( Consumption/Serverless)
GitHub (build
)
git clone https://github.com/abhirockzz/serverless-go-slack-app
cd serverless-go-slack-app
GOOS=linux go build -o go_funcy cmd/main.go
GOOS=linux
Linux, Linux -.
Azure Functions core tools CLI
func azure functionapp publish <enter name of the function app>
URL- , — .
Slack
, Slack (-) :
Slack
-
Slack -
(Create New Command), - . , URL- (Request URL) - , HTTP , , URL-, . , (Save), .
, -, , (Basic Information) , (Install your app to your workspace) (Install App to Workspace) — Slack, , API Slack. , (App Credentials).
- (Signing Secret) ,
… , - SLACKSIGNINGSECRET GIPHYAPIKEY — .
fun(cy) time!
Slack /funcy <search term>
. , /funcy dog
. !
, : /funcy
Slack, , Giphy API , , GIF ( !).
timeout error
Slack . , cold start
, , . , Slack 3 — .
. , , , !
: , , , , , (-, App Service Plan . .).
Go Azure! , . .
«Golang Developer. Professional».