fix(slack): select widest-scope connector in sender
sendMessage and updateMessage used LoadAllByOrganizationIDProtocol AndProvider and then picked connectors[0], which is ordered by created_at ASC. On an organization with multiple Slack installs only the oldest install ever received messages — re-installing Slack to switch channels silently broke because the sort kept the old row winning. Switch to LoadOneByOrganizationIDAndProvider, which picks the widest-scope row with updated_at DESC as the tiebreak. For Slack the scope sets are typically identical across installs, so the effective behavior becomes "most recent install wins" — the expected behavior. While here, prefix the remaining error messages in this file with "cannot" to match the project convention. Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
This commit is contained in:
@@ -148,39 +148,36 @@ func (s *Sender) sendMessage(ctx context.Context, tx pg.Querier, message *coreda
|
||||
tenantID := message.ID.TenantID()
|
||||
scope := coredata.NewScope(tenantID)
|
||||
|
||||
var connectors coredata.Connectors
|
||||
if err := connectors.LoadAllByOrganizationIDProtocolAndProvider(
|
||||
var c coredata.Connector
|
||||
if err := c.LoadOneByOrganizationIDAndProvider(
|
||||
ctx,
|
||||
tx,
|
||||
scope,
|
||||
message.OrganizationID,
|
||||
coredata.ConnectorProtocolOAuth2,
|
||||
coredata.ConnectorProviderSlack,
|
||||
s.encryptionKey,
|
||||
message.OrganizationID,
|
||||
coredata.ConnectorProviderSlack,
|
||||
); err != nil {
|
||||
return nil, nil, fmt.Errorf("cannot load slack connectors: %w", err)
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return nil, nil, fmt.Errorf("cannot send slack message: no connector configured for organization")
|
||||
}
|
||||
return nil, nil, fmt.Errorf("cannot load slack connector: %w", err)
|
||||
}
|
||||
|
||||
if len(connectors) == 0 {
|
||||
return nil, nil, fmt.Errorf("no slack connectors configured for organization")
|
||||
}
|
||||
|
||||
c := connectors[0]
|
||||
if c.Connection == nil {
|
||||
return nil, nil, fmt.Errorf("slack connector has nil connection")
|
||||
return nil, nil, fmt.Errorf("cannot send slack message: connector has nil connection")
|
||||
}
|
||||
|
||||
slackConn, ok := c.Connection.(*connector.SlackConnection)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("slack connector must have SlackConnection type, got %T", c.Connection)
|
||||
return nil, nil, fmt.Errorf("cannot send slack message: unexpected connection type %T", c.Connection)
|
||||
}
|
||||
|
||||
if slackConn.Settings.ChannelID == "" {
|
||||
return nil, nil, fmt.Errorf("slack connector %s has no channel ID", c.ID)
|
||||
return nil, nil, fmt.Errorf("cannot send slack message: connector %s has no channel ID", c.ID)
|
||||
}
|
||||
|
||||
if slackConn.AccessToken == "" {
|
||||
return nil, nil, fmt.Errorf("slack connector %s has no access token", c.ID)
|
||||
return nil, nil, fmt.Errorf("cannot send slack message: connector %s has no access token", c.ID)
|
||||
}
|
||||
|
||||
client := NewClient(s.logger)
|
||||
@@ -269,41 +266,38 @@ func (s *Sender) batchUpdateMessages(ctx context.Context) error {
|
||||
|
||||
func (s *Sender) updateMessage(ctx context.Context, tx pg.Querier, updateMessage *coredata.SlackMessage) error {
|
||||
if updateMessage.ChannelID == nil || updateMessage.MessageTS == nil {
|
||||
return fmt.Errorf("slack message has no channel ID or message TS")
|
||||
return fmt.Errorf("cannot update slack message: missing channel ID or message TS")
|
||||
}
|
||||
|
||||
tenantID := updateMessage.ID.TenantID()
|
||||
scope := coredata.NewScope(tenantID)
|
||||
|
||||
var connectors coredata.Connectors
|
||||
if err := connectors.LoadAllByOrganizationIDProtocolAndProvider(
|
||||
var c coredata.Connector
|
||||
if err := c.LoadOneByOrganizationIDAndProvider(
|
||||
ctx,
|
||||
tx,
|
||||
scope,
|
||||
updateMessage.OrganizationID,
|
||||
coredata.ConnectorProtocolOAuth2,
|
||||
coredata.ConnectorProviderSlack,
|
||||
s.encryptionKey,
|
||||
updateMessage.OrganizationID,
|
||||
coredata.ConnectorProviderSlack,
|
||||
); err != nil {
|
||||
return fmt.Errorf("cannot load slack connectors: %w", err)
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return fmt.Errorf("cannot update slack message: no connector configured for organization")
|
||||
}
|
||||
return fmt.Errorf("cannot load slack connector: %w", err)
|
||||
}
|
||||
|
||||
if len(connectors) == 0 {
|
||||
return fmt.Errorf("no slack connectors configured for organization")
|
||||
}
|
||||
|
||||
c := connectors[0]
|
||||
if c.Connection == nil {
|
||||
return fmt.Errorf("slack connector has nil connection")
|
||||
return fmt.Errorf("cannot update slack message: connector has nil connection")
|
||||
}
|
||||
|
||||
slackConn, ok := c.Connection.(*connector.SlackConnection)
|
||||
if !ok {
|
||||
return fmt.Errorf("slack connector must have SlackConnection type, got %T", c.Connection)
|
||||
return fmt.Errorf("cannot update slack message: unexpected connection type %T", c.Connection)
|
||||
}
|
||||
|
||||
if slackConn.AccessToken == "" {
|
||||
return fmt.Errorf("slack connector %s has no access token", c.ID)
|
||||
return fmt.Errorf("cannot update slack message: connector %s has no access token", c.ID)
|
||||
}
|
||||
|
||||
client := NewClient(s.logger)
|
||||
|
||||
Reference in New Issue
Block a user