Skip to content

Commit

Permalink
Merge pull request #1119 from stephenwan-opal/master
Browse files Browse the repository at this point in the history
Add ListTeams and TeamAccess{Granted,Revoked}Events and fix missing enterprise ID
  • Loading branch information
kanata2 authored Dec 16, 2022
2 parents 617bdc1 + 2d81614 commit c0676fc
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 12 deletions.
34 changes: 34 additions & 0 deletions auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,37 @@ func (api *Client) SendAuthRevokeContext(ctx context.Context, token string) (*Au

return api.authRequest(ctx, "auth.revoke", values)
}

type listTeamsResponse struct {
Teams []Team `json:"teams"`
SlackResponse
}

type ListTeamsParameters struct {
Limit int
Cursor string
}

// ListTeams returns all workspaces a token can access.
// More info: https://api.slack.com/methods/admin.teams.list
func (api *Client) ListTeams(params ListTeamsParameters) ([]Team, string, error) {
return api.ListTeamsContext(context.Background(), params)
}

// ListTeams returns all workspaces a token can access with a custom context.
func (api *Client) ListTeamsContext(ctx context.Context, params ListTeamsParameters) ([]Team, string, error) {
values := url.Values{
"token": {api.token},
}
if params.Cursor != "" {
values.Add("cursor", params.Cursor)
}

response := &listTeamsResponse{}
err := api.postMethod(ctx, "auth.teams.list", values, response)
if err != nil {
return nil, "", err
}

return response.Teams, response.ResponseMetadata.Cursor, response.Err()
}
51 changes: 51 additions & 0 deletions auth_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package slack

import (
"net/http"
"testing"

"github.com/stretchr/testify/assert"
)

func getTeamList(rw http.ResponseWriter, r *http.Request) {
rw.Header().Set("Content-Type", "application/json")
response := []byte(`{
"ok": true,
"teams": [
{
"name": "Shinichi's workspace",
"id": "T12345678"
},
{
"name": "Migi's workspace",
"id": "T12345679"
}
],
"response_metadata": {
"next_cursor": "dXNlcl9pZDo5MTQyOTI5Mzkz"
}
}`)
rw.Write(response)
}

func TestListTeams(t *testing.T) {
http.HandleFunc("/auth.teams.list", getTeamList)

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

teams, cursor, err := api.ListTeams(ListTeamsParameters{})
if err != nil {
t.Errorf("Unexpected error: %s", err)
return
}

assert.Len(t, teams, 2)
assert.Equal(t, "T12345678", teams[0].ID)
assert.Equal(t, "Shinichi's workspace", teams[0].Name)

assert.Equal(t, "T12345679", teams[1].ID)
assert.Equal(t, "Migi's workspace", teams[1].Name)

assert.Equal(t, "dXNlcl9pZDo5MTQyOTI5Mzkz", cursor)
}
19 changes: 14 additions & 5 deletions conversation.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,17 +343,26 @@ func (api *Client) CloseConversationContext(ctx context.Context, channelID strin
return response.NoOp, response.AlreadyClosed, response.Err()
}

type CreateConversationParams struct {
ChannelName string
IsPrivate bool
TeamID string
}

