go结合Slash Commands使用

2023-10-23 15:01:38 浏览数 (2)

需求

通过 Slack 命令模式,调用操作远程服务器。 服务端需要跟一个http服务来解析slash调过来的命令。

准备

准备以下步骤:

  1. 创建Slash conmand
  2. 开发服务端应用

添加 Slash Conmand

添加App

先到官网地址:https://api.slack.com/ 创建一个App

Slash Conmand

输出一个自定义命令

到这就创建完成了,接下来开发服务端。

实现

创建 go 项目slacktool,添加:

  1. main.go 文件
  2. go.mod 文件
  3. environment.env 文件

项目结构

代码语言:javascript复制
slacktool
|---main.go
|---go.mod
|---environment.env

添加 go.mod 依赖

添加两个依赖: godotenvslack

代码语言:javascript复制
module github.com/forfreeday/slacktool

go 1.17

require (
    github.com/joho/godotenv v1.4.0
    github.com/nlopes/slack v0.6.0
)

添加后执行:

代码语言:javascript复制
go mod tidy

编辑 main.go

下面的功能包括:

  1. 运行一个http服务端
  2. runConmand 运行逻辑
  3. exec 执行shell命令
代码语言:javascript复制
package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"os/exec"

	"github.com/joho/godotenv"
	"github.com/nlopes/slack"
)

func main() {
    // 读取环境变量配置
	err := godotenv.Load("environment.env")
	if err != nil {
		log.Fatal("Error loading .env file")
	}
    // 具体处理逻辑
	http.HandleFunc("/deploy-test", slashCommandHandler)
	fmt.Println("[INFO] Server listening")
    // 启动 http
	http.ListenAndServe(":10001", nil)
}

func slashCommandHandler(w http.ResponseWriter, r *http.Request) {
	s, err := slack.SlashCommandParse(r)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
	fmt.Println("for test: invoke msg")
	if !s.ValidateToken(os.Getenv("SLACK_VERIFICATION_TOKEN")) {
		w.WriteHeader(http.StatusUnauthorized)
		return
	}

	switch s.Command {
	case "/deploy-test":
		params := &slack.Msg{Text: s.Text}
		response := fmt.Sprintf("Command params : %v", params.Text)
        // 开启协程,否则如果执行太久,slack端会返回 timeout
		go runConmand(params, w)
		w.Write([]byte(response))
	default:
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
}

// 执行命令
func runConmand(param *slack.Msg, w http.ResponseWriter) {
	switch param.Text {
	case "--restartAll":
		fmt.Println("restart All node")
		cmd := exec.Command("deploy-test", param.Text)
		_, err := cmd.CombinedOutput()
		if err != nil {
			log.Fatalf("cmd.Run() failed with %sn", err)
		}
	case "--develop":
		fmt.Println("develop code")
	default:
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
}

服务端行一下,服务端可以多加一些日志,查看效果。

总结

比较简单,上面的代码最终调了一个系统命令deploy-test,这个实际写的另一个命令,写文章举个例子。

0 人点赞