Pular para o conteúdo principal

Artigo atualizado: 27 de maio de 2022

API do agente virtual Sparkcentral

Os agentes virtuais Sparkcentral permitem que as empresas adicionem bots à plataforma como se fossem agentes reais. Eles podem responder a mensagens recebidas, resolver conversas, aplicar tópicos e definir atributos de contato. Em vez de limitar as plataformas de bot que podem ser integradas, é fornecida uma API genérica que você pode usar para integrar a qualquer plataforma.

Para integrar sua plataforma de bot favorita ao Sparkcentral, você precisará fornecer um endpoint HTTPS. O Sparkcentral chama esse endpoint toda vez que uma conversa é atribuída ao seu agente virtual e sempre que o contato envia uma nova mensagem. Se você estiver usando uma plataforma de bot síncrono, poderá responder imediatamente a essa solicitação com a resposta. Se você estiver usando uma plataforma de bot assíncrona, você também pode enviar uma solicitação POST para o Sparkcentral para enviar uma resposta a uma conversa.

Dois tipos de agentes virtuais

Incepção

Um agente virtual inicial pega automaticamente conversas privadas que começam nos canais aos quais tem acesso. Se um agente virtual de início precisar de um agente humano, ele colocará a conversa na fila Nova para que qualquer agente possa responder. O agente virtual de início também pode resolver uma conversa se nenhuma assistência humana for necessária.

Como um agente virtual de início pega conversas automaticamente no canal ao qual ele tem acesso, você não pode criar vários agentes virtuais de início que tenham acesso ao mesmo canal.

Delegação

Um agente virtual de delegação não coletará conversas automaticamente. Em vez disso, um agente humano pode dar uma conversa a um agente virtual de delegação a qualquer momento da conversa. O agente virtual de delegação assumirá neste momento. A regra de entrega determina o que deve acontecer se um agente virtual de delegação precisar de um agente humano. Se “Nova fila” estiver selecionada, a conversa será movida para a fila Nova a ser retirada por qualquer agente. Se “agente anterior” for selecionado, o agente virtual de delegação atribuirá a conversa de volta ao agente humano anterior.

Vários agentes virtuais de delegação podem ter acesso ao mesmo canal. Um agente humano deve selecionar especificamente o agente virtual para assumir a conversa.

Adicionar um agente virtual

Para adicionar um agente virtual:

  1. Vá para Configurações do administrador, expanda Agentes virtuais, selecione Agentes virtuais personalizados e, em seguida, selecione Adicionar agente virtual personalizado.
  2. Insira um nome para o agente virtual. Esse nome aparecerá no Sparkcentral como “{Name}VA”.
  3. Especifique se você deseja que seu agente virtual seja ativado como um agente Inception ou um agente de delegação.
  4. O URL do Webhook deve ser fornecido para enviar corretamente as informações da conversa ao seu agente virtual (consulte a seção Webhooks para obter mais informações).
  5. Preencha os campos restantes como quiser, incluindo todas as regras de entrega que você deseja adicionar.
  6. Selecione Salvar.
  7. Role para baixo até a seção Acesso ao canal e use as alternâncias para selecionar um canal ou canais onde esse agente virtual possa ser acessado.

Agente virtual de tempo limite

Você pode configurar dois tipos de regras de contato para agentes virtuais:

  • Timeout Virtual Agent - Determina quando ocorrerá uma entrega se o agente virtual parar de responder por qualquer motivo. O máximo é de 60 minutos.
  • Contato de tempo limite - Determina quando uma entrega ocorrerá se o contato (usuário) parar de responder. O máximo é de 60 minutos.

Tratamento de erros

Se a conexão do agente virtual acabar, ocorrer um erro ou se o contato esgotar, você poderá fazer o seguinte:

  • Marque a conversa como nova ou resolvida
  • Aplicar automaticamente um tópico
  • Se a conversa estiver marcada como Resolvida, envie automaticamente uma resposta padrão para o cliente

Editar ou excluir um agente virtual

Para editar um agente virtual, na página Agentes virtuais personalizados, selecione o ícone Editar. Para excluir um agente virtual, selecione o ícone Lixeira.

Exibir o segredo de um agente virtual

