Skip to content

Commit

Permalink
Merge branch 'master' into scheduled_msg_id
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzoaiello authored Nov 14, 2024
2 parents 3648a32 + 52fcd3d commit f5fc792
Show file tree
Hide file tree
Showing 7 changed files with 432 additions and 79 deletions.
157 changes: 157 additions & 0 deletions assistant.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package slack

import (
"context"
"encoding/json"
"net/url"
)

// AssistantThreadSetStatusParameters are the parameters for AssistantThreadSetStatus
type AssistantThreadsSetStatusParameters struct {
ChannelID string `json:"channel_id"`
Status string `json:"status"`
ThreadTS string `json:"thread_ts"`
}

// AssistantThreadSetTitleParameters are the parameters for AssistantThreadSetTitle
type AssistantThreadsSetTitleParameters struct {
ChannelID string `json:"channel_id"`
ThreadTS string `json:"thread_ts"`
Title string `json:"title"`
}

// AssistantThreadSetSuggestedPromptsParameters are the parameters for AssistantThreadSetSuggestedPrompts
type AssistantThreadsSetSuggestedPromptsParameters struct {
Title string `json:"title"`
ChannelID string `json:"channel_id"`
ThreadTS string `json:"thread_ts"`
Prompts []AssistantThreadsPrompt `json:"prompts"`
}

// AssistantThreadPrompt is a suggested prompt for a thread
type AssistantThreadsPrompt struct {
Title string `json:"title"`
Message string `json:"message"`
}

// AssistantThreadSetSuggestedPrompts sets the suggested prompts for a thread
func (p *AssistantThreadsSetSuggestedPromptsParameters) AddPrompt(title, message string) {
p.Prompts = append(p.Prompts, AssistantThreadsPrompt{
Title: title,
Message: message,
})
}

// SetAssistantThreadsSugesstedPrompts sets the suggested prompts for a thread
// @see https://api.slack.com/methods/assistant.threads.setSuggestedPrompts
func (api *Client) SetAssistantThreadsSuggestedPrompts(params AssistantThreadsSetSuggestedPromptsParameters) (err error) {
return api.SetAssistantThreadsSuggestedPromptsContext(context.Background(), params)
}

// SetAssistantThreadSuggestedPromptsContext sets the suggested prompts for a thread with a custom context
// @see https://api.slack.com/methods/assistant.threads.setSuggestedPrompts
func (api *Client) SetAssistantThreadsSuggestedPromptsContext(ctx context.Context, params AssistantThreadsSetSuggestedPromptsParameters) (err error) {

values := url.Values{
"token": {api.token},
}

if params.ThreadTS != "" {
values.Add("thread_ts", params.ThreadTS)
}

values.Add("channel_id", params.ChannelID)

// Send Prompts as JSON
prompts, err := json.Marshal(params.Prompts)
if err != nil {
return err
}

values.Add("prompts", string(prompts))

response := struct {
SlackResponse
}{}

err = api.postMethod(ctx, "assistant.threads.setSuggestedPrompts", values, &response)
if err != nil {
return
}

return response.Err()
}

// SetAssistantThreadStatus sets the status of a thread
// @see https://api.slack.com/methods/assistant.threads.setStatus
func (api *Client) SetAssistantThreadsStatus(params AssistantThreadsSetStatusParameters) (err error) {
return api.SetAssistantThreadsStatusContext(context.Background(), params)
}

// SetAssistantThreadStatusContext sets the status of a thread with a custom context
// @see https://api.slack.com/methods/assistant.threads.setStatus
func (api *Client) SetAssistantThreadsStatusContext(ctx context.Context, params AssistantThreadsSetStatusParameters) (err error) {

values := url.Values{
"token": {api.token},
}

if params.ThreadTS != "" {
values.Add("thread_ts", params.ThreadTS)
}

values.Add("channel_id", params.ChannelID)

// Always send the status parameter, if empty, it will clear any existing status
values.Add("status", params.Status)

response := struct {
SlackResponse
}{}

err = api.postMethod(ctx, "assistant.threads.setStatus", values, &response)
if err != nil {
return
}

return response.Err()
}

// SetAssistantThreadsTitle sets the title of a thread
// @see https://api.slack.com/methods/assistant.threads.setTitle
func (api *Client) SetAssistantThreadsTitle(params AssistantThreadsSetTitleParameters) (err error) {
return api.SetAssistantThreadsTitleContext(context.Background(), params)
}

// SetAssistantThreadsTitleContext sets the title of a thread with a custom context
// @see https://api.slack.com/methods/assistant.threads.setTitle
func (api *Client) SetAssistantThreadsTitleContext(ctx context.Context, params AssistantThreadsSetTitleParameters) (err error) {

values := url.Values{
"token": {api.token},
}

if params.ChannelID != "" {
values.Add("channel_id", params.ChannelID)
}

if params.ThreadTS != "" {
values.Add("thread_ts", params.ThreadTS)
}

if params.Title != "" {
values.Add("title", params.Title)
}

response := struct {
SlackResponse
}{}

err = api.postMethod(ctx, "assistant.threads.setTitle", values, &response)
if err != nil {
return
}

return response.Err()

}
86 changes: 86 additions & 0 deletions assistant_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package slack

import (
"encoding/json"
"net/http"
"testing"
)

