mirror of
https://github.com/EvolutionAPI/evolution-client-python.git
synced 2025-07-13 15:14:48 -06:00

- 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
1246 lines
27 KiB
Markdown
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
|