tlw_irus

Crates.iotlw_irus
lib.rstlw_irus
version0.1.6
created_at2025-11-27 19:00:55.445+00
updated_at2025-12-19 01:59:47.559807+00
descriptionCliente Rust para a API Suri - plataforma de atendimento e e-commerce
homepage
repositoryhttps://github.com/nextlw/tlw_irus
max_upload_size
id1954271
size789,058
William (willy3087)

documentation

README

tlw_irus

Cliente Rust para a API Suri - plataforma de atendimento e e-commerce via WhatsApp.

Instalacao

Adicione ao seu Cargo.toml:

[dependencies]
tlw_irus = "0.1.2"
tokio = { version = "1", features = ["full"] }

Uso Basico

use suri::{SuriClient, SuriConfig};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Configuracao do cliente
    // OBRIGATÓRIO: Configure as variáveis de ambiente antes:
    // export SURI_BASE_URL="https://api.suri.com.br"
    // export SURI_API_TOKEN="seu_token_aqui"
    let config = SuriConfig::from_env()
        .expect("Variáveis de ambiente não configuradas");
    let client = SuriClient::new(config);

    // Listar produtos
    let products = client.shop()
        .list_products(Default::default())
        .await?;

    for product in products.data {
        println!("{}: R$ {:.2}", product.name, product.price.unwrap_or(0.0));
    }

    Ok(())
}

APIs Disponiveis

Shop (E-commerce)

use suri::{Product, BatchProductsRequest, ListProductsRequest};

// Criar produto
let product = Product::new("Meu Produto")
    .with_price(99.90)
    .with_stock(100)
    .with_description("Descricao do produto");

client.shop().create_product(&product.into()).await?;

// Listar produtos com paginacao
let response = client.shop()
    .list_products(ListProductsRequest {
        per_page: Some(100),
        ..Default::default()
    })
    .await?;

// Batch de produtos (criar/atualizar em massa)
let produtos = vec![
    Product::new("Produto 1").with_price(10.0).with_external_id("SKU001"),
    Product::new("Produto 2").with_price(20.0).with_external_id("SKU002"),
];

let batch = client.shop()
    .batch_products(BatchProductsRequest::upsert(produtos))
    .await?;

// Aguardar conclusao do batch
let status = client.shop()
    .wait_batch_completion(&batch.id, 2000, 300)
    .await?;

println!("Batch concluido: {:?}", status.status);

// Atualizar precos
use suri::types::UpdatePricesRequest;
client.shop().update_prices("product_id", &UpdatePricesRequest {
    price: Some(149.90),
    sale_price: Some(129.90),
    variants: None,
}).await?;

// Atualizar estoque
use suri::types::UpdateStocksRequest;
use suri::Stock;
client.shop().update_stocks("product_id", &UpdateStocksRequest {
    stock: Some(Stock {
        quantity: 50,
        available: 50,
        reserved: 0,
        track_inventory: true,
        allow_backorder: false,
    }),
    variants: None,
}).await?;

Categorias

use suri::{Category, CreateCategoryRequest};

// Listar categorias
let categories = client.shop().list_categories().await?;

// Criar categoria
let category = client.shop().create_category(&CreateCategoryRequest {
    name: "Eletronicos".to_string(),
    description: Some("Produtos eletronicos".to_string()),
    parent_id: None,
    image_url: None,
    order: Some(1),
    store: None,
}).await?;

Colecoes

use suri::{Collection, CreateCollectionRequest, CollectionType};

// Listar colecoes
let collections = client.shop().list_collections().await?;

// Criar colecao manual
let collection = Collection::new("Promocoes")
    .with_product("product_id_1")
    .with_product("product_id_2");

client.shop().create_collection(&collection.into()).await?;

Pedidos

use suri::{ListOrdersRequest, OrderStatus, UpdateOrderLogisticRequest};

// Listar pedidos
let orders = client.shop()
    .list_orders(ListOrdersRequest {
        status: Some(OrderStatus::Paid),
        per_page: Some(50),
        ..Default::default()
    })
    .await?;

// Obter pedido especifico
let order = client.shop().get_order("order_id").await?;

// Atualizar logistica
client.shop().update_order_logistic(&UpdateOrderLogisticRequest {
    order_id: "order_id".to_string(),
    tracking_code: Some("BR123456789".to_string()),
    carrier: Some("Correios".to_string()),
    status: Some(OrderStatus::Shipped),
    ..Default::default()
}).await?;

// Marcar como pago
use suri::MarkOrderPaidRequest;
client.shop().mark_order_paid(&MarkOrderPaidRequest {
    order_id: "order_id".to_string(),
    transaction_id: Some("txn_123".to_string()),
    ..Default::default()
}).await?;

// Cancelar pedido
use suri::CancelOrderRequest;
client.shop().cancel_order(&CancelOrderRequest {
    order_id: "order_id".to_string(),
    reason: Some("Cliente solicitou cancelamento".to_string()),
    refund: Some(true),
}).await?;

Contatos

use suri::{ImportContactRequest, AddVariableRequest, RequestAttendanceRequest};

// Importar contato
let contact = client.contacts()
    .import(ImportContactRequest {
        phone: "5511999999999".to_string(),
        name: Some("Joao Silva".to_string()),
        email: Some("joao@email.com".to_string()),
        channel: "channel_id".to_string(),
        variables: None,
        tags: Some(vec!["cliente-vip".to_string()]),
    })
    .await?;

// Obter contato
let contact = client.contacts().get("contact_id").await?;

// Adicionar variavel
client.contacts()
    .add_variable("contact_id", AddVariableRequest {
        name: "ultima_compra".to_string(),
        value: serde_json::json!("2024-01-15"),
    })
    .await?;

