Skip to content

Conversation

@ElioBonfim
Copy link

@ElioBonfim ElioBonfim commented Feb 8, 2026

…ose' state

Evolution is a webhook-based integration that should always be considered 'open' since it passively receives events. Three changes fix the issue:

  1. monitor.service.ts: Always call connectToWhatsapp() for Evolution instances on server restart, regardless of stored connection status.
  2. instance.controller.ts: Call connectToWhatsapp() for Evolution instances during creation to initialize Chatwoot settings.
  3. evolution.channel.service.ts: Restore stateConnection to 'open' and persist it to DB when connectToWhatsapp() is called in init mode.

Closes #2419

https://claude.ai/code/session_013wxk4cj5U2H5fr2cxCgWdH

📋 Description

🔗 Related Issue

Closes #(issue_number)

🧪 Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update
  • 🔧 Refactoring (no functional changes)
  • ⚡ Performance improvement
  • 🧹 Code cleanup
  • 🔒 Security fix

🧪 Testing

  • Manual testing completed
  • Functionality verified in development environment
  • No breaking changes introduced
  • Tested with different connection types (if applicable)

📸 Screenshots (if applicable)

✅ Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have manually tested my changes thoroughly
  • I have verified the changes work with different scenarios
  • Any dependent changes have been merged and published

📝 Additional Notes

Summary by Sourcery

Ensure Evolution WhatsApp integrations are always initialized and marked as open so they do not remain stuck in a closed state.

Bug Fixes:

  • Reset Evolution instances' connection state to open and persist it when initialized without data.
  • Auto-connect Evolution instances on server restart regardless of their stored connection status.
  • Initialize Evolution instances by connecting to WhatsApp on creation so related settings are correctly set up.

…ose' state

Evolution is a webhook-based integration that should always be considered
'open' since it passively receives events. Three changes fix the issue:

1. monitor.service.ts: Always call connectToWhatsapp() for Evolution
   instances on server restart, regardless of stored connection status.
2. instance.controller.ts: Call connectToWhatsapp() for Evolution
   instances during creation to initialize Chatwoot settings.
3. evolution.channel.service.ts: Restore stateConnection to 'open' and
   persist it to DB when connectToWhatsapp() is called in init mode.

Closes EvolutionAPI#2419

https://claude.ai/code/session_013wxk4cj5U2H5fr2cxCgWdH
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Feb 8, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Ensures Evolution WhatsApp integration instances are always treated as 'open' webhook-based connections by auto-connecting them on startup/creation and resetting their connection state to 'open' when initialized, including persisting that state to the database.

Sequence diagram for Evolution instance auto-connect on server restart

sequenceDiagram
  participant Server
  participant WAMonitoringService
  participant PrismaRepository
  participant EvolutionStartupService

  Server->>WAMonitoringService: onStartup()
  WAMonitoringService->>PrismaRepository: findManyInstances()
  PrismaRepository-->>WAMonitoringService: instanceList
  loop forEach instanceData
    WAMonitoringService->>WAMonitoringService: shouldAutoConnect(instanceData)
    alt instanceData.connectionStatus is open or connecting or integration is EVOLUTION
      WAMonitoringService->>EvolutionStartupService: connectToWhatsapp(instanceData)
      alt data is not provided (init mode)
        EvolutionStartupService->>EvolutionStartupService: stateConnection = { state: open }
        alt instanceId is defined
          EvolutionStartupService->>PrismaRepository: updateInstance(id, connectionStatus = open)
          PrismaRepository-->>EvolutionStartupService: updatedInstance
        end
        EvolutionStartupService->>EvolutionStartupService: loadChatwoot()
      else data is provided
        EvolutionStartupService->>EvolutionStartupService: normal connection flow
      end
    else no auto connect
      WAMonitoringService->>WAMonitoringService: skipConnect(instanceData)
    end
  end
Loading

Sequence diagram for Evolution instance creation and initialization

sequenceDiagram
  actor Client
  participant InstanceController
  participant PrismaRepository
  participant EvolutionStartupService

  Client->>InstanceController: createInstance(requestBody)
  InstanceController->>PrismaRepository: createInstanceInDatabase(requestBody)
  PrismaRepository-->>InstanceController: instanceData
  InstanceController->>EvolutionStartupService: createInstance(instanceData)
  EvolutionStartupService-->>InstanceController: instance
  InstanceController->>InstanceController: prepareResponseData(instance, instanceData)
  alt instanceData.integration is EVOLUTION
    InstanceController->>EvolutionStartupService: connectToWhatsapp()
    EvolutionStartupService->>EvolutionStartupService: stateConnection = { state: open }
    alt instanceId is defined
      EvolutionStartupService->>PrismaRepository: updateInstance(id, connectionStatus = open)
      PrismaRepository-->>EvolutionStartupService: updatedInstance
    end
    EvolutionStartupService->>EvolutionStartupService: loadChatwoot()
  end
  InstanceController-->>Client: createdInstanceResponse