Na página do Agente Virtual Personalizado, selecione o ícone Editar ao lado do agente virtual. Você pode exibir ou copiar o segredo compartilhado gerado para esse agente virtual na página Editar Agente Virtual Personalizado. Consulte a seção Protegendo Webhooks para obter mais informações.

Webhooks

Quando uma conversa é atribuída ao agente virtual registrado na seção anterior, o Sparkcentral envia um evento por meio da URL que você configurou.

Três eventos importantes são enviados:

  • CONVERSATION_STARTED
  • CONVERSATION_DELEGATED
  • INBOUND_MESSAGE_RECEIVED

Campos comuns

Todos os eventos têm certos campos comuns:

  • type: Uma string que define que tipo de evento ocorreu (atualmente CONVERSATION_STARTED ou INBOUND_MESSAGE_RECEIVED). Novos eventos podem ser adicionados no futuro. Evite responder com um erro a valores desconhecidos; em vez disso, ignore-os. Dependendo desse tipo, a estrutura dos dados será diferente.
  • version: Um número que designa a versão do tipo de solicitação. Atualmente, a versão é sempre 1. As versões serão usadas no futuro para introduzir alterações não compatíveis com versões anteriores.
  • IDempotencyKey: Uma string que identifica exclusivamente cada evento. Quando ocorrer um tempo limite ao enviar o evento (ou recebermos uma resposta de erro), tentaremos o evento novamente. Essa chave pode ajudá-lo a garantir que uma solicitação seja processada apenas uma vez.
  • timestamp: O carimbo de data/hora quando enviamos a solicitação. Isso é usado para combater possíveis ataques de repetição.
  • data: Um objeto que contém dados estruturados para o tipo específico. Por exemplo, um evento do tipo INBOUND_MESSAGE_RECEIBED tem campos como ConversationId e message. Os campos podem ser adicionados no futuro.

CONVERSATION_STARTED

O evento CONVERSATION_STARTED é enviado quando uma conversa é atribuída ao seu agente virtual Inception. Você só receberá mensagens e só poderá responder a mensagens, desde que a conversa seja atribuída ao agente virtual Inception.

Como parte deste evento, você recebe informações extras sobre o perfil de contato tentando entrar em contato com você, o canal sobre o qual eles estão entrando em contato com você e os atributos de contato. Os atributos de contato incluem informações específicas médias, informações adicionadas manualmente antes e informações provenientes de pesquisas anteriores de CRM. Observe que o Agente Virtual Inception receberá o evento CONVERSATION_STARTED antes que qualquer pesquisa de CRM configurada seja realizada e, portanto, o evento não incluirá nenhuma nova informação do CRM.

Após o evento CONVERSATION_STARTED, você receberá um evento INBOUND_MESSAGE_RECEIVED para cada mensagem enviada pelo contato, a partir do início da conversa.

Copiar
{
"iDempotencyKey":" 933d877e-a13f-4958-93a4-d5d4941bf624",
"versão ": 1,
"tipo":" CONVERSATION_STARTED",
"carimbo de data/hora":" 2019-01-17T 16:46:51 .908736Z",
"dados ": {
"conversationId":" 0-01d90bc1b13-000-9a9ca0d8",
"médio":{ "id": "fb" },
"canal":{
"id": "0-019a0b43ad3-000-471aa28a",
"name": "Sparkcentral support channel"
},
"ContactProfile":{
"id": "0-01835f0fec3-000-0a6c390a",
"mediumContactProfileId": "975734236828364800",
"primaryIdentifier": "jan_spark",
"secondaryIdentifier": "Jan Spark",
"pictureUrl": "http://image.com/sticky/default_profile_images/default_profile_normal.png"
},
"ContactAttributes": [
{ "attribute": "company", "value": "Sparkcentral", "source": "AGENT" },
{
"attribute": "fb-profile-image",
"value": "https://image.com/sticky/default_profile_images/default_profile_normal.png",
"source": "MEDIUM"
},
{
"attribute": "fb-verified",
"value": "Not Verified",
"source": "MEDIUM"
},
{
"attribute": "fb-account-created",
"value": "March 19, 2018",
"source": "MEDIUM"
},
{
"attribute": "fb-handle-name",
"value": "jan_spark",
"source": "MEDIUM"
},
{ "attribute": "fb-name", "value": "Jan Spark", "source": "MEDIUM" },
{
"attribute": "spark-url",
"value": "http://www.sparkcentral.com",
"source": "AGENT"
}
]
}
}

