Im Rahmen des Kurses „Golang Developer. Professional “ erstellte eine Übersetzung eines nützlichen Artikels.
Wir laden Studieninteressierte und alle ein, die am offenen Webinar zum Thema "Go-Kanäle außen und innen" teilnehmen möchten . In der Lektion erhalten die Teilnehmer eine einfache Abstraktion in Bildern, um die Prinzipien der Kanäle zu verstehen und die Struktur der Kanäle auf Sprachebene kennenzulernen.
Heute lernen wir, wie man eine Slack-Anwendung als serverloses Backend integriert.
— 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».