evolution-client-python/README.md
Davidson Gomes 043a7f9b3c docs: Update README documentation with WebSocket examples and configuration improvements
- Add detailed WebSocket configuration examples
- Include instructions for creating a WebSocket using the client method
- Expand the events section with clearer explanations
- Add notes on security and best practices for API tokens
2025-03-06 14:33:26 -03:00

1246 lines
27 KiB
Markdown

# Evolution Client Python
Python client to interact with the evolutionapi.
## Installation
```bash
pip install evolutionapi
```
## Basic Usage
### Initializing the Client
```python
from evolutionapi.client import EvolutionClient
client = EvolutionClient(
base_url='http://your-server:port',
api_token='your-api-token'
)
```
### Instance Management
#### List Instances
```python
instances = client.instances.fetch_instances()
```
#### Create New Instance
```python
from evolutionapi.models.instance import InstanceConfig
# Configuração básica
config = InstanceConfig(
instanceName="minha-instancia",
integration="WHATSAPP-BAILEYS",
qrcode=True
)
# Configuração completa
config = InstanceConfig(
instanceName="minha-instancia",
integration="WHATSAPP-BAILEYS",
token="token_da_instancia",
number="5511999999999",
qrcode=True,
rejectCall=True,
msgCall="Mensagem de chamada rejeitada",
groupsIgnore=True,
alwaysOnline=True,
readMessages=True,
readStatus=True,
syncFullHistory=True
)
new_instance = client.instances.create_instance(config)
```
#### Configure Webhook
```python
from evolutionapi.models.instance import WebhookConfig
config = WebhookConfig(
url="https://seu-servidor.com/webhook",
byEvents=True,
base64=True,
headers={
"Authorization": "Bearer seu-token"
},
events=[
"messages.upsert",
"messages.update",
"messages.delete",
"groups.upsert",
"groups.update",
"groups.delete",
"group-participants.update",
"contacts.upsert",
"contacts.update",
"contacts.delete",
"presence.update",
"chats.upsert",
"chats.update",
"chats.delete",
"call"
]
)
response = client.instances.set_webhook(instance_id, config, instance_token)
```
#### Configure Events
```python
from evolutionapi.models.instance import EventsConfig
config = EventsConfig(
enabled=True,
events=[
"messages.upsert",
"messages.update",
"messages.delete",
"groups.upsert",
"groups.update",
"groups.delete",
"group-participants.update",
"contacts.upsert",
"contacts.update",
"contacts.delete",
"presence.update",
"chats.upsert",
"chats.update",
"chats.delete",
"call"
]
)
response = client.instances.set_events(instance_id, config, instance_token)
```
#### Configure Chatwoot Integration
```python
from evolutionapi.models.instance import ChatwootConfig
config = ChatwootConfig(
accountId="seu-account-id",
token="seu-token",
url="https://seu-chatwoot.com",
signMsg=True,
reopenConversation=True,
conversationPending=False,
importContacts=True,
nameInbox="evolution",
mergeBrazilContacts=True,
importMessages=True,
daysLimitImportMessages=3,
organization="Evolution Bot",
logo="https://evolution-api.com/files/evolution-api-favicon.png"
)
response = client.instances.set_chatwoot(instance_id, config, instance_token)
```
#### Delete Instance
```python
response = client.instances.delete_instance(instance_id, instance_token)
```
#### Get Instance Info
```python
response = client.instances.get_instance_info(instance_id, instance_token)
```
#### Get Instance QR Code
```python
response = client.instances.get_instance_qrcode(instance_id, instance_token)
```
#### Get Instance Status
```python
response = client.instances.get_instance_status(instance_id, instance_token)
```
#### Logout Instance
```python
response = client.instances.logout_instance(instance_id, instance_token)
```
#### Restart Instance
```python
response = client.instances.restart_instance(instance_id, instance_token)
```
### Instance Operations
#### Connect Instance
```python
state = client.instance_operations.connect(instance_id, instance_token)
```
#### Check Connection State
```python
state = client.instance_operations.get_connection_state(instance_id, instance_token)
```
#### Set Presence
```python
from evolutionapi.models.presence import PresenceConfig, PresenceStatus
# Definir como disponível
config = PresenceConfig(
presence=PresenceStatus.AVAILABLE
)
# Definir como indisponível
config = PresenceConfig(
presence=PresenceStatus.UNAVAILABLE
)
response = client.instance_operations.set_presence(instance_id, config, instance_token)
```
### Sending Messages
#### Text Message
```python
from evolutionapi.models.message import TextMessage, QuotedMessage
# Mensagem simples
message = TextMessage(
number="5511999999999",
text="Olá, como você está?",
delay=1000 # delay opcional em ms
)
# Mensagem com menções
message = TextMessage(
number="5511999999999",
text="@everyone Olá a todos!",
mentionsEveryOne=True,
mentioned=["5511999999999", "5511888888888"]
)
# Mensagem com link preview
message = TextMessage(
number="5511999999999",
text="Confira este link: https://exemplo.com",
linkPreview=True
)
# Mensagem com citação
quoted = QuotedMessage(
key={
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": False,
"participant": "5511999999999@s.whatsapp.net",
"id": "123456789",
"owner": "5511999999999@s.whatsapp.net"
}
)
message = TextMessage(
number="5511999999999",
text="Esta é uma resposta",
quoted=quoted
)
response = client.messages.send_text(instance_id, message, instance_token)
```
#### Media Message
```python
from evolutionapi.models.message import MediaMessage, MediaType, QuotedMessage
# Mensagem com imagem
message = MediaMessage(
number="5511999999999",
mediatype=MediaType.IMAGE.value,
mimetype="image/jpeg",
caption="Minha imagem",
media="base64_da_imagem_ou_url",
fileName="imagem.jpg",
delay=1000 # delay opcional
)
# Mensagem com vídeo
message = MediaMessage(
number="5511999999999",
mediatype=MediaType.VIDEO.value,
mimetype="video/mp4",
caption="Meu vídeo",
media="base64_do_video_ou_url",
fileName="video.mp4"
)
# Mensagem com documento
message = MediaMessage(
number="5511999999999",
mediatype=MediaType.DOCUMENT.value,
mimetype="application/pdf",
caption="Meu documento",
media="base64_do_documento_ou_url",
fileName="documento.pdf"
)
# Mensagem com menções
message = MediaMessage(
number="5511999999999",
mediatype=MediaType.IMAGE.value,
mimetype="image/jpeg",
caption="@everyone Olhem esta imagem!",
media="base64_da_imagem",
mentionsEveryOne=True,
mentioned=["5511999999999", "5511888888888"]
)
response = client.messages.send_media(instance_id, message, instance_token)
```
#### Status Message
```python
from evolutionapi.models.message import StatusMessage, StatusType, FontType
# Status de texto
message = StatusMessage(
type=StatusType.TEXT,
content="Meu status de texto",
caption="Legenda opcional",
backgroundColor="#FF0000",
font=FontType.BEBASNEUE_REGULAR,
allContacts=True
)
# Status de imagem
message = StatusMessage(
type=StatusType.IMAGE,
content="base64_da_imagem",
caption="Minha imagem de status"
)
# Status de vídeo
message = StatusMessage(
type=StatusType.VIDEO,
content="base64_do_video",
caption="Meu vídeo de status"
)
# Status de áudio
message = StatusMessage(
type=StatusType.AUDIO,
content="base64_do_audio",
caption="Meu áudio de status"
)
response = client.messages.send_status(instance_id, message, instance_token)
```
#### Location Message
```python
from evolutionapi.models.message import LocationMessage
message = LocationMessage(
number="5511999999999",
name="Localização",
address="Endereço completo",
latitude=-23.550520,
longitude=-46.633308,
delay=1000 # delay opcional
)
response = client.messages.send_location(instance_id, message, instance_token)
```
#### Contact Message
```python
from evolutionapi.models.message import ContactMessage, Contact
contact = Contact(
fullName="Nome Completo",
wuid="5511999999999",
phoneNumber="5511999999999",
organization="Empresa",
email="email@exemplo.com",
url="https://exemplo.com"
)
message = ContactMessage(
number="5511999999999",
contact=[contact]
)
response = client.messages.send_contact(instance_id, message, instance_token)
```
#### Reaction Message
```python
from evolutionapi.models.message import ReactionMessage
message = ReactionMessage(
key={
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": False,
"participant": "5511999999999@s.whatsapp.net",
"id": "123456789",
"owner": "5511999999999@s.whatsapp.net"
},
reaction="👍"
)
response = client.messages.send_reaction(instance_id, message, instance_token)
```
#### Poll Message
```python
from evolutionapi.models.message import PollMessage
message = PollMessage(
number="5511999999999",
name="Minha Enquete",
selectableCount=1, # número de opções que podem ser selecionadas
values=["Opção 1", "Opção 2", "Opção 3"],
delay=1000 # delay opcional
)
response = client.messages.send_poll(instance_id, message, instance_token)
```
#### Button Message
```python
from evolutionapi.models.message import ButtonMessage, Button
# Botão de resposta simples
buttons = [
Button(
type="reply",
displayText="Opção 1",
id="1"
),
Button(
type="reply",
displayText="Opção 2",
id="2"
)
]
# Botão com URL
buttons = [
Button(
type="url",
displayText="Visitar Site",
url="https://exemplo.com"
)
]
# Botão com número de telefone
buttons = [
Button(
type="phoneNumber",
displayText="Ligar",
phoneNumber="5511999999999"
)
]
# Botão com código de cópia
buttons = [
Button(
type="copyCode",
displayText="Copiar Código",
copyCode="ABC123"
)
]
message = ButtonMessage(
number="5511999999999",
title="Título",
description="Descrição",
footer="Rodapé",
buttons=buttons,
delay=1000 # delay opcional
)
response = client.messages.send_buttons(instance_id, message, instance_token)
```
#### List Message
```python
from evolutionapi.models.message import ListMessage, ListSection, ListRow
rows = [
ListRow(
title="Item 1",
description="Descrição do item 1",
rowId="1"
),
ListRow(
title="Item 2",
description="Descrição do item 2",
rowId="2"
)
]
section = ListSection(
title="Seção 1",
rows=rows
)
message = ListMessage(
number="5511999999999",
title="Título da Lista",
description="Descrição da lista",
buttonText="Clique aqui",
footerText="Rodapé",
sections=[section],
delay=1000 # delay opcional
)
response = client.messages.send_list(instance_id, message, instance_token)
```
### Group Management
#### Create Group
```python
from evolutionapi.models.group import CreateGroup
config = CreateGroup(
subject="Nome do Grupo",
participants=["5511999999999", "5511888888888"],
description="Descrição do grupo"
)
response = client.group.create_group(instance_id, config, instance_token)
```
#### Update Group Picture
```python
from evolutionapi.models.group import GroupPicture
config = GroupPicture(
image="base64_da_imagem"
)
response = client.group.update_group_picture(instance_id, "group_jid", config, instance_token)
```
#### Update Group Subject
```python
from evolutionapi.models.group import GroupSubject
config = GroupSubject(
subject="Novo Nome do Grupo"
)
response = client.group.update_group_subject(instance_id, "group_jid", config, instance_token)
```
#### Update Group Description
```python
from evolutionapi.models.group import GroupDescription
config = GroupDescription(
description="Nova descrição do grupo"
)
response = client.group.update_group_description(instance_id, "group_jid", config, instance_token)
```
#### Send Group Invite
```python
from evolutionapi.models.group import GroupInvite
config = GroupInvite(
groupJid="group_jid",
description="Convite para o grupo",
numbers=["5511999999999", "5511888888888"]
)
response = client.group.send_group_invite(instance_id, config, instance_token)
```
#### Manage Participants
```python
from evolutionapi.models.group import UpdateParticipant
# Adicionar participantes
config = UpdateParticipant(
action="add",
participants=["5511999999999", "5511888888888"]
)
# Remover participantes
config = UpdateParticipant(
action="remove",
participants=["5511999999999"]
)
# Promover a administrador
config = UpdateParticipant(
action="promote",
participants=["5511999999999"]
)
# Rebaixar de administrador
config = UpdateParticipant(
action="demote",
participants=["5511999999999"]
)
response = client.group.update_participant(instance_id, "group_jid", config, instance_token)
```
#### Update Group Settings
```python
from evolutionapi.models.group import UpdateSetting
# Ativar modo anúncio
config = UpdateSetting(
action="announcement"
)
# Desativar modo anúncio
config = UpdateSetting(
action="not_announcement"
)
# Bloquear grupo
config = UpdateSetting(
action="locked"
)
# Desbloquear grupo
config = UpdateSetting(
action="unlocked"
)
response = client.group.update_setting(instance_id, "group_jid", config, instance_token)
```
#### Toggle Ephemeral Messages
```python
from evolutionapi.models.group import ToggleEphemeral
config = ToggleEphemeral(
expiration=86400 # 24 horas em segundos
)
response = client.group.toggle_ephemeral(instance_id, "group_jid", config, instance_token)
```
### Profile Management
#### Fetch Profile
```python
from evolutionapi.models.profile import FetchProfile
config = FetchProfile(
number="5511999999999"
)
response = client.profile.fetch_profile(instance_id, config, instance_token)
```
#### Update Profile Name
```python
from evolutionapi.models.profile import ProfileName
config = ProfileName(
name="Novo Nome"
)
response = client.profile.update_profile_name(instance_id, config, instance_token)
```
#### Update Status
```python
from evolutionapi.models.profile import ProfileStatus
config = ProfileStatus(
status="Novo status"
)
response = client.profile.update_profile_status(instance_id, config, instance_token)
```
#### Update Profile Picture
```python
from evolutionapi.models.profile import ProfilePicture
config = ProfilePicture(
picture="base64_da_imagem"
)
response = client.profile.update_profile_picture(instance_id, config, instance_token)
```
#### Configure Privacy Settings
```python
from evolutionapi.models.profile import PrivacySettings
config = PrivacySettings(
readreceipts="all", # "all" ou "none"
profile="contacts", # "all", "contacts", "contact_blacklist" ou "none"
status="contacts", # "all", "contacts", "contact_blacklist" ou "none"
online="all", # "all" ou "match_last_seen"
last="contacts", # "all", "contacts", "contact_blacklist" ou "none"
groupadd="contacts" # "all", "contacts" ou "contact_blacklist"
)
response = client.profile.update_privacy_settings(instance_id, config, instance_token)
```
### Chat Operations
#### Check WhatsApp Numbers
```python
from evolutionapi.models.chat import CheckIsWhatsappNumber
config = CheckIsWhatsappNumber(
numbers=["5511999999999", "5511888888888"]
)
response = client.chat.check_is_whatsapp_numbers(instance_id, config, instance_token)
```
#### Mark Message as Read
```python
from evolutionapi.models.chat import ReadMessage
message = ReadMessage(
remote_jid="5511999999999@s.whatsapp.net",
from_me=False,
id="message_id"
)
response = client.chat.mark_message_as_read(instance_id, [message], instance_token)
```
#### Archive Chat
```python
from evolutionapi.models.chat import ArchiveChat
config = ArchiveChat(
last_message={
"key": {
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": False,
"id": "message_id",
"participant": "5511999999999@s.whatsapp.net"
},
"message": {
"conversation": "Última mensagem"
}
},
chat="5511999999999@s.whatsapp.net",
archive=True # True para arquivar, False para desarquivar
)
response = client.chat.archive_chat(instance_id, config, instance_token)
```
#### Mark Chat as Unread
```python
from evolutionapi.models.chat import UnreadChat
config = UnreadChat(
last_message={
"key": {
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": False,
"id": "message_id",
"participant": "5511999999999@s.whatsapp.net"
},
"message": {
"conversation": "Última mensagem"
}
},
chat="5511999999999@s.whatsapp.net"
)
response = client.chat.unread_chat(instance_id, config, instance_token)
```
#### Get Chat Profile Picture
```python
from evolutionapi.models.chat import ProfilePicture
config = ProfilePicture(
number="5511999999999"
)
response = client.chat.get_chat_profile_picture(instance_id, config, instance_token)
```
#### Download Media Message
```python
from evolutionapi.models.chat import MediaMessage
config = MediaMessage(
message={
"key": {
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": False,
"id": "message_id",
"participant": "5511999999999@s.whatsapp.net"
},
"message": {
"imageMessage": {
"jpegThumbnail": "base64_da_imagem"
}
}
},
convert_to_mp4=True # opcional, para converter vídeos para MP4
)
response = client.chat.download_media_message(instance_id, config, instance_token)
```
#### Update Message
```python
from evolutionapi.models.chat import UpdateMessage
config = UpdateMessage(
number="5511999999999",
key={
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": False,
"id": "message_id",
"participant": "5511999999999@s.whatsapp.net"
},
text="Mensagem atualizada"
)
response = client.chat.update_message(instance_id, config, instance_token)
```
#### Set Presence
```python
from evolutionapi.models.chat import Presence
config = Presence(
number="5511999999999",
delay=1000, # delay em ms
presence="composing" # "composing", "recording", "paused"
)
response = client.chat.set_presence(instance_id, config, instance_token)
```
### Calls
#### Simulate Call
```python
from evolutionapi.models.call import FakeCall
# Chamada de voz
config = FakeCall(
number="5511999999999",
isVideo=False,
callDuration=30 # duração em segundos
)
# Chamada de vídeo
config = FakeCall(
number="5511999999999",
isVideo=True,
callDuration=30 # duração em segundos
)
response = client.calls.fake_call(instance_id, config, instance_token)
```
### Labels
#### Manage Labels
```python
from evolutionapi.models.label import HandleLabel
# Adicionar etiqueta
config = HandleLabel(
number="5511999999999",
label_id="label_id",
action="add"
)
# Remover etiqueta
config = HandleLabel(
number="5511999999999",
label_id="label_id",
action="remove"
)
response = client.label.handle_label(instance_id, config, instance_token)
```
## WebSocket
The Evolution API client supports WebSocket connection to receive real-time events. Here's a guide on how to use it:
### Prerequisites
Before using WebSocket, you need to:
1. Enable WebSocket in your Evolution API by setting the environment variable:
```bash
WEBSOCKET_ENABLED=true
```
2. Configure WebSocket events for your instance using the WebSocket service:
```python
from evolutionapi.models.websocket import WebSocketConfig
# Configure WebSocket events
config = WebSocketConfig(
enabled=True,
events=[
"APPLICATION_STARTUP",
"QRCODE_UPDATED",
"MESSAGES_SET",
"MESSAGES_UPSERT",
"MESSAGES_UPDATE",
"MESSAGES_DELETE",
"SEND_MESSAGE",
"CONTACTS_SET",
"CONTACTS_UPSERT",
"CONTACTS_UPDATE",
"PRESENCE_UPDATE",
"CHATS_SET",
"CHATS_UPSERT",
"CHATS_UPDATE",
"CHATS_DELETE",
"GROUPS_UPSERT",
"GROUP_UPDATE",
"GROUP_PARTICIPANTS_UPDATE",
"CONNECTION_UPDATE",
"LABELS_EDIT",
"LABELS_ASSOCIATION",
"CALL",
"TYPEBOT_START",
"TYPEBOT_CHANGE_STATUS"
]
)
# Set WebSocket configuration
response = client.websocket.set_websocket(instance_id, config, instance_token)
# Get current WebSocket configuration
websocket_info = client.websocket.find_websocket(instance_id, instance_token)
print(f"WebSocket enabled: {websocket_info.enabled}")
print(f"Configured events: {websocket_info.events}")
```
### Basic Configuration
There are two ways to create a WebSocket manager:
1. Using the client's helper method (recommended):
```python
# Create WebSocket manager using the client
websocket = client.create_websocket(
instance_id="test",
api_token="your_api_token",
max_retries=5, # Maximum number of reconnection attempts
retry_delay=1.0 # Initial delay between attempts in seconds
)
```
2. Creating the manager directly:
```python
from evolutionapi.client import EvolutionClient
import logging
# Logging configuration
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# Initialize client
client = EvolutionClient(
base_url="http://localhost:8081",
api_token="your-api-token"
)
# Create WebSocket manager
websocket = client.create_websocket(
instance_id="test",
api_token="your_api_token",
max_retries=5,
retry_delay=1.0
)
```
### Registering Event Handlers
You can register handlers for different types of events:
```python
def handle_message(data):
print(f"New message received: {data}")
def handle_qrcode(data):
print(f"QR Code updated: {data}")
# Registering handlers
websocket.on("messages.upsert", handle_message)
websocket.on("qrcode.updated", handle_qrcode)
```
### Available Events
The available events are:
#### Instance Events
- `application.startup`: Triggered when the application starts
- `instance.create`: Triggered when a new instance is created
- `instance.delete`: Triggered when an instance is deleted
- `remove.instance`: Triggered when an instance is removed
- `logout.instance`: Triggered when an instance logs out
#### Connection and QR Code Events
- `qrcode.updated`: Triggered when the QR Code is updated
- `connection.update`: Triggered when connection status changes
- `status.instance`: Triggered when instance status changes
- `creds.update`: Triggered when credentials are updated
#### Message Events
- `messages.set`: Triggered when messages are set
- `messages.upsert`: Triggered when new messages are received
- `messages.edited`: Triggered when messages are edited
- `messages.update`: Triggered when messages are updated
- `messages.delete`: Triggered when messages are deleted
- `send.message`: Triggered when a message is sent
- `messaging-history.set`: Triggered when messaging history is set
#### Contact Events
- `contacts.set`: Triggered when contacts are set
- `contacts.upsert`: Triggered when new contacts are added
- `contacts.update`: Triggered when contacts are updated
#### Chat Events
- `chats.set`: Triggered when chats are set
- `chats.update`: Triggered when chats are updated
- `chats.upsert`: Triggered when new chats are added
- `chats.delete`: Triggered when chats are deleted
#### Group Events
- `groups.upsert`: Triggered when groups are created/updated
- `groups.update`: Triggered when groups are updated
- `group-participants.update`: Triggered when group participants are updated
#### Presence Events
- `presence.update`: Triggered when presence status is updated
#### Call Events
- `call`: Triggered when there's a call
#### Typebot Events
- `typebot.start`: Triggered when a typebot starts
- `typebot.change-status`: Triggered when typebot status changes
#### Label Events
- `labels.edit`: Triggered when labels are edited
- `labels.association`: Triggered when labels are associated/disassociated
### Example with Specific Events
```python
def handle_messages(data):
logger.info(f"New message: {data}")
def handle_contacts(data):
logger.info(f"Contacts updated: {data}")
def handle_groups(data):
logger.info(f"Groups updated: {data}")
def handle_presence(data):
logger.info(f"Presence status: {data}")
# Registering handlers for different events
websocket.on("messages.upsert", handle_messages)
websocket.on("contacts.upsert", handle_contacts)
websocket.on("groups.upsert", handle_groups)
websocket.on("presence.update", handle_presence)
```
### Complete Example
```python
from evolutionapi.client import EvolutionClient
from evolutionapi.models.websocket import WebSocketConfig
import logging
import time
# Logging configuration
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def handle_message(data):
logger.info(f"New message received: {data}")
def handle_qrcode(data):
logger.info(f"QR Code updated: {data}")
def handle_connection(data):
logger.info(f"Connection status: {data}")
def main():
# Initialize client
client = EvolutionClient(
base_url="http://localhost:8081",
api_token="your-api-token"
)
# Configure WebSocket
websocket_config = WebSocketConfig(
enabled=True,
events=[
"MESSAGES_UPSERT",
"QRCODE_UPDATED",
"CONNECTION_UPDATE"
]
)
# Set WebSocket configuration
client.websocket.set_websocket("instance_id", websocket_config, "instance_token")
# Create WebSocket manager
websocket = client.create_websocket(
instance_id="instance_id",
api_token="your_api_token",
max_retries=5,
retry_delay=1.0
)
# Register handlers
websocket.on("messages.upsert", handle_message)
websocket.on("qrcode.updated", handle_qrcode)
websocket.on("connection.update", handle_connection)
try:
# Connect to WebSocket
websocket.connect()
logger.info("Connected to WebSocket. Waiting for events...")
# Keep the program running
while True:
time.sleep(1)
except KeyboardInterrupt:
logger.info("Closing connection...")
websocket.disconnect()
except Exception as e:
logger.error(f"Error: {e}")
websocket.disconnect()
if __name__ == "__main__":
main()
```
### Additional Features
#### Automatic Reconnection
The WebSocket Manager has automatic reconnection with exponential backoff:
```python
websocket = client.create_websocket(
instance_id="test",
api_token="your_api_token",
max_retries=5, # Maximum number of reconnection attempts
retry_delay=1.0 # Initial delay between attempts in seconds
)
```
#### Logging
The WebSocket Manager uses Python's logging system. You can adjust the log level as needed:
```python
# For more details
logging.getLogger("evolutionapi.services.websocket").setLevel(logging.DEBUG)
```
### Error Handling
The WebSocket Manager has robust error handling:
- Automatic reconnection on disconnection
- Detailed error logs
- Invalid event handling
- Data validation
### Usage Tips
1. Always use try/except when connecting to WebSocket
2. Implement handlers for all events you need to monitor
3. Use logging for debugging and monitoring
4. Consider implementing a heartbeat mechanism if needed
5. Keep your API token secure and don't expose it in logs
6. Keep your API token secure and don't expose it in logs