CONVERSATION_DELEGATED

O evento CONVERSATION_DELEGATED é enviado quando uma conversa é atribuída ao seu agente virtual da Delegação. Como o evento CONVERSATION_STARTED, isso contém informações extras sobre o perfil de contato tentando entrar em contato com você, o canal sobre o qual eles estão entrando em contato com você e os atributos de contato.

Após o evento CONVERSATION_DELEGATED, você receberá um evento INBOUND_MESSAGE_RECEIVED para cada mensagem enviada pelo contato, a partir de quando a conversa for atribuída ao agente virtual. Ao contrário do evento CONVERSATION_STARTED, o evento CONVERSATION_DELEGATED geralmente não é seguido imediatamente por um INBOUND_MESSAGE_RECEIVED. Em vez disso, espera-se que o agente virtual faça a primeira pergunta ao contato. Depois de receber um evento CONVERSATION_DELEGATED, você terá 2 minutos para fazer esta primeira pergunta. Consulte os requisitos para obter mais detalhes.

Copiar
{
"timestamp":" 2019-03-28T 14:29:56 .727041Z",
"IDempotencyKey ":" 8fa424c3-a88b-4f02-bd38-4e292a27597b",
"versão": 1,
"tipo":" CONVERSATION_DELEGATED",
"dados": {
"conversationId":" 0-01f20ec5e10-000-860d4dde",
"médio ":{ "id": "fb" },
"canal":{
"id": "0-01e25845518-000-19087686",
"name": "JansDevFbChannel4"
},
"ContactProfile ":{
"id": "0-01f116a7f9c-000-b5d375aa",
"mediumContactProfileId": "cd067e88519aa063b15e9944",
"primaryIdentifier": "Anonymous",
"secondaryIdentifier": "Young Parrot",
"pictureUrl": null
},
"ContactAttributes": [
{
"attribute": "fb-page-title",
"value": "In-Web Messaging Demo",
"source": "MEDIUM"
},
{
"attribute": "fb-page-url",
"value": "https://messenger-demoapp-dev/#JansDevSmoochChannel4",
"source": "MEDIUM"
},
{
"attribute": "fb-browser-language",
"value": "en-US",
"source": "MEDIUM"
},
{
"attribute": "fb-domain",
"value": "messenger-demoapp-dev",
"source": "MEDIUM"
},
{
"attribute": "fb-sdk-version",
"value": "1.14.2",
"source": "MEDIUM"
}
]
}
}

INBOUND_MESSAGE_RECEIVED

Depois que a conversa for atribuída ao agente virtual e depois de receber um evento CONVERSATION_STARTED ou CONVERSATION_DELEGATED, você começará a receber eventos INBOUND_MESSAGE_RECEIVED. Esses eventos ocorrem toda vez que o contato envia uma mensagem. Observe que enviamos os tópicos de conversa com cada evento INBOUND_MESSAGE_RECEIVED.

Copiar

{
"idempotencyKey":" cc75552a-1a78-11e9-855e-6d1e71016abf",
"versão ": 1,
"tipo":" INBOUND_MESSAGE_RECEIVED",
"timestamp":" 2019-01-17T 16:56:16 .108626Z",
"dados ": {
"conversação ID":" 0-01d90bc1b13-000-9a9ca0d8",
"mensagem":{
"messageId": "cc75552a-1a78-11e9-855e-6d1e71016abf",
"text": "Hello",
"payload":"payload"
},
"Tópicos de conversa": [
"Tópico 1",
"Tópico 2"
],
"canal": {
"id": "0-019a0b43ad3-000-471aa28a",
"name": "Sparkcentral support channel"
},
"Perfil de contato":{
"id": "0-01835f0fec3-000-0a6c390a",
"mediumContactProfileId": "975734236828364800",
"primaryIdentifier": "jan_spark",
"secondaryIdentifier": "Jan Spark",
"pictureUrl": "http://image.com/sticky/default_profile_images/default_profile_normal.png"
},
"médio": {
"id": "facebook"
}
}
}

RESPOSTA

Sua resposta ao webhook deve ser 200 OK. No corpo, você pode retornar a resposta que deseja enviar para o contato:

Copiar
{
"sendMessage":{ "text": "Hi! How can I help you?", "attachment": "funny_cat.gif" },
"ApplyTopics": [" Reserva de Hotel"],
"Aplicar Tags": ["Happy"],
"Definir atributos de contato":{ "account_number": "19758293529351" },
"complete":" HANDOVER"
"Aplicar notas de conversação": [{"text": "A note"}]
}
  • sendMessage: (Opcional) A mensagem que você deseja enviar para o contato. Você pode enviar somente texto, apenas um anexo ou ambos ao mesmo tempo. Se você quiser enviar um anexo, você deve fazer o upload dele firs, por isso recomendamos usar o fluxo assíncrono.
  • ApplyTopics: (Opcional) A lista de tópicos que você deseja aplicar à conversa (a intenção ou ação que seu Agente Virtual correspondeu). Tópicos que não existem no Sparkcentral serão ignorados.
  • ApplyTags: A lista de tags que você deseja aplicar à mensagem do contato. As tags que não existem no Sparkcentral serão ignoradas. Só é possível usar ApplyTags em resposta a um INBOUND_MESSAGE_RECEIVED. Também é possível marcar uma mensagem específica especificando o MessageID. Nesse caso, você pode responder usando" ApplyTags": [{"messageId": "cc75552a-1a78-11e9-855e-6d1e71016abf", "tag": "Happy"}].
  • setContactAttributes: Os atributos que você deseja definir em um contato. O objeto é um mapa entre o alias e o valor da definição do atributo a ser definido.
  • completo. (Opcional) Isso pode ser HANDOVER se você quiser dar a conversa a outro agente ou RESOLVIDO se quiser resolver a conversa. Quando você passar o HANDOVER, a regra de entrega que você configurou nas configurações determina o que acontecerá a seguir. Se a regra de entrega for “Ninguém”, a conversa será colocada na nova fila sem um proprietário. Qualquer agente humano pode retomar a conversa. Se a regra tiver sido definida como “Agente anterior”, a conversa será atribuída de volta ao agente humano anterior. Se não houver nenhum agente anterior, a conversa será colocada na fila Nova sem um proprietário.
  • ApplyConversationNotes: (Opcional): Notas que devem ser adicionadas à conversa nas trilhas de auditoria.

Se você estiver se integrando a uma plataforma de bot assíncrona, você pode simplesmente retornar um corpo JSON vazio {} e enviar essa mensagem usando uma solicitação POST. Também recomendamos usar a API REST quando você quiser enviar um anexo. Você pode responder com {}, enviar um anexo usando uma solicitação PUT e, em seguida, enviar o anexo usando uma solicitação POST.

Protegendo webhooks

Ao configurar um agente virtual, você recebeu uma chave secreta que pode ser usada para verificar se uma solicitação de webhook de entrada realmente vem do Sparkcentral sem alterações. Nos cabeçalhos da solicitação de cada chamada de webhook está o X-Sparkcentral-Signature. Ele contém uma assinatura HMAC-SHA256 baseada no corpo da solicitação. Tanto a chave secreta que você recebeu quanto a assinatura são codificadas como strings hexadecimais. A maioria dos idiomas vem com bibliotecas prontas para usar para verificar essa assinatura. Aqui está um exemplo de código para verificá-lo em Node.js:

Copiar
const SparkCentralSecret ="... "; //não compartilhe! 
const expectedSignature = request.headers ["X-Sparkcentral-Signature"];
const ActualSignature = crypto
.createHMac ("sha256", buffer.from (SparkCentralSecret," hex"))
.update (request.body," utf-8")
.digest ("hex ");
if (Assinatura real! == Assinatura esperada){
throw new createError.Unauthorized("X-Sparkcentral-Signature wrong");
}
Nota: Certifique-se de calcular a assinatura fora do corpo como está, antes de desserializá-la do JSON. Durante o cálculo da assinatura, todo o espaço em branco é considerado significativo.
Como parte do corpo da solicitação, você encontrará um carimbo de data/hora. Este é o momento em que uma solicitação foi enviada. Para evitar ataques de repetição, recomendamos verificar se esse carimbo de data/hora não tem mais de 5 minutos:
Copiar
if (
moment (JSON.parse (request.body) .timestamp) .isBefore (
moment () .subtrair (5," minutos")
)
){
throw new createError.Unauthorized("Request too old");
}

Requisitos