// CreateConversation initiates a public or private channel-based conversation
func (api *Client) CreateConversation(channelName string, isPrivate bool) (*Channel, error) {
return api.CreateConversationContext(context.Background(), channelName, isPrivate)
func (api *Client) CreateConversation(params CreateConversationParams) (*Channel, error) {
return api.CreateConversationContext(context.Background(), params)
}

// CreateConversationContext initiates a public or private channel-based conversation with a custom context
func (api *Client) CreateConversationContext(ctx context.Context, channelName string, isPrivate bool) (*Channel, error) {
func (api *Client) CreateConversationContext(ctx context.Context, params CreateConversationParams) (*Channel, error) {
values := url.Values{
"token": {api.token},
"name": {channelName},
"is_private": {strconv.FormatBool(isPrivate)},
"name": {params.ChannelName},
"is_private": {strconv.FormatBool(params.IsPrivate)},
}
if params.TeamID != "" {
values.Set("team_id", params.TeamID)
}
response, err := api.channelRequest(ctx, "conversations.create", values)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion conversation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ func TestCreateConversation(t *testing.T) {
http.HandleFunc("/conversations.create", okChannelJsonHandler)
once.Do(startServer)
api := New("testing-token", OptionAPIURL("http://"+serverAddr+"/"))
channel, err := api.CreateConversation("CXXXXXXXX", false)
channel, err := api.CreateConversation(CreateConversationParams{ChannelName: "CXXXXXXXX"})
if err != nil {
t.Errorf("Unexpected error: %s", err)
return
Expand Down
2 changes: 1 addition & 1 deletion examples/pins/pins.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func main() {
postAsUserID = authTest.UserID

// Create a temporary channel
channel, err := api.CreateConversation(channelName, false)
channel, err := api.CreateConversation(slack.CreateConversationParams{ChannelName: channelName})

if err != nil {
// If the channel exists, that means we just need to unarchive it
Expand Down
18 changes: 18 additions & 0 deletions slackevents/inner_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,18 @@ func (e MessageEvent) IsEdited() bool {
e.Message.Edited != nil
}

// TeamAccessGrantedEvent is sent if access to teams was granted for your org-wide app.
type TeamAccessGrantedEvent struct {
Type string `json:"type"`
TeamIDs []string `json:"team_ids"`
}

// TeamAccessRevokedEvent is sent if access to teams was revoked for your org-wide app.
type TeamAccessRevokedEvent struct {
Type string `json:"type"`
TeamIDs []string `json:"team_ids"`
}

type EventsAPIType string

const (
Expand Down Expand Up @@ -599,6 +611,10 @@ const (
MessageMetadataUpdated = EventsAPIType("message_metadata_updated")
// MessageMetadataPosted A message with metadata was deleted
MessageMetadataDeleted = EventsAPIType("message_metadata_deleted")
// TeamAccessGranted is sent if access to teams was granted for your org-wide app.
TeamAccessGranted = EventsAPIType("team_access_granted")
// TeamAccessrevoked is sent if access to teams was revoked for your org-wide app.
TeamAccessrevoked = EventsAPIType("team_access_revoked")
)

// EventsAPIInnerEventMapping maps INNER Event API events to their corresponding struct
Expand Down Expand Up @@ -641,4 +657,6 @@ var EventsAPIInnerEventMapping = map[EventsAPIType]interface{}{
MessageMetadataPosted: MessageMetadataPostedEvent{},
MessageMetadataUpdated: MessageMetadataUpdatedEvent{},
MessageMetadataDeleted: MessageMetadataDeletedEvent{},
TeamAccessGranted: TeamAccessGrantedEvent{},
TeamAccessrevoked: TeamAccessRevokedEvent{},
}
1 change: 1 addition & 0 deletions slackevents/outer_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type EventsAPICallbackEvent struct {
Token string `json:"token"`
TeamID string `json:"team_id"`
APIAppID string `json:"api_app_id"`
EnterpriseID string `json:"enterprise_id"`
InnerEvent *json.RawMessage `json:"event"`
AuthedUsers []string `json:"authed_users"`
AuthedTeams []string `json:"authed_teams"`
Expand Down
8 changes: 4 additions & 4 deletions slackevents/parsers.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func parseInnerEvent(e *EventsAPICallbackEvent) (EventsAPIEvent, error) {
e.TeamID,
"unmarshalling_error",
e.APIAppID,
"",
e.EnterpriseID,
&slack.UnmarshallingErrorEvent{ErrorObj: err},
EventsAPIInnerEvent{},
}, err
Expand All @@ -114,7 +114,7 @@ func parseInnerEvent(e *EventsAPICallbackEvent) (EventsAPIEvent, error) {
e.TeamID,
iE.Type,
e.APIAppID,
"",
e.EnterpriseID,
nil,
EventsAPIInnerEvent{},
}, fmt.Errorf("Inner Event does not exist! %s", iE.Type)
Expand All @@ -128,7 +128,7 @@ func parseInnerEvent(e *EventsAPICallbackEvent) (EventsAPIEvent, error) {
e.TeamID,
"unmarshalling_error",
e.APIAppID,
"",
e.EnterpriseID,
&slack.UnmarshallingErrorEvent{ErrorObj: err},
EventsAPIInnerEvent{},
}, err
Expand All @@ -138,7 +138,7 @@ func parseInnerEvent(e *EventsAPICallbackEvent) (EventsAPIEvent, error) {
e.TeamID,
e.Type,
e.APIAppID,
"",
e.EnterpriseID,
e,
EventsAPIInnerEvent{iE.Type, recvEvent},
}, nil
Expand Down
2 changes: 1 addition & 1 deletion slacktest/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestServerCreateConversationHandler(t *testing.T) {
go s.Start()

client := slack.New("ABCDEFG", slack.OptionAPIURL(s.GetAPIURL()))
conversation, err := client.CreateConversation("test", false)
conversation, err := client.CreateConversation(slack.CreateConversationParams{ChannelName: "test"})
assert.NoError(t, err)
assert.Equal(t, "C0EAQDV4Z", conversation.ID)
assert.Equal(t, "U023BECGF", conversation.Creator)
Expand Down

0 comments on commit c0676fc

Please sign in to comment.