Loading

Updated class diagram for Evolution startup, monitoring, and instance controller

classDiagram
  class WAMonitoringService {
    - logger
    - prismaRepository
    + onStartup() void
    + monitorInstances() void
    + connectInstance(instanceData) void
  }

  class InstanceController {
    - prismaRepository
    - logger
    + createInstance(requestBody) Promise
    + getInstance(instanceId) Promise
  }

  class EvolutionStartupService {
    - prismaRepository
    - instanceId
    - stateConnection
    + connectToWhatsapp(data) Promise
    + loadChatwoot() void
  }

  class PrismaRepository {
    + findManyInstances() Promise
    + updateInstance(id, connectionStatus) Promise
    + createInstanceInDatabase(requestBody) Promise
  }

  class Integration {
    <<enumeration>>
    EVOLUTION
    OTHER
  }

  WAMonitoringService --> PrismaRepository : uses
  WAMonitoringService --> EvolutionStartupService : creates_and_connects
  InstanceController --> PrismaRepository : uses
  InstanceController --> EvolutionStartupService : initializes_and_connects
  EvolutionStartupService --> PrismaRepository : updates_instance_state
  InstanceController --> Integration : checks_integration_type
  WAMonitoringService --> Integration : checks_integration_type
Loading

File-Level Changes

Change Details Files
Treat Evolution integrations as always-auto-connect on server startup regardless of stored connectionStatus.
  • Extend auto-connect condition to also trigger when the instance integration type is Evolution, not just when connectionStatus is 'open' or 'connecting'.
  • Preserve existing logging of auto-connect attempts while broadening when they occur for Evolution instances.
src/api/services/monitor.service.ts
Auto-initialize Evolution instances on creation so Chatwoot settings are configured immediately.
  • After instance creation, if the integration type is Evolution, invoke connectToWhatsapp() on the instance.
  • Ensure this happens before constructing and returning the instance payload (instanceName, ownerJid, etc.) to the client.
src/api/controllers/instance.controller.ts
When Evolution connectToWhatsapp() is called in init mode (no data), force the connection state to 'open' and persist it.
  • On init (no data), set the in-memory stateConnection to { state: 'open' } before loading Chatwoot.
  • If an instanceId is available, update the corresponding DB record's connectionStatus to 'open' via prismaRepository.instance.update().
  • Retain existing behavior of loadChatwoot() and the early return in init mode.
src/api/integrations/channel/evolution/evolution.channel.service.ts

Assessment against linked issues

Issue Objective Addressed Explanation
#2419 Ensure that newly created Evolution/WhatsApp instances are fully initialized and functional after creation, with a non-close connection status (e.g., open/connecting) instead of remaining in an unusable close state.

Possibly linked issues

  • #(not specified): PR forces Evolution instances to ‘open’ and reconnect so incoming messages appear as Open in Chatwoot.
  • #(not provided): PR reopens Evolution instances and restores 'open' status, likely fixing the integrated chat message delivery failures.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In InstanceController, consider whether await instance.connectToWhatsapp() on Evolution creation should block the whole request (and potentially fail instance creation on connection/init errors) or if it would be safer to kick this off asynchronously and surface errors via monitoring instead.
  • The auto-connect log message in WAMonitoringService still reports connectionStatus even when auto-connecting solely because integration === Integration.EVOLUTION; consider clarifying the log text or including the integration type so the reason for auto-connection is unambiguous in logs.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `InstanceController`, consider whether `await instance.connectToWhatsapp()` on Evolution creation should block the whole request (and potentially fail instance creation on connection/init errors) or if it would be safer to kick this off asynchronously and surface errors via monitoring instead.
- The auto-connect log message in `WAMonitoringService` still reports `connectionStatus` even when auto-connecting solely because `integration === Integration.EVOLUTION`; consider clarifying the log text or including the integration type so the reason for auto-connection is unambiguous in logs.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

# Instance creation generates empty, non-functional instances

2 participants