Skip to content

Commit 2b21884

Browse files
committed
version: 0.0.5
1 parent 2b7ce3a commit 2b21884

File tree

8 files changed

+191
-70
lines changed

8 files changed

+191
-70
lines changed

build/lib/evolutionapi/client.py

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import requests
2+
from requests_toolbelt import MultipartEncoder
23
from .exceptions import EvolutionAuthenticationError, EvolutionNotFoundError, EvolutionAPIError
34
from .services.instance import InstanceService
45
from .services.instance_operations import InstanceOperationsService
@@ -62,11 +63,43 @@ def get(self, endpoint: str, instance_token: str = None):
6263
response = requests.get(url, headers=self._get_headers(instance_token))
6364
return self._handle_response(response)
6465

65-
def post(self, endpoint: str, data: dict = None, instance_token: str = None):
66-
"""Faz uma requisição POST."""
67-
url = self._get_full_url(endpoint)
68-
response = requests.post(url, headers=self._get_headers(instance_token), json=data)
69-
return self._handle_response(response)
66+
def post(self, endpoint: str, data: dict = None, instance_token: str = None, files: dict = None):
67+
url = f'{self.base_url}/{endpoint}'
68+
headers = self._get_headers(instance_token)
69+
70+
if files:
71+
# Remove o Content-Type do header quando enviando arquivos
72+
if 'Content-Type' in headers:
73+
del headers['Content-Type']
74+
75+
# Prepara os campos do multipart
76+
fields = {}
77+
78+
# Adiciona os campos do data
79+
for key, value in data.items():
80+
fields[key] = str(value) if not isinstance(value, (int, float)) else (None, str(value), 'text/plain')
81+
82+
# Adiciona o arquivo
83+
file_tuple = files['file']
84+
fields['file'] = (file_tuple[0], file_tuple[1], file_tuple[2])
85+
86+
# Cria o multipart encoder
87+
multipart = MultipartEncoder(fields=fields)
88+
headers['Content-Type'] = multipart.content_type
89+
90+
response = requests.post(
91+
url,
92+
headers=headers,
93+
data=multipart
94+
)
95+
else:
96+
response = requests.post(
97+
url,
98+
headers=headers,
99+
json=data
100+
)
101+
102+
return response.json()
70103

71104
def put(self, endpoint, data=None):
72105
"""Faz uma requisição PUT."""

build/lib/evolutionapi/models/message.py

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,28 +53,34 @@ class MediaMessage(BaseMessage):
5353
def __init__(
5454
self,
5555
number: str,
56-
mediatype: str,
57-
mimetype: str,
58-
caption: str,
59-
media: str,
60-
fileName: str,
61-
delay: Optional[int] = None,
56+
media: dict = None,
57+
mediatype: Optional[str] = None,
58+
caption: str = None,
59+
mimetype: str = None,
60+
fileName: str = None,
61+
delay: Optional[Union[int, float, str]] = None,
6262
quoted: Optional[QuotedMessage] = None,
6363
mentionsEveryOne: Optional[bool] = None,
6464
mentioned: Optional[List[str]] = None
6565
):
66-
super().__init__(
67-
number=number,
68-
mediatype=mediatype,
69-
mimetype=mimetype,
70-
caption=caption,
71-
media=media,
72-
fileName=fileName,
73-
delay=delay,
74-
quoted=quoted.__dict__ if quoted else None,
75-
mentionsEveryOne=mentionsEveryOne,
76-
mentioned=mentioned
77-
)
66+
data = {
67+
'number': number,
68+
'mediatype': mediatype,
69+
'caption': caption,
70+
'mimetype': mimetype,
71+
'fileName': fileName,
72+
'quoted': quoted.__dict__ if quoted else None,
73+
'mentionsEveryOne': mentionsEveryOne,
74+
'mentioned': mentioned
75+
}
76+
77+
if delay is not None:
78+
data['delay'] = delay
79+
80+
if media and media != {}:
81+
data['media'] = media
82+
83+
super().__init__(**{k: v for k, v in data.items() if v is not None})
7884