Para proporcionar uma boa experiência ao cliente, alguns requisitos não funcionais são impostos ao webhook. Quando um webhook é enviado, você tem 10 segundos para responder com 200 OK. Se ocorrer um tempo limite, tentaremos novamente 3 vezes usando um recuo exponencial (até 2 segundos). Se as falhas persistirem durante as novas tentativas, a conversa atribuída será entregue a um agente humano colocando-a na fila Nova.

Quando o contato envia uma mensagem pelo Sparkcentral, por padrão, esperamos que o agente virtual responda a essa mensagem em 5 minutos (usando a resposta à chamada webhook ou à API REST). Você pode configurar o tempo limite na tela de configurações do seu agente virtual (Timeout Virtual Agent). Se o agente virtual não responder ao contato, por padrão, a conversa será colocada na fila Nova para um agente humano pegar. Isso também pode ser configurado em Configurações. Se preferir, você pode resolver automaticamente a conversa e enviar uma mensagem para o contato (por exemplo", tente novamente em pouco tempo"). O agente virtual também pode decidir retornar imediatamente o controle enviando RESOLVED ou HANDOVER no campo completo.

Da mesma forma, após um evento CONVERSATION_DELEGATED, seu agente virtual tem 5 minutos para fazer uma pergunta ao contato por padrão. Se o agente virtual não conseguir fazer isso, a conversa será devolvida ao proprietário anterior da conversa ou colocada na fila Nova, dependendo da regra de entrega.

Autorização

Se você quiser enviar as respostas de forma assíncrona ou manipular a conversa em seu código de preenchimento, você precisará chamar a API REST do Virtual Agent. A API do Virtual Agent usa o fluxo de Concessão de credenciais de clientes da especificação Oauth 2.0 para autenticação e autorização dos clientes.

Os clientes recebem client_id e client_secret para autenticar com o servidor de autorização do Sparkcentral e um access_token a ser usado para autorização de solicitação de API. O access_token deve ser usado em um cabeçalho de autorização, mas opcionalmente pode ser passado como um parâmetro de string de consulta (consulte detalhes de solicitação/resposta nas seções a seguir). Quando o access_token expira, a API retorna um 401 não autorizado. O cliente pode automatizar isso gerando um novo token de acesso e reproduzindo a solicitação com falha com o token de acesso novo, conforme documentado na seção a seguir. Este é o mesmo client_id e client_secret que você pode ter recebido para Proactive Messaging API ou Realtime Reporting API.

Os usuários do Sparkcentral com direitos de administrador podem gerar chaves de API em Configurações, expandindo as &APIs de integração e selecionando Chaves de API Rest.

Concessão de credencial

Recupere um access_token para fazer solicitações de API autorizadas. Quando o access_token expirar, use esse endpoint para gerar um novo token.

REQUERIMENTO

Copiar
$ curl -X POST https://public-api.sparkcentral.com/oauth2/token -H 'content-type: application/x-www-form-urlencoded' -d 'grant_type=client_credentials& client_id=your_client_id_here& client_secret=your_client_secret_here &scope=client-read'

OR

Copiar
$ curl -X POST https://public-api-eu.sparkcentral.com/oauth2/token -H 'content-type: application/x-www-form-urlencoded' -d 'grant_type=client_credentials& client_id=your_client_id_here& client_secret=your_client_secret_here &scope=client-read'
  
Parâmetros da API
Parâmetro Status Descrição
grant_type requeridos Deve ser definido como client_credentials
client_id requeridos Identificador de cliente fornecido pelo Sparkcentral
client_secret requeridos Sparkcentral forneceu segredo do cliente
objetivo requeridos Deve ser definido para leitura do cliente

RESPOSTA

{ “token_type”: “bearer”, “access_token”: “a1b2c3d4e5f6”, “expires_in”: 43200 }

Parâmetros e descrições de respostas
Parâmetro Descrição
token_type O tipo de token a ser usado no cabeçalho de autorização. Isso sempre será portador da concessão de credenciais do cliente.
access_token O token usado para autorizar solicitações. Isso deve ser adicionado às solicitações como cabeçalho de autorização: Autorização: Portador a1b2c3d4e5f6. A API também aceitará access_token como um parâmetro de string de consulta, no entanto, usar o cabeçalho de autorização é o método preferido.
expires_in O número de segundos até o token expirar (12 horas)

