shade-plugins-hubspot
Busca contatos e negócios, cria ou atualiza um contato pelo e-mail e move um negócio de estágio no
HubSpot CRM (API v3), de dentro
de um robô do shade-sdk, com o token OAuth da conexão do
HubSpot na plataforma. Só a biblioteca padrão do Python: nenhuma dependência além do shade-sdk.
No shade.toml do robô, o host da API vai em [hosts] permitidos e a conexão em [conexoes]:
[hosts]
permitidos = ["api.hubapi.com"]
[conexoes]
nomes = ["hubspot"]
[plugins]
hubspot = "0.1.2"
import shade_plugins_hubspot as hubspot
# Leitura: roda inclusive no ensaio.
negocios = hubspot.buscar_negocios({"dealstage": "contractsent"}, propriedades=["dealname"])
# Escrita: só dentro de item.efetivar() (no ensaio não roda).
with item.efetivar("registrar o cliente"):
hubspot.upsert_contato(item["email"], {"firstname": item["nome"], "phone": item["fone"]})
hubspot.mover_negocio(negocios[0]["id"], "closedwon")
A conta
- Conexão: o robô nunca vê a senha nem o refresh token. O token de acesso chega sob demanda da
conexão
hubspotda plataforma e é renovado por ela. Fora da plataforma (no laptop), ponha um token de acesso emSHADE_TOKEN_HUBSPOT. - Escopos:
crm.objects.contacts.read,crm.objects.contacts.write,crm.objects.deals.readecrm.objects.deals.write. A conexão sem o escopo de uma operação é recusada pelo HubSpot, e o erro manda reconectar o HubSpot. - Propriedades são os nomes internos do HubSpot (
firstname,dealstage), e o estágio do negócio é o id interno do estágio do funil (closedwon), não o nome que aparece na tela.
O que o plugin garante
- Contato sem duplicar.
upsert_contatousa o upsert em lote do HubSpot comidProperty=email: o mesmo e-mail é sempre um contato só, e a segunda chamada atualiza as propriedades que cita (as outras ficam como estavam). Repetir a chamada é seguro, então a falha transitória é repetida dentro dotimeout=. - Negócio sem
PATCHà toa.mover_negociolê o estágio e, se o negócio já está no estágio pedido, não escreve nada (movido=False). Se oPATCHsai sem confirmação, o plugin confere o estágio: igual ao pedido é sucesso; diferente éHubSpotIncerto. - Só dentro de
item.efetivar(). Fora dele, a operação é um erro de contrato antes de qualquer byte; no ensaio, o bloco é pulado e nada é enviado. - Valores literais. Os valores vão como texto, num corpo montado como objeto e serializado pelo
shade_sdk.http, nunca por concatenação. O nome de propriedade, o id e o estágio são validados antes de qualquer pedido. - Host e prazo: só
api.hubapi.com, com o certificado verificado, sem seguir redirecionamento; toda chamada aceitatimeout=(30 s por padrão), que vale para a chamada inteira. - Sem conteúdo em evento nem em erro: cada chamada emite um evento com a operação, o host, a
duração e o status. Nunca o e-mail, as propriedades, o token nem o corpo da resposta; o erro da
API chega só pela categoria que o HubSpot dá (
VALIDATION_ERROR,MISSING_SCOPES).
Operações
| Operação | Efeito | O que faz |
|---|---|---|
buscar_contatos(filtros, propriedades=None, *, limite=100) |
não | Contatos que atendem a todos os filtros: id e propriedades. |
upsert_contato(email, propriedades) |
sim | Cria ou atualiza o contato do e-mail. Devolve id, email e novo. |
buscar_negocios(filtros, propriedades=None, *, limite=100) |
não | Negócios que atendem a todos os filtros: id e propriedades. |
mover_negocio(id, estagio) |
sim | Move o negócio para o estágio. Devolve id, estagio e movido. |
Os filtros são um dicionário: {"dealstage": "contractsent"} (igual) ou
{"amount": ["GTE", 1000]} (operador e valor: EQ, NEQ, LT, LTE, GT, GTE,
CONTAINS_TOKEN, NOT_CONTAINS_TOKEN; ["HAS_PROPERTY"] e ["NOT_HAS_PROPERTY"] sem valor). Todos
valem ao mesmo tempo, até 6 por busca.
Limites
- A busca do HubSpot devolve no máximo 10 000 registros por consulta e enxerga o que acabou de ser
criado com um pequeno atraso: não use
buscar_contatospara conferir o contato que oupsert_contatoacabou de gravar (o upsert já devolve oid). - Criar negócio e propriedade customizada ficam fora do plugin.
Testes
A suíte de contrato do shade_sdk.testing.plugins e um servidor falso da API (TLS de uma CA de
teste, que só aceita valor em texto e recusa propriedade e estágio inexistentes, como a de
verdade) acompanham o código-fonte em tests/.
Metadata
Release files for shade-plugins-hubspot 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| shade_plugins_hubspot-0.1.2-py3-none-any.whl | Python 3 | none | any | Details for shade_plugins_hubspot-0.1.2-py3-none-any.whl |
Release files / shade_plugins_hubspot-0.1.2-py3-none-any.whl
| Download URL | shade_plugins_hubspot-0.1.2-py3-none-any.whl |
|---|---|
| Size | 19.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
15564dc60b0fca4a54b60a9d79278cccbaa4966302699ba23e3300e83869239d
|
|
BLAKE2b-256 checksum How to use checksums |
689a0a2cc25148b1ad0c47a8706908b832d67a48b1f1ed06a901a326137e0199
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Security for shade-plugins-hubspot 0.1.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.