Biblioteca Python para criar bots para o Google Chat
Project description
Google Chat Bot Library (gchatbot)
Uma biblioteca Python moderna para simplificar a criação de bots para o Google Chat, utilizando FastAPI para alta performance e suporte nativo a operações assíncronas.
Visão Geral
Esta biblioteca fornece uma classe base robusta (GChatBot) que gerencia as complexidades da API do Google Chat, permitindo que você se concentre na lógica do seu bot.
- Estrutura Moderna com FastAPI: Aproveita a velocidade e o suporte
asyncnativo do FastAPI. - Processamento Híbrido Robusto: Tenta responder em segundos para tarefas curtas. Para tarefas longas, ele muda para um modo assíncrono seguro, que não duplica o trabalho, garantindo consistência e uma ótima experiência do usuário.
- Arquitetura Modular: Componentes como
EventParser,AsyncProcessoreResponseFactorysão desacoplados, permitindo customizações avançadas. - Extração de Eventos Simplificada: Converte automaticamente os diversos formatos de payload do Google Chat em uma estrutura de dados (
ExtractedEventData) limpa e previsível.
Como Funciona: O Modelo Híbrido Robusto
A biblioteca implementa um padrão de processamento híbrido que é eficiente e, mais importante, seguro contra condições de corrida e duplicação de trabalho.
- Requisição Recebida: O
GChatBotrecebe um evento do Google Chat. - Tentativa Síncrona: Ele inicia o processamento da sua lógica (
_process_slash_commandou_process_message) e aguarda por um curto período de tempo (sync_timeout). - Caminho Feliz (Resposta Rápida): Se a sua lógica terminar antes do timeout, a resposta é enviada diretamente na requisição original.
- Caminho Assíncrono (Resposta Lenta): Se o timeout for atingido:
a. O bot responde imediatamente
200 OKao Google Chat, liberando a conexão. b. Uma tarefa "monitora" é iniciada em background. Essa tarefa não reexecuta sua lógica. c. A tarefa monitora aguarda a conclusão da tarefa original, que continua rodando. d. Assim que a tarefa original termina, a monitora pega o resultado e o envia como uma nova mensagem no chat (começando com "Processando..." e depois atualizando com a resposta final).
Este modelo garante que sua lógica de negócio nunca seja executada mais de uma vez por evento, prevenindo bugs de consistência de dados e consumo excessivo de recursos.
Diagrama de Fluxo (GChatBot com FastAPI):
graph TD
A[Webhook Recebido] --> B("GChatBot.handleRequest");
B --> C{Parsing do Evento};
C --> D[Criação da Tarefa de Processamento];
D --> E{Aguardar Tarefa com Timeout};
E -- Concluído a Tempo --> F[Formatar Resposta Síncrona];
F --> G[Resposta HTTP 200 OK com JSON];
E -- Timeout Atingido --> H[Resposta HTTP 200 OK Vazio];
H --> I[Iniciar Tarefa Monitora Async];
subgraph "Processamento em Background"
D -- Tarefa Original Continua --> Z[Lógica do Bot];
I -- Monitora --> Z;
Z -- Resultado Pronto --> J[Pegar Resultado];
J --> K[API: Postar/Atualizar Mensagem no Chat]
end
Instalação
A biblioteca é projetada para funcionar com FastAPI.
# Instale a biblioteca com as dependências do FastAPI
pip install "gchatbot[fastapi]"
# Dependências instaladas: fastapi, uvicorn, google-auth, google-api-python-client, google-apps-chat, protobuf
Uso Recomendado: Exemplo com FastAPI
# main.py
import os
import time
import asyncio
from fastapi import FastAPI, Request, Response
from gchatbot import GChatBot
# Certifique-se de ter um arquivo 'service.json' ou defina a variável de ambiente.
SERVICE_ACCOUNT_FILE = os.environ.get("SERVICE_ACCOUNT_FILE", "service.json")
class MeuBot(GChatBot):
"""
Um bot de exemplo que demonstra a lógica de processamento híbrida e segura.
"""
def __init__(self):
super().__init__(
botName="Assistente Moderno",
serviceAccountFile=SERVICE_ACCOUNT_FILE,
syncTimeout=4.0 # Responde em até 4s ou muda para modo assíncrono.
)
def _process_slash_command(self, command: str, arguments: str, extracted_data, event_data) -> str:
"""Processa comandos de barra."""
user = extracted_data.get('userDisplayName', 'Usuário')
if command == "lento":
# Esta tarefa vai exceder o timeout e ser tratada de forma assíncrona.
time.sleep(6)
return f"⏱️ Tarefa lenta concluída para {user} após 6 segundos!"
# Este comando é rápido e responderá de forma síncrona.
return f"✅ Comando '/{command}' executado rapidamente para {user}."
def _process_message(self, text: str, extracted_data, event_data) -> str:
"""Processa mensagens diretas ou menções."""
if "demorado" in text.lower():
time.sleep(7)
return "Você pediu uma tarefa demorada, e ela foi concluída em 7 segundos."
return f"Recebi sua mensagem: '{text}'."
# --- Configuração do FastAPI ---
app = FastAPI(title="Google Chat Bot")
bot = MeuBot()
@app.post("/")
async def handle_event(request: Request):
"""Ponto de entrada para todos os eventos do Google Chat."""
return await bot.handleRequest(request)
@app.get("/")
def home():
"""Endpoint para verificação de saúde."""
return {"status": "ativo", "bot_name": bot.botName}
# Para executar localmente: uvicorn main:app --reload
Suporte Legado (Flask)
Para garantir a retrocompatibilidade, as classes baseadas em Flask (GChatBotFlask e GChatBotOld) ainda estão disponíveis, mas não são mais recomendadas para novos projetos. A versão GChatBotFlask já inclui a correção de concorrência da versão 0.2.4.
Clique para ver o exemplo com Flask
# app_flask.py
import os
import time
from flask import Flask, request
from gchatbot import GChatBotFlask # Importe a versão para Flask
class MeuBotFlask(GChatBotFlask):
def __init__(self):
super().__init__(
bot_name="Assistente Flask",
service_account_file=os.environ.get("SERVICE_ACCOUNT_FILE", "service.json"),
sync_timeout=3.0
)
def _process_slash_command(self, command: str, arguments: str, extracted_data: dict, event_data: dict) -> str:
if command == 'lento':
time.sleep(5)
return "Tarefa lenta concluída no Flask!"
return "Comando rápido executado no Flask."
def _process_message(self, text: str, extracted_data: dict, event_data: dict) -> str:
return f"Mensagem recebida no Flask: '{text}'"
# Configuração da aplicação Flask
app = Flask(__name__)
bot_flask = MeuBotFlask()
@app.route('/', methods=['POST'])
def webhook():
"""Endpoint que recebe eventos do Google Chat"""
return bot_flask.handle_request(request)
@app.route('/', methods=['GET'])
def home():
"""Página inicial para verificar se o serviço está rodando"""
return "Bot Flask está ativo!"
if __name__ == '__main__':
port = int(os.environ.get('PORT', 8080))
app.run(host='0.0.0.0', port=port, debug=True)
Arquitetura e Detalhes Técnicos
A biblioteca foi refatorada para uma arquitetura modular, com cada componente tendo uma responsabilidade clara.
main.py: Contém a classe principalGChatBote a lógica de orquestração.parser.py: Responsável por analisar os payloads dos eventos.processor.py: Gerencia o fluxo de resposta assíncrona.response.py: Fábrica para criar as respostas em formato de card.types.py: Define todas as estruturas de dados e tipos para clareza e robustez.
Estrutura de Dados do Evento (ExtractedEventData)
O EventParser unifica os diferentes payloads do Google Chat em um dicionário ExtractedEventData previsível:
rawText,processedText,command,arguments,userEmail,userDisplayName,spaceName,isDirectMessageEvent,messageName,isFallbackEvent.
Configuração do Google Chat
Para configurar seu bot no Google Chat:
- Acesse o Google Cloud Console.
- Crie/Configure um projeto.
- Habilite a API do Google Chat.
- Vá para a configuração da API do Chat:
- Nome do App, Avatar, Descrição: Preencha os detalhes.
- Funcionalidade: Habilite "Receber mensagens 1:1" e "Participar de espaços".
- Configurações de Conexão:
- Selecione "App URL".
- Insira a URL pública do seu endpoint (ex: de um serviço de nuvem ou
ngrokpara testes).
Changelog
0.2.4 - 2024-05-17 - Refatoração para FastAPI e Correção Definitiva de Concorrência
✨ Novo (New)
- Implementação com FastAPI: Introduzida uma nova classe
GChatBotbaseada em FastAPI como a implementação principal e recomendada. Ela oferece suporte nativo aasynciopara maior performance e um código mais limpo. - Arquitetura Modular: A biblioteca foi reestruturada em módulos com responsabilidades claras (
parser,processor,response,types), tornando-a mais extensível e fácil de manter. - Exportações Controladas: O
__init__.pyfoi atualizado para expor claramente a nova classeGChatBote os componentes modulares, mantendo as classes legadas (GChatBotFlask,GChatBotOld) para retrocompatibilidade.
🛠️ Correção (Fixed)
- Correção Definitiva de Duplicação de Trabalho:
- Problema: As implementações anteriores, embora corrigissem o bloqueio de requisições, introduziram um bug onde a lógica de negócio era executada duas vezes em caso de timeout (uma na tarefa original e outra na thread de resposta assíncrona).
- Solução: Implementado um padrão de "monitoramento". Agora, em caso de timeout, uma tarefa em background aguarda a conclusão da tarefa original em vez de reexecutá-la. Apenas o resultado da tarefa original é usado para responder ao usuário. Esta correção foi aplicada tanto à nova versão FastAPI quanto à versão legada
GChatBotFlask. - Resultado: O manuseio de timeouts agora é totalmente robusto, seguro e eficiente, eliminando o risco de duplicação de trabalho e garantindo a consistência dos dados.
0.2.3 - 2025-04-24 - Correções de Concorrência, Timeout e Tipo de Resposta
🛠️ Correção (Fixed)
-
Manuseio de Timeout e Concorrência:
- Problema: O uso de
with ThreadPoolExecutor()causava um bloqueio no handler HTTP, levando o Google Chat a reenviar o evento e causar respostas duplicadas. - Solução: Substituído por gerenciamento manual do
ThreadPoolExecutorpara liberar o handler HTTP imediatamente. - Resultado: Resposta HTTP 200 OK imediata em caso de timeout, sem bloqueios. (Nota: Esta solução foi um passo intermediário e foi substituída pela correção definitiva na versão 0.2.4).
- Problema: O uso de
-
Prevenção de
TypeErrorna Resposta:- Solução: Adicionada conversão automática para
str()ao resultado dos métodos de processamento. - Resultado: Garante que a resposta seja sempre uma string, aumentando a robustez.
- Solução: Adicionada conversão automática para
0.2.2 - Versão base
| Componente | Descrição |
|---|---|
| GChatBot | Classe base com lógica híbrida síncrona/assíncrona, parsing de payloads e criação de cards. |
| handle_request | Gerencia timeout síncrono e fallback para processamento assíncrono via thread. |
| _run_async_processing | Envia card "Processando…" e atualiza com o resultado final. |
| MeuBotHibrido | Exemplo de comandos (/ajuda, /rapido, /lento, /skills) e respostas simuladas. |
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gchatbot-0.2.4.tar.gz.
File metadata
- Download URL: gchatbot-0.2.4.tar.gz
- Upload date:
- Size: 33.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8aacd68c3cd9f5d8256e44be20b7a853138e0e77d064ddb9912f8cdc77552eb4
|
|
| MD5 |
a561005d3c0a0b01687917a90c8de19d
|
|
| BLAKE2b-256 |
74b821d60b7a3bf86f68d225c579a2abd8aa209184c511ccff79774bd0b471bf
|
File details
Details for the file gchatbot-0.2.4-py3-none-any.whl.
File metadata
- Download URL: gchatbot-0.2.4-py3-none-any.whl
- Upload date:
- Size: 31.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c5b8d1a46af354c5f538762ad6cb28b850b4c80289a11997f1ec986c10d1d6a
|
|
| MD5 |
3a14c09037a553299ab04d9fe1262c10
|
|
| BLAKE2b-256 |
31ba7b8165445a2a8c90f3dab3dc03249d9b134bfc1deb2ef70f43e814649845
|