A maioria das plataformas tem compatibilidade pronta para uso com o Oauth2. Por exemplo, em Node.js, usando o axios-oauth-client, você pode fazer o seguinte:

Copiar
const axios = require ('axios'); 
const oauth = require ('axios-oauth-client');
const TokenProvider = require ('axios-token-interceptor');
const RESTClient = axios.create ({ baseURL: 'https://public-api.sparkcentral.com' }); //ou public-api-eu.sparkcentral.com em EU
const GetClientCredentials = oauth.client ( axios,{
url: 'https://public-api.sparkcentral.com/oauth2/token',
grant_type: 'client_credentials',
client_id: process.env.SPARKCENTRAL_CLIENT_ID,
client_secret: process.env.SPARKCENTRAL_CLIENT_SECRET,
scope: 'client-read'
});
RESTClient.interceptors.request.use (oauth.interceptor (TokenProvider, GetClientCredentials));

API de agente virtual

Conversas

POST /agente virtual/conversações/{conversationId}

Isso permite que você manipule a conversa da mesma forma que faria ao responder a uma solicitação webhook. Você pode enviar uma resposta, adicionar um tópico e/ou entregar a conversa. Cada propriedade no corpo é opcional. Se você quiser apenas enviar uma mensagem, você pode enviar {"sendMessage": {"text": "Oi! "}}. Se você quiser aplicar um tópico e concluir, mas não enviar uma mensagem, você pode, por exemplo, enviar {"applyTopics":["Spam"], "complete": "RESOLVED"}.

Observe que somente tópicos que correspondam exatamente a um tópico na plataforma serão aplicados à conversa (sem distinção entre maiúsculas e minúsculas). Tópicos não existentes são ignorados. No momento, nenhuma correspondência difusa ocorrerá e erros tipográficos resultarão em um tópico não existente.

O mesmo se aplica às tags. Somente tags que correspondam exatamente a uma tag na plataforma serão aplicadas a uma mensagem específica (sem distinção entre maiúsculas e minúsculas). Tags não existentes são ignoradas. Observe que é obrigatório especificar o MessageID ao usar a API REST. O MessageID faz parte de todos os eventos INBOUND_MESSAGE_RECEIVED.

Se você quiser enviar um anexo, você precisará primeiro fazer o upload do anexo em uma chamada separada (PUT /virtual-agent/conversations/{conversationId} /attachments/{filename}) e, em seguida, usar o nome do arquivo ao enviar o message ({"sendMessage": {"attachment":" "}}).

Se o contato já tiver um valor salvo para a definição de atributo com um alias específico, a atualização será ignorada. Se qualquer uma das definições de atributo for configurada como valores de Pesquisa de CRM, uma Pesquisa de CRM será executada depois que os atributos forem definidos. Para obter o melhor desempenho, recomendamos definir atributos de contato junto com a resposta para indicar que a conversa foi concluída. Observe que o agente virtual não receberá os novos atributos da resposta do CRM até que o próximo evento CONVERSATION_STARTED ou CONVERSATION_DELEGATED seja recebido para uma conversa com um contato.

Exemplo de URI

POST /Agente virtual/Conversas/ConversationID

Anexos

PUT /agente virtual/conversais/{conversationId} /anexos/{filename}

Isso permite que você carregue um anexo que você pode enviar em uma conversa. Você precisa fazer o upload do anexo primeiro e, em seguida, você pode enviar uma mensagem com texto e um anexo. Por exemplo, se você carregar um anexo para /virtual-agent/conversations//attachments/cat.jpg, poderá enviar esse anexo enviando {"sendMessage": {"text ":" Este é um gato! "," anexo":" cat.jpg"}} para /virtual-agent/conversations/. O nome do arquivo deve ser exclusivo em uma conversa e fica visível para o contato se ele baixar seu anexo.

O cabeçalho Content-Type deve conter o tipo MIME correto do anexo (como “image/jpeg”). O cabeçalho Content-Length deve conter o tamanho do anexo em bytes. Os anexos devem ter menos de 10 megabytes para evitar erros.

 

Exemplo de URI

PUT /Agente virtual/Conversas/ConversationID/Anexos/Nome do arquivo

 

Não consegue encontrar o que está procurando? Estamos aqui para ajudar