dtrt2368 2016-09-30 09:40
浏览 57

松弛整合:404过期的网址https://hooks.slack.com/commands

Here is my golang app listening requests from slack command: main.go:

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "time"
)

type SlackCmdResponse struct {
    Text string `json:"text"`
}

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
        if err := req.ParseForm(); err != nil {
            panic(err)
        }
        responseUrl := req.PostFormValue("response_url")
        go func() {
            time.Sleep(time.Second)
            postBack(responseUrl)
        }()
        rj, err := json.Marshal(SlackCmdResponse{Text: "Test started"})
        if err != nil {
            panic(err)
        }
        w.Header().Set("Content-Type", "application/json")
        w.Write(rj)

    })
    fmt.Println("listening 8383")
    if err := http.ListenAndServe(":8383", nil); err != nil {
        panic(err)
    }
}

func postBack(responseUrl string) {
    fmt.Println("responseUrl", responseUrl)
    cResp := SlackCmdResponse{
        Text: "Test finished",
    }
    cj, err := json.Marshal(cResp)
    if err != nil {
        panic(err)
    }
    req, err := http.NewRequest("POST", responseUrl, bytes.NewReader(cj))
    req.Header.Set("Content-Type", "application/json")

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }
    if resp != nil {
        fmt.Println(resp.StatusCode)
        if b, err := ioutil.ReadAll(resp.Body); err != nil {
            panic(err)
        } else {
            fmt.Println(string(b))
        }
        if resp.Body != nil {
            resp.Body.Close()
        }
    }
}

I run it:

$ go run main.go
listening 8383

I use ngrok to make it accessible from the internet:

ngrok http 8383

I created slack slash command /my-command with POST option and pasted https URL that ngrok gave:

slash command options - slack

Now when I run /my-command in slack, I get slack reply Test started. And then in a second slack prints Test finished

For now, it's all fine.

Problem

If I replace line

time.Sleep(time.Second)

by line

time.Sleep(time.Hour) // long test

I don't get slack printed "Test finished" in hour. Instead, I see in my app logs:

responseUrl https://hooks.slack.com/commands/T3GBFUZ64/86817661808/XRmDO21jYaP1Wzu7GFpNw9eW
404
Expired url

Looks like slack's response URL has an expiration time. How to extend this expiration time?

Or in a case of expiration, is there another way to send a message to the user about having the test finished? I have name and id of a user launching /my-command

req.PostFormValue("user_name")
req.PostFormValue("user_id")

So I want to run integration tests by slack which are longer than 2 hours and get a response after finishing such tests in slack.

  • 写回答

1条回答 默认 最新

  • dongmuzhan4705 2016-10-03 08:36
    关注

    You can not increase the expire time for the URL that is a Slack internal setting.

    Using the Slack Web API

    You can send unattended messages to any user through the Slack Web API which you need a token for it.

    For more information check: https://api.slack.com/web.

    chat.postMessage

    The Slack API has a postMessage command that allows the user to post messages to a channel, to the slackbot channel and to the user through IM channel (direct message). It seems you want to do the later which is quite simple.

    Post to an IM channel

    chat.postMessage#channels

    Method Url: https://slack.com/api/chat.postMessage

    Posting to an IM channel is a little more complex when settings the value of channel depending on the value of as_user.

    • If as_user is false:
      • Pass a username (@chris) as the value of channel to post to that user's @slackbot channel as the bot.
      • Pass the IM channel's ID (D023BB3L2) as the value of channel to post to that IM channel as the bot. The IM channel's ID can be retrieved through the im.list API method.
    • If as_user is true:
      • Pass the IM channel's ID (D023BB3L2) as the value of channel to post to that IM channel as the authenticated user. The IM channel's ID can be retrieved through the im.list API method. To send a direct message to the user owning the token used in the request, provide the channel field with the a conversation/IM ID value found in a method like im.list.

    To send a direct message to the user owning the token used in the request, provide the channel field with the a conversation/IM ID value found in a method like im.list.

    im.list

    This method will return a list of direct messages channels if you don't have a channel open with the user yet you can call the im.open.

    im.open

    This method is used to open a direct message channel with a specified user.

    Documentation about im.open can be found here.

    Example URL

    https://slack.com/api/chat.postMessage?token=**TOKEN**&channel=**Direct Channel ID**&text=HelloWorld&as_user=true&pretty=1

    Just replace **TOKEN** and **Direct Channel ID** with your values and it should send a direct message to the specified user.

    评论

报告相同问题?

悬赏问题

  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 划分vlan后不通了
  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大