@@ -100,28 +100,47 @@ async function getSlackChannelsForToken(integration: AuthenticatableIntegration)
100100
101101type Channels = Awaited < ReturnType < WebClient [ "conversations" ] [ "list" ] > > [ "channels" ] ;
102102
103- async function getSlackConversationsPage ( client : WebClient , nextCursor ?: string ) {
104- return client . conversations . list ( {
105- types : "public_channel,private_channel" ,
106- exclude_archived : true ,
107- cursor : nextCursor ,
108- } ) ;
109- }
110-
111103async function getAllSlackConversations ( client : WebClient ) {
112104 let nextCursor : string | undefined = undefined ;
113105 let channels : Channels = [ ] ;
114106
115- do {
116- const response = await getSlackConversationsPage ( client , nextCursor ) ;
117-
118- if ( ! response . ok ) {
119- throw new Error ( `Failed to get channels: ${ response . error } ` ) ;
107+ try {
108+ do {
109+ // The `tryCatch` util runs into a type error due to self referencing.
110+ // So we fall back to a good old try/catch block here.
111+ const response = await client . conversations . list ( {
112+ types : "public_channel,private_channel" ,
113+ exclude_archived : true ,
114+ cursor : nextCursor ,
115+ limit : 999 ,
116+ } ) ;
117+
118+ channels = channels . concat ( response . channels ?? [ ] ) ;
119+ nextCursor = response . response_metadata ?. next_cursor ;
120+ } while ( nextCursor ) ;
121+ } catch ( error ) {
122+ if ( error && isSlackError ( error ) && error . data . error === "ratelimited" ) {
123+ logger . warn ( "Rate limiting issue occurred while fetching Slack channels" , {
124+ error,
125+ } ) ;
126+
127+ // This is a workaround to the current way we handle Slack channels for creating alerts.
128+ // For workspaces with a lot of channels (>10000) we might hit the rate limit for this slack endpoint,
129+ // as multiple requests are needed to fetch all channels.
130+ // We use the largest allowed page size of 999 to reduce the chance of hitting the rate limit.
131+
132+ // This is mainly due to workspaces with a large number of archived channels,
133+ // which this slack endpoint unfortunately filters out only after fetching the page of channels without applying any filters first.
134+ // https://api.slack.com/methods/conversations.list#markdown
135+
136+ // We expect most workspaces not to run into this issue, but if they do, we at least return some channels.
137+ // In the future, we might revisit the way we handle Slack channels and cache them on our side to support
138+ // proper searching. Until then, we track occurrences of this issue using a metric.
139+ return channels ;
120140 }
121141
122- channels = channels . concat ( response . channels ?? [ ] ) ;
123- nextCursor = response . response_metadata ?. next_cursor ;
124- } while ( nextCursor ) ;
142+ throw error ;
143+ }
125144
126145 return channels ;
127146}
0 commit comments