|
| 1 | +--- |
| 2 | +name: greenapi-client-python |
| 3 | +description: > |
| 4 | + Write correct Python code with the official GREEN-API SDK whatsapp-api-client-python |
| 5 | + (package whatsapp_api_client_python). Use when sending/receiving WhatsApp messages, |
| 6 | + files, polls, groups, journals, queues, statuses, contacts, partner instances, polling |
| 7 | + notifications, or configuring a GREEN-API instance in Python. Triggers: GREEN-API, |
| 8 | + green-api, whatsapp-api-client-python, GreenAPI, GreenApi, sendMessage, receiveNotification. |
| 9 | +license: MIT |
| 10 | +metadata: |
| 11 | + version: "1.0.0" |
| 12 | + sdk: whatsapp-api-client-python |
| 13 | + pypi: whatsapp-api-client-python |
| 14 | + docs: https://green-api.com/en/docs/api/ |
| 15 | + github: https://github.com/green-api/whatsapp-api-client-python |
| 16 | +--- |
| 17 | + |
| 18 | +# GREEN-API Python client (`whatsapp-api-client-python`) |
| 19 | + |
| 20 | +## When to apply |
| 21 | + |
| 22 | +Use this skill whenever the task is to call GREEN-API from **Python** via the official |
| 23 | +SDK. Do **not** invent HTTP paths or method names from memory: only methods listed in |
| 24 | +[references/inventory.md](references/inventory.md) exist in this SDK. Semantics of |
| 25 | +parameters, `chatId` formats, delays, and notification types come from the official docs |
| 26 | +linked in each method section — not from other repos. |
| 27 | + |
| 28 | +For **webhook HTTP server** libraries in other languages, use a language-specific |
| 29 | +webhook skill if present. This SDK receives notifications via **polling** |
| 30 | +(`webhooks.startReceivingNotifications` / `receiving.receiveNotification`) or you can |
| 31 | +build your own HTTP endpoint for webhook-endpoint technology. |
| 32 | + |
| 33 | +## Sources of truth (mandatory) |
| 34 | + |
| 35 | +1. **Official API docs** — https://green-api.com/en/docs/api/ |
| 36 | + Parameters, response shapes, limits, `chatId`, delays, notification formats. |
| 37 | +2. **This repository / installed package** — method names, class attributes, init |
| 38 | + signatures. Inventory: [references/inventory.md](references/inventory.md). |
| 39 | + |
| 40 | +If a method exists in the docs but **not** in the inventory → do not use it in code. |
| 41 | + |
| 42 | +## Install |
| 43 | + |
| 44 | +```shell |
| 45 | +python -m pip install whatsapp-api-client-python |
| 46 | +``` |
| 47 | + |
| 48 | +Requires Python **>= 3.10**. Credentials: `idInstance` and `apiTokenInstance` from |
| 49 | +[console.green-api.com](https://console.green-api.com/). |
| 50 | + |
| 51 | +## Client initialization |
| 52 | + |
| 53 | +```python |
| 54 | +from whatsapp_api_client_python import API |
| 55 | + |
| 56 | +greenAPI = API.GreenAPI( |
| 57 | + "1101000001", # idInstance (string) |
| 58 | + "d75b3a66374942c5b3c019c698abc2067e151558acbd412345", # apiTokenInstance |
| 59 | +) |
| 60 | +``` |
| 61 | + |
| 62 | +Optional constructor kwargs (from `GreenApi.__init__` in `API.py`): |
| 63 | + |
| 64 | +| Kwarg | Default | Meaning | |
| 65 | +| --- | --- | --- | |
| 66 | +| `debug_mode` | `False` | Verbose request logging | |
| 67 | +| `raise_errors` | `False` | Raise `GreenAPIError` on failures | |
| 68 | +| `host` | `https://api.green-api.com` | API host (`apiUrl`) | |
| 69 | +| `media` | `https://media.green-api.com` | Media host for uploads | |
| 70 | +| `host_timeout` | `180` | Seconds per host request retry | |
| 71 | +| `media_timeout` | `10800` | Seconds per media request | |
| 72 | + |
| 73 | +Aliases: `API.GreenAPI` is the same class as `API.GreenApi`. |
| 74 | + |
| 75 | +Partner API (separate client): |
| 76 | + |
| 77 | +```python |
| 78 | +partner = API.GreenApiPartner(partnerToken="PARTNER_TOKEN") |
| 79 | +# then: partner.partner.getInstances() / createInstance / deleteInstanceAccount |
| 80 | +``` |
| 81 | + |
| 82 | +### Response object |
| 83 | + |
| 84 | +Every API method returns `whatsapp_api_client_python.response.Response`: |
| 85 | + |
| 86 | +| Attribute | When | Content | |
| 87 | +| --- | --- | --- | |
| 88 | +| `code` | always | HTTP status, or `None` on transport failure | |
| 89 | +| `data` | `code == 200` | Parsed JSON (`dict` / list) | |
| 90 | +| `error` | non-200 | Response body text | |
| 91 | + |
| 92 | +Always check `response.code == 200` before reading `response.data`. |
| 93 | + |
| 94 | +### Async |
| 95 | + |
| 96 | +Most groups expose `*Async` twins (`sendMessageAsync`, `receiveNotificationAsync`, …). |
| 97 | +Call them with `await` inside `asyncio`. |
| 98 | + |
| 99 | +## chatId and phone format |
| 100 | + |
| 101 | +Docs: https://green-api.com/en/docs/api/chat-id/ |
| 102 | + |
| 103 | +| Kind | Format | Example | |
| 104 | +| --- | --- | --- | |
| 105 | +| Personal chat | `<phone>@c.us` | `79876543210@c.us` | |
| 106 | +| Group chat | `...@g.us` | `120363043968066561@g.us` | |
| 107 | +| Lid | `...@lid` | returned by API; do not invent | |
| 108 | + |
| 109 | +- Phone: full international number, **digits only**, no `+`, spaces, or leading zeros tricks. |
| 110 | +- **Never** hand-craft group IDs — take them from `createGroup`, journals, or notifications. |
| 111 | +- Wrong `chatId` → validation 400: must be `phone_number@c.us` or `group_id@g.us`. |
| 112 | + |
| 113 | +## Instance must be authorized |
| 114 | + |
| 115 | +Docs: https://green-api.com/en/docs/api/account/GetStateInstance/ |
| 116 | + |
| 117 | +Before sending, verify: |
| 118 | + |
| 119 | +```python |
| 120 | +state = greenAPI.account.getStateInstance() |
| 121 | +print(state.data) # expect {"stateInstance": "authorized"} |
| 122 | +``` |
| 123 | + |
| 124 | +Important states: `authorized`, `notAuthorized`, `blocked`, `starting`, `suspended`. |
| 125 | +Authorize via console QR / `account.qr()` / `account.getAuthorizationCode(phoneNumber)`. |
| 126 | +Messages sit in the send queue up to **24 hours** until the instance is authorized. |
| 127 | + |
| 128 | +## Message sending delay |
| 129 | + |
| 130 | +Docs: https://green-api.com/en/docs/api/send-messages-delay/ |
| 131 | + |
| 132 | +Outgoing messages go through a FIFO queue. Delay is controlled by instance setting |
| 133 | +`delaySendMessagesMilliseconds` (min **500** ms, max **600000** ms; recommend ≤ 300000): |
| 134 | + |
| 135 | +```python |
| 136 | +greenAPI.account.setSettings({"delaySendMessagesMilliseconds": 5000}) |
| 137 | +``` |
| 138 | + |
| 139 | +Note: `setSettings` reboots the instance; settings apply within ~5 minutes. |
| 140 | + |
| 141 | +## Typical scenarios |
| 142 | + |
| 143 | +### 1. Send a text message |
| 144 | + |
| 145 | +Docs: https://green-api.com/en/docs/api/sending/SendMessage/ |
| 146 | + |
| 147 | +```python |
| 148 | +from whatsapp_api_client_python import API |
| 149 | + |
| 150 | +greenAPI = API.GreenAPI(id_instance, api_token) |
| 151 | + |
| 152 | +response = greenAPI.sending.sendMessage( |
| 153 | + "79876543210@c.us", |
| 154 | + "Hello from GREEN-API", |
| 155 | + typingTime=3000, # optional: 1000–20000 ms typing indicator |
| 156 | +) |
| 157 | + |
| 158 | +if response.code == 200: |
| 159 | + print(response.data["idMessage"]) |
| 160 | +else: |
| 161 | + print(response.error) |
| 162 | +``` |
| 163 | + |
| 164 | +Required: `chatId`, `message` (max 20000 chars). Optional in SDK: `quotedMessageId`, |
| 165 | +`archiveChat`, `linkPreview`, `typingTime`, `typePreview`, `customPreview`. |
| 166 | +Response: `{ "idMessage": "..." }`. |
| 167 | + |
| 168 | +### 2. Send a file by URL |
| 169 | + |
| 170 | +Docs: https://green-api.com/en/docs/api/sending/SendFileByUrl/ |
| 171 | + |
| 172 | +```python |
| 173 | +response = greenAPI.sending.sendFileByUrl( |
| 174 | + "79876543210@c.us", |
| 175 | + "https://download.samplelib.com/png/sample-clouds2-400x300.png", |
| 176 | + "sample-clouds2-400x300.png", |
| 177 | + "Caption text", |
| 178 | +) |
| 179 | +``` |
| 180 | + |
| 181 | +Required: `chatId`, `urlFile`, `fileName` (with extension). Max file size **100 MB**. |
| 182 | + |
| 183 | +### 3. Send a file by upload (local path) |
| 184 | + |
| 185 | +Docs: https://green-api.com/en/docs/api/sending/SendFileByUpload/ |
| 186 | +Uses **media** host (SDK sets this automatically). |
| 187 | + |
| 188 | +```python |
| 189 | +response = greenAPI.sending.sendFileByUpload( |
| 190 | + "79876543210@c.us", |
| 191 | + "data/logo.jpg", |
| 192 | + "logo.jpg", |
| 193 | + "Available rates", |
| 194 | +) |
| 195 | +# response.data: idMessage, urlFile (link valid 15 days) |
| 196 | +``` |
| 197 | + |
| 198 | +SDK signature: `sendFileByUpload(chatId, path, fileName=None, caption=None, ...)`. |
| 199 | +The local path is the second argument (`path`), not a raw file object. |
| 200 | + |
| 201 | +### 4. Receive notifications — polling (built-in) |
| 202 | + |
| 203 | +Docs: https://green-api.com/en/docs/api/receiving/technology-http-api/ReceiveNotification/ |
| 204 | + |
| 205 | +**Requirement:** instance `webhookUrl` must be **empty**. If a custom webhook URL is set, |
| 206 | +`receiveNotification` returns an error telling you to clear it. |
| 207 | + |
| 208 | +```python |
| 209 | +from whatsapp_api_client_python import API |
| 210 | + |
| 211 | +greenAPI = API.GreenAPI(id_instance, api_token) |
| 212 | + |
| 213 | + |
| 214 | +def on_event(type_webhook: str, body: dict) -> None: |
| 215 | + if type_webhook == "incomingMessageReceived": |
| 216 | + chat_id = body["senderData"]["chatId"] |
| 217 | + msg = body["messageData"] |
| 218 | + if msg.get("typeMessage") == "textMessage": |
| 219 | + text = msg["textMessageData"]["textMessage"] |
| 220 | + print(chat_id, text) |
| 221 | + |
| 222 | + |
| 223 | +# Blocks; Ctrl+C to stop. Internally: receiveNotification → handler → deleteNotification |
| 224 | +greenAPI.webhooks.startReceivingNotifications(on_event) |
| 225 | +``` |
| 226 | + |
| 227 | +Handler signature is fixed: `(typeWebhook: str, body: dict)`. |
| 228 | +After handling, the SDK deletes the notification by `receiptId` (do not skip this |
| 229 | +if you poll manually). |
| 230 | + |
| 231 | +Manual poll loop: |
| 232 | + |
| 233 | +```python |
| 234 | +resp = greenAPI.receiving.receiveNotification(receiveTimeout=5) |
| 235 | +if resp.code == 200 and resp.data: |
| 236 | + receipt_id = resp.data["receiptId"] |
| 237 | + body = resp.data["body"] |
| 238 | + # ... process body["typeWebhook"] ... |
| 239 | + greenAPI.receiving.deleteNotification(receipt_id) |
| 240 | +``` |
| 241 | + |
| 242 | +`receiveTimeout`: 5–60 seconds (API default 5). Empty queue → empty body / no data. |
| 243 | +Notifications live in the queue **24 hours**, FIFO. |
| 244 | + |
| 245 | +### 5. Receive notifications — webhook endpoint (your HTTP server) |
| 246 | + |
| 247 | +Docs: https://green-api.com/en/docs/api/receiving/technology-webhook-endpoint/ |
| 248 | + |
| 249 | +This SDK does **not** ship a webhook HTTP server. Configure the instance, then run your |
| 250 | +own endpoint that accepts POST JSON and returns 200: |
| 251 | + |
| 252 | +```python |
| 253 | +greenAPI.account.setSettings({ |
| 254 | + "webhookUrl": "https://your.public.host/webhook", |
| 255 | + "webhookUrlToken": "Bearer your-secret", # optional; see docs for Basic/Bearer |
| 256 | + "incomingWebhook": "yes", |
| 257 | + "outgoingWebhook": "yes", |
| 258 | + "outgoingAPIMessageWebhook": "yes", |
| 259 | + "stateWebhook": "yes", |
| 260 | +}) |
| 261 | +``` |
| 262 | + |
| 263 | +GREEN-API POSTs notification JSON to `webhookUrl`. Retries every ~1 minute; guaranteed |
| 264 | +within 24 hours. While `webhookUrl` is set, **polling will not receive** those notifications. |
| 265 | + |
| 266 | +Common `typeWebhook` values: `incomingMessageReceived`, `outgoingMessageReceived`, |
| 267 | +`outgoingAPIMessageReceived`, `outgoingMessageStatus`, `stateInstanceChanged`, |
| 268 | +`statusInstanceChanged`, `incomingCall`, `outgoingCall`, `quotaExceeded`, … |
| 269 | +Full list: https://green-api.com/en/docs/api/receiving/notifications-format/type-webhook/ |
| 270 | + |
| 271 | +### 6. Create a group and message it |
| 272 | + |
| 273 | +Docs: https://green-api.com/en/docs/api/groups/CreateGroup/ |
| 274 | + |
| 275 | +```python |
| 276 | +created = greenAPI.groups.createGroup("Group Name", ["79876543210@c.us"]) |
| 277 | +if created.code == 200 and created.data.get("created"): |
| 278 | + chat_id = created.data["chatId"] # ...@g.us |
| 279 | + greenAPI.sending.sendMessage(chat_id, "Hello group") |
| 280 | +``` |
| 281 | + |
| 282 | +Do not create groups faster than about **1 per 5 minutes** (anti-spam). Invalid numbers |
| 283 | +can get the sender blocked. |
| 284 | + |
| 285 | +## API surface map (SDK attributes) |
| 286 | + |
| 287 | +Access as `greenAPI.<group>.<method>(...)`. |
| 288 | + |
| 289 | +| Attribute | Class | Reference | |
| 290 | +| --- | --- | --- | |
| 291 | +| `account` | `Account` | [references/account.md](references/account.md) | |
| 292 | +| `sending` | `Sending` | [references/sending.md](references/sending.md) | |
| 293 | +| `receiving` | `Receiving` | [references/receiving.md](references/receiving.md) | |
| 294 | +| `webhooks` | `Webhooks` | [references/receiving.md](references/receiving.md) | |
| 295 | +| `groups` | `Groups` | [references/groups.md](references/groups.md) | |
| 296 | +| `journals` | `Journals` | [references/journals.md](references/journals.md) | |
| 297 | +| `queues` | `Queues` | [references/queues.md](references/queues.md) | |
| 298 | +| `serviceMethods` | `ServiceMethods` | [references/service-methods.md](references/service-methods.md) | |
| 299 | +| `marking` | `Marking` | [references/marking.md](references/marking.md) | |
| 300 | +| `contacts` | `Contacts` | [references/contacts.md](references/contacts.md) | |
| 301 | +| `statuses` | `Statuses` | [references/statuses.md](references/statuses.md) | |
| 302 | +| `device` | `Device` | [references/device.md](references/device.md) | |
| 303 | +| `partner` | `Partner` | only on `GreenApiPartner` — [references/partner.md](references/partner.md) | |
| 304 | + |
| 305 | +Full method list + signatures: [references/inventory.md](references/inventory.md). |
| 306 | + |
| 307 | +## Pitfalls (read before coding) |
| 308 | + |
| 309 | +1. **`chatId` format** — personal `phone@c.us`, group `id@g.us`. No `+` in the phone part. |
| 310 | +2. **Authorized instance** — `getStateInstance` must be `authorized` for delivery. |
| 311 | +3. **Polling vs webhook** — mutually exclusive for the same traffic: clear `webhookUrl` |
| 312 | + for HTTP API polling; set `webhookUrl` for push. |
| 313 | +4. **Always `deleteNotification`** after processing a polled notification, or the same |
| 314 | + event will be returned forever. |
| 315 | +5. **Sending delay** — use `delaySendMessagesMilliseconds` ≥ 500 ms; bulk blasts without |
| 316 | + delay risk limits / bans. |
| 317 | +6. **File size** — max 100 MB; `sendFileByUpload` goes to `media.green-api.com`. |
| 318 | +7. **Response handling** — use `response.data` only when `response.code == 200`. |
| 319 | +8. **Deprecated sending APIs** still in SDK but marked deprecated: `sendButtons`, |
| 320 | + `sendTemplateButtons`, `sendListMessage`, `sendLink` — prefer |
| 321 | + `sendInteractiveButtons` / `sendInteractiveButtonsReply` / `sendMessage`. |
| 322 | +9. **`serviceMethods` attribute name** — camelCase `serviceMethods`, not `service`. |
| 323 | +10. **Partner methods** require `GreenApiPartner`, not `GreenAPI`. |
| 324 | +11. **Groups rate limit** — create groups slowly; non-existent numbers are dangerous. |
| 325 | +12. **Hosts** — default `api.green-api.com` / `media.green-api.com`; some accounts use |
| 326 | + instance-specific hosts from console — pass `host=` / `media=` if console shows them. |
| 327 | + |
| 328 | +## Agent checklist |
| 329 | + |
| 330 | +When writing code for the user: |
| 331 | + |
| 332 | +- [ ] Import `from whatsapp_api_client_python import API` |
| 333 | +- [ ] Init `API.GreenAPI(idInstance, apiTokenInstance)` with real or env credentials |
| 334 | +- [ ] Use only methods from [references/inventory.md](references/inventory.md) |
| 335 | +- [ ] Format `chatId` as `@c.us` / `@g.us` |
| 336 | +- [ ] Check `response.code` before `response.data` |
| 337 | +- [ ] For receive: either polling (`startReceivingNotifications` / manual receive+delete) |
| 338 | + or webhook endpoint + `setSettings`, not a fictional SDK method |
| 339 | +- [ ] Prefer reading the matching `references/*.md` file for parameters before coding |
| 340 | +- [ ] Prefer official docs URL from the method docstring when unsure about edge cases |
0 commit comments