// Solicitar atendimento
client.contacts()
    .request_attendance("contact_id", RequestAttendanceRequest {
        department: Some("vendas_id".to_string()),
        attendant: None,
        message: Some("Cliente precisa de ajuda".to_string()),
    })
    .await?;

Mensagens

use suri::SendMessageRequest;

// Enviar texto simples
client.messages()
    .send_text("contact_id", "Ola! Como posso ajudar?")
    .await?;

// Enviar imagem com caption
client.messages()
    .send(SendMessageRequest::image("contact_id", "https://example.com/img.jpg")
        .with_caption("Confira nossa promocao!"))
    .await?;

// Responder mensagem
client.messages()
    .send(SendMessageRequest::text("contact_id", "Obrigado pelo contato!")
        .with_reply_to("message_id"))
    .await?;

Templates

// Listar templates
let templates = client.templates().list().await?;

// Obter template especifico
let template = client.templates().get("template_id").await?;

Campanhas

use suri::{CreateCampaignRequest, CampaignAudience};

// Listar campanhas
let campaigns = client.campaigns().list().await?;

// Criar campanha
let campaign = client.campaigns()
    .create(CreateCampaignRequest {
        name: "Campanha de Natal".to_string(),
        description: Some("Promocoes de fim de ano".to_string()),
        channel: "channel_id".to_string(),
        template: "template_id".to_string(),
        template_params: Some(vec!["{{1}}".to_string()]),
        audience: CampaignAudience {
            tags: Some(vec!["clientes-vip".to_string()]),
            ..Default::default()
        },
        schedule: None,
        action: None,
    })
    .await?;

// Iniciar campanha
client.campaigns().start("campaign_id").await?;

// Pausar campanha
client.campaigns().pause("campaign_id").await?;

// Cancelar campanha
client.campaigns().cancel("campaign_id").await?;

Departamentos e Atendentes

// Listar departamentos
let departments = client.departments().list().await?;

// Listar atendentes
let attendants = client.attendants().list().await?;

Canais

// Listar canais
let channels = client.channels().list().await?;

// Obter canal especifico
let channel = client.channels().get("channel_id").await?;

Flows (Automacoes)

// Listar flows
let flows = client.flows().list().await?;

// Obter flow especifico
let flow = client.flows().get("flow_id").await?;

Atendimentos

use suri::{ListAttendancesRequest, AttendanceStatusType};

// Listar atendimentos ativos
let attendances = client.attendances()
    .list(ListAttendancesRequest {
        status: Some(AttendanceStatusType::Active),
        per_page: Some(50),
        ..Default::default()
    })
    .await?;

Webhook

use suri::{SetWebhookRequest, WebhookEvent};

// Configurar webhook
client.shop().set_webhook(&SetWebhookRequest {
    url: "https://meusite.com/webhook".to_string(),
    events: Some(vec![
        WebhookEvent::OrderCreated,
        WebhookEvent::OrderPaid,
        WebhookEvent::OrderShipped,
    ]),
    active: Some(true),
    secret: Some("meu_secret".to_string()),
    store: None,
}).await?;

Tratamento de Erros

use suri::error::SuriError;

match client.shop().get_product("invalid_id").await {
    Ok(product) => println!("Produto: {}", product.name),
    Err(SuriError::NotFoundError { resource }) => {
        println!("Produto nao encontrado: {}", resource);
    }
    Err(SuriError::RateLimitError { retry_after_secs }) => {
        println!("Rate limit, aguarde {} segundos", retry_after_secs);
    }
    Err(SuriError::ValidationError { message, details }) => {
        println!("Erro de validacao: {}", message);
        if let Some(d) = details {
            for err in d.field_errors {
                println!("  - {}: {}", err.field, err.message);
            }
        }
    }
    Err(e) => println!("Erro: {}", e),
}

Configuracao Avancada

use std::time::Duration;

// OBRIGATÓRIO: Configure as variáveis de ambiente antes:
// export SURI_BASE_URL="https://api.suri.com.br"
// export SURI_API_TOKEN="seu_token_aqui"
let config = SuriConfig::from_env()
    .expect("Variáveis de ambiente não configuradas")
    .with_timeout(Duration::from_secs(60))  // Timeout de 60 segundos
    .with_max_retries(5)                     // 5 tentativas em caso de erro
    .with_rate_limit(20)                     // 20 requisicoes por segundo
    .with_user_agent("MeuApp/1.0");          // User-Agent personalizado

let client = SuriClient::new(config);

Estrutura do Crate

tlw_irus/
├── Cargo.toml
├── README.md
└── src/
    ├── lib.rs          # Re-exports publicos
    ├── client.rs       # Cliente HTTP principal
    ├── error.rs        # Tipos de erro (SuriError)
    ├── config.rs       # Configuracao do cliente
    ├── types/          # Tipos de dados
    │   ├── mod.rs
    │   ├── user.rs
    │   ├── channel.rs
    │   ├── department.rs
    │   ├── attendant.rs
    │   ├── message.rs
    │   ├── template.rs
    │   ├── campaign.rs
    │   ├── flow.rs
    │   ├── attendance.rs
    │   └── shop/
    │       ├── mod.rs
    │       ├── product.rs
    │       ├── category.rs
    │       ├── collection.rs
    │       ├── order.rs
    │       ├── batch.rs
    │       └── store.rs
    └── api/            # Implementacoes de endpoints
        ├── mod.rs
        ├── shop.rs
        ├── contacts.rs
        ├── messages.rs
        ├── templates.rs
        ├── campaigns.rs
        ├── departments.rs
        ├── attendants.rs
        ├── channels.rs
        ├── flows.rs
        └── attendances.rs

Licenca

MIT

Commit count: 0

cargo fmt