func TestAssistantThreadsSuggestedPrompts(t *testing.T) {

http.HandleFunc("/assistant.threads.setSuggestedPrompts", okJSONHandler)
once.Do(startServer)
api := New("testing-token", OptionAPIURL("http://"+serverAddr+"/"))

params := AssistantThreadsSetSuggestedPromptsParameters{
ChannelID: "CXXXXXXXX",
ThreadTS: "1234567890.123456",
}

params.AddPrompt("title1", "message1")
params.AddPrompt("title2", "message2")

err := api.SetAssistantThreadsSuggestedPrompts(params)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}

}

func TestSetAssistantThreadsStatus(t *testing.T) {

http.HandleFunc("/assistant.threads.setStatus", okJSONHandler)
once.Do(startServer)
api := New("testing-token", OptionAPIURL("http://"+serverAddr+"/"))

params := AssistantThreadsSetStatusParameters{
ChannelID: "CXXXXXXXX",
ThreadTS: "1234567890.123456",
Status: "updated status",
}

err := api.SetAssistantThreadsStatus(params)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}

}

func assistantThreadsTitleHandler(rw http.ResponseWriter, r *http.Request) {

channelID := r.FormValue("channel_id")
threadTS := r.FormValue("thread_ts")
title := r.FormValue("title")

rw.Header().Set("Content-Type", "application/json")

if channelID != "" && threadTS != "" && title != "" {

resp, _ := json.Marshal(&addBookmarkResponse{
SlackResponse: SlackResponse{Ok: true},
})
rw.Write(resp)
} else {
rw.Write([]byte(`{ "ok": false, "error": "errored" }`))
}

}

func TestSetAssistantThreadsTitle(t *testing.T) {

http.HandleFunc("/assistant.threads.setTitle", assistantThreadsTitleHandler)
once.Do(startServer)
api := New("testing-token", OptionAPIURL("http://"+serverAddr+"/"))

params := AssistantThreadsSetTitleParameters{
ChannelID: "CXXXXXXXX",
ThreadTS: "1234567890.123456",
Title: "updated title",
}

err := api.SetAssistantThreadsTitle(params)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}

}
2 changes: 1 addition & 1 deletion block_rich_text.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ func NewRichTextSectionUserElement(userID string, style *RichTextSectionTextStyl
type RichTextSectionEmojiElement struct {
Type RichTextSectionElementType `json:"type"`
Name string `json:"name"`
SkinTone int `json:"skin_tone"`
SkinTone int `json:"skin_tone,omitempty"`
Unicode string `json:"unicode,omitempty"`
Style *RichTextSectionTextStyle `json:"style,omitempty"`
}
Expand Down
14 changes: 13 additions & 1 deletion block_rich_text_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,16 @@ func TestRichTextSection_UnmarshalJSON(t *testing.T) {
},
nil,
},
{
[]byte(`{"type": "rich_text_section","elements":[{"type": "emoji","name": "+1"}]}`),
RichTextSection{
Type: RTESection,
Elements: []RichTextSectionElement{
&RichTextSectionEmojiElement{Type: RTSEEmoji, Name: "+1"},
},
},
nil,
},
{
[]byte(`{"type": "rich_text_section","elements":[{"type": "emoji","name": "+1","unicode": "1f44d-1f3fb","skin_tone": 2}]}`),
RichTextSection{
Expand Down Expand Up @@ -299,7 +309,7 @@ func TestRichTextList_UnmarshalJSON(t *testing.T) {

func TestRichTextQuote_Marshal(t *testing.T) {
t.Run("rich_text_section", func(t *testing.T) {
const rawRSE = "{\"type\":\"rich_text_section\",\"elements\":[{\"type\":\"text\",\"text\":\"Some Text\"}]}"
const rawRSE = "{\"type\":\"rich_text_section\",\"elements\":[{\"type\":\"text\",\"text\":\"Some Text\"},{\"type\":\"emoji\",\"name\":\"+1\"},{\"type\":\"emoji\",\"name\":\"+1\",\"skin_tone\":2}]}"

var got RichTextSection
if err := json.Unmarshal([]byte(rawRSE), &got); err != nil {
Expand All @@ -309,6 +319,8 @@ func TestRichTextQuote_Marshal(t *testing.T) {
Type: RTESection,
Elements: []RichTextSectionElement{
&RichTextSectionTextElement{Type: RTSEText, Text: "Some Text"},
&RichTextSectionEmojiElement{Type: RTSEEmoji, Name: "+1"},
&RichTextSectionEmojiElement{Type: RTSEEmoji, Name: "+1", SkinTone: 2},
},
}

Expand Down
10 changes: 10 additions & 0 deletions block_section.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type SectionBlock struct {
BlockID string `json:"block_id,omitempty"`
Fields []*TextBlockObject `json:"fields,omitempty"`
Accessory *Accessory `json:"accessory,omitempty"`
Expand bool `json:"expand,omitempty"`
}

// BlockType returns the type of the block
Expand All @@ -25,6 +26,15 @@ func SectionBlockOptionBlockID(blockID string) SectionBlockOption {
}
}

// SectionBlockOptionExpand allows long text to be auto-expanded when displaying
//
// @see https://api.slack.com/reference/block-kit/blocks#section
func SectionBlockOptionExpand(shouldExpand bool) SectionBlockOption {
return func(block *SectionBlock) {
block.Expand = shouldExpand
}
}

// NewSectionBlock returns a new instance of a section block to be rendered
func NewSectionBlock(textObj *TextBlockObject, fields []*TextBlockObject, accessory *Accessory, options ...SectionBlockOption) *SectionBlock {
block := SectionBlock{
Expand Down
Loading

0 comments on commit f5fc792

Please sign in to comment.