7985
class StatusMessage(BaseMessage):
8086
def __init__(
Lines changed: 127 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,118 @@
11
from typing import Union, BinaryIO
22
from ..models.message import *
3+
from requests_toolbelt import MultipartEncoder
4+
import mimetypes
5+
import requests
36

47
class MessageService:
58
def __init__(self, client):
69
self.client = client
710

811
def send_text(self, instance_id: str, message: TextMessage, instance_token: str):
12+
# Preparar os dados como JSON
13+
data = {
14+
'number': message.number,
15+
'text': message.text
16+
}
17+
18+
if hasattr(message, 'delay') and message.delay is not None:
19+
data['delay'] = message.delay
20+
21+
# Usar o método post do cliente que já trata JSON corretamente
922
return self.client.post(
1023
f'message/sendText/{instance_id}',
11-
data=message.__dict__,
24+
data=data,
1225
instance_token=instance_token
1326
)
1427

1528
def send_media(self, instance_id: str, message: MediaMessage, instance_token: str, file: Union[BinaryIO, str] = None):
16-
payload = {
17-
'data': message.__dict__,
18-
'instance_token': instance_token
29+
# Preparar os dados do formulário
30+
fields = {
31+
'number': (None, message.number, 'text/plain'),
32+
'mediatype': (None, message.mediatype, 'text/plain'),
33+
'mimetype': (None, message.mimetype, 'text/plain'),
34+
'caption': (None, message.caption, 'text/plain'),
35+
'fileName': (None, message.fileName, 'text/plain'),
1936
}
2037

38+
# Adicionar delay apenas se existir
39+
if hasattr(message, 'delay') and message.delay is not None:
40+
fields['delay'] = (None, str(message.delay), 'text/plain; type=number')
41+
42+
# Adicionar o arquivo se fornecido
2143
if file:
2244
if isinstance(file, str):
23-
with open(file, 'rb') as f:
24-
payload['files'] = {'file': f}
45+
mime_type = mimetypes.guess_type(file)[0] or 'application/octet-stream'
46+
fields['file'] = ('file', open(file, 'rb'), mime_type)
2547
else:
26-
payload['files'] = {'file': file}
27-
28-
return self.client.post(
29-
f'message/sendMedia/{instance_id}',
30-
**payload
48+
fields['file'] = ('file', file, 'application/octet-stream')
49+
50+
# Criar o multipart encoder
51+
multipart = MultipartEncoder(fields=fields)
52+
53+
# Preparar os headers
54+
headers = self.client._get_headers(instance_token)
55+
headers['Content-Type'] = multipart.content_type
56+
57+
# Fazer a requisição diretamente
58+
url = f'{self.client.base_url}/message/sendMedia/{instance_id}'
59+
response = requests.post(
60+
url,
61+
headers=headers,
62+
data=multipart
3163
)
64+
65+
return response.json()
3266

3367
def send_ptv(self, instance_id: str, message: dict, instance_token: str, file: Union[BinaryIO, str] = None):
34-
payload = {
35-
'data': message,
36-
'instance_token': instance_token
37-
}
68+
fields = {}
69+
70+
# Adiciona todos os campos do message como text/plain
71+
for key, value in message.items():
72+
if key == 'delay' and value is not None:
73+
fields[key] = (None, str(value), 'text/plain; type=number')
74+
else:
75+
fields[key] = (None, str(value), 'text/plain')
3876

3977
if file:
4078
if isinstance(file, str):
41-
with open(file, 'rb') as f:
42-
payload['files'] = {'file': f}
79+
mime_type = mimetypes.guess_type(file)[0] or 'application/octet-stream'
80+
fields['file'] = ('file', open(file, 'rb'), mime_type)
4381
else:
44-
payload['files'] = {'file': file}
45-
46-
return self.client.post(
47-
f'message/sendPtv/{instance_id}',
48-
**payload
49-
)
82+
fields['file'] = ('file', file, 'application/octet-stream')
83+
84+
multipart = MultipartEncoder(fields=fields)
85+
headers = self.client._get_headers(instance_token)
86+
headers['Content-Type'] = multipart.content_type
87+
88+
url = f'{self.client.base_url}/message/sendPtv/{instance_id}'
89+
response = requests.post(url, headers=headers, data=multipart)
90+
return response.json()
5091

5192
def send_whatsapp_audio(self, instance_id: str, message: dict, instance_token: str, file: Union[BinaryIO, str] = None):
52-
payload = {
53-
'data': message,
54-
'instance_token': instance_token
55-
}
93+
fields = {}
94+
95+
# Adiciona todos os campos do message como text/plain
96+
for key, value in message.items():
97+
if key == 'delay' and value is not None:
98+
fields[key] = (None, str(value), 'text/plain; type=number')
99+
else:
100+
fields[key] = (None, str(value), 'text/plain')
56101

57102
if file:
58103
if isinstance(file, str):
59-
with open(file, 'rb') as f:
60-
payload['files'] = {'file': f}
104+
mime_type = mimetypes.guess_type(file)[0] or 'application/octet-stream'
105+
fields['file'] = ('file', open(file, 'rb'), mime_type)
61106
else:
62-
payload['files'] = {'file': file}
63-
64-
return self.client.post(
65-
f'message/sendWhatsAppAudio/{instance_id}',
66-
**payload
67-
)
107+
fields['file'] = ('file', file, 'application/octet-stream')
108+
109+
multipart = MultipartEncoder(fields=fields)
110+
headers = self.client._get_headers(instance_token)
111+
headers['Content-Type'] = multipart.content_type
112+
113+
url = f'{self.client.base_url}/message/sendWhatsAppAudio/{instance_id}'
114+
response = requests.post(url, headers=headers, data=multipart)
115+
return response.json()
68116

69117
def send_status(self, instance_id: str, message: StatusMessage, instance_token: str):
70118
return self.client.post(
@@ -73,17 +121,39 @@ def send_status(self, instance_id: str, message: StatusMessage, instance_token:
73121
instance_token=instance_token
74122
)
75123

76-
def send_sticker(self, instance_id: str, message: dict, instance_token: str):
77-
return self.client.post(
78-
f'message/sendSticker/{instance_id}',
79-
data=message,
80-
instance_token=instance_token
81-
)
124+
def send_sticker(self, instance_id: str, message: dict, instance_token: str, file: Union[BinaryIO, str] = None):
125+
fields = {}
126+
127+
# Adiciona todos os campos do message como text/plain
128+
for key, value in message.items():
129+
if key == 'delay' and value is not None:
130+
fields[key] = (None, str(value), 'text/plain; type=number')
131+
else:
132+
fields[key] = (None, str(value), 'text/plain')
133+
134+
if file:
135+
if isinstance(file, str):
136+
mime_type = mimetypes.guess_type(file)[0] or 'application/octet-stream'
137+
fields['file'] = ('file', open(file, 'rb'), mime_type)
138+
else:
139+
fields['file'] = ('file', file, 'application/octet-stream')
140+
141+
multipart = MultipartEncoder(fields=fields)
142+
headers = self.client._get_headers(instance_token)
143+
headers['Content-Type'] = multipart.content_type
144+
145+
url = f'{self.client.base_url}/message/sendSticker/{instance_id}'
146+
response = requests.post(url, headers=headers, data=multipart)
147+
return response.json()
82148

83149
def send_location(self, instance_id: str, message: LocationMessage, instance_token: str):
150+
data = message.__dict__.copy()
151+
if 'delay' in data and data['delay'] is not None:
152+
data['delay'] = int(data['delay'])
153+
84154
return self.client.post(
85155
f'message/sendLocation/{instance_id}',
86-
data=message.__dict__,
156+
data=data,
87157
instance_token=instance_token
88158
)
89159

@@ -102,22 +172,34 @@ def send_reaction(self, instance_id: str, message: ReactionMessage, instance_tok
102172
)
103173

104174
def send_poll(self, instance_id: str, message: PollMessage, instance_token: str):
175+
data = message.__dict__.copy()
176+
if 'delay' in data and data['delay'] is not None:
177+
data['delay'] = int(data['delay'])
178+
105179
return self.client.post(
106180
f'message/sendPoll/{instance_id}',
107-
data=message.__dict__,
181+
data=data,
108182
instance_token=instance_token
109183
)
110184

111185
def send_list(self, instance_id: str, message: ListMessage, instance_token: str):
186+
data = message.__dict__.copy()
187+
if 'delay' in data and data['delay'] is not None:
188+
data['delay'] = int(data['delay'])
189+
112190
return self.client.post(
113191
f'message/sendList/{instance_id}',
114-
data=message.__dict__,
192+
data=data,
115193
instance_token=instance_token
116194
)
117195

118196
def send_buttons(self, instance_id: str, message: ButtonMessage, instance_token: str):
197+
data = message.__dict__.copy()
198+
if 'delay' in data and data['delay'] is not None:
199+
data['delay'] = int(data['delay'])
200+
119201
return self.client.post(
120202
f'message/sendButtons/{instance_id}',
121-
data=message.__dict__,
203+
data=data,
122204
instance_token=instance_token
123205
)

dist/evolutionapi-0.0.4.tar.gz

-8.97 KB
Binary file not shown.

dist/evolutionapi-0.0.5.tar.gz

9.97 KB
Binary file not shown.

evolutionapi.egg-info/PKG-INFO

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Metadata-Version: 2.1
22
Name: evolutionapi
3-
Version: 0.0.4
3+
Version: 0.0.5
44
Summary: Client Python para a API Evolution
55
Home-page: UNKNOWN
66
Author: Davidson Gomes

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
setup(
44
name='evolutionapi',
5-
version='0.0.4',
5+
version='0.0.5',
66
description='Client Python para a API Evolution',
77
author='Davidson Gomes',
88
author_email='contato@agenciadgcode.com',

0 commit comments

Comments
 (0)