FUNIFIER TRIGGER - Quick Start - Português

Neste tutorial vamos aprender como utilizar as Triggers Funifier. Esta funcionalidade permite que desenvolvedores possam programar orientado a eventos de gamificação. As triggers permitem alterar os comportamentos das técnicas de engajamento em tempo de execução. Com as triggers você pode escrever seu próprio script que será executado por exemplo assim que o jogador completar um determinado desafio ou mudar de nível. Ao final deste tutorial você terá aprendido como criar suas próprias triggers para modificar o comportamento padrão de uma gamificação e assim poder implementar qualquer estratégia de engajamento que precisar.

INTRODUÇÃO AS TRIGGERS

As triggers da Funifier permitem que você execute ações personalizadas definidas antes ou depois de determinados eventos na gamificação, tais como a conquista de um desafio, a criação de um novo jogador, a mudança de nível ou quando o jogador realizar alguma ação. Assim como os sistemas de banco de dados suporta triggers, a Funifier fornece suporte a triggers para o gerenciamento de registros.

Normalmente, as triggers são usadas para realizar operações baseadas em condições específicas, para modificar registros ou modificar um comportamento padrão de uma técnica de engajamento. É possível usar triggers para fazer praticamente tudo como por exemplo fazer validações, consultas na internet, registros em bancos de dados, envio de email e muito mais. Use as triggers para executar tarefas que não podem ser feitas usando as ferramentas de apontar e clicar na interface de usuário da Funifier. Por exemplo, se você precisar de uma regra especial para pontuar o usuário quando ele completar um desafio, você pode usar as triggers.

As Triggers Funifier são compostas de três elementos fundamentais que são:

  1. Evento, que dispara a trigger;
  2. Entidade, onde o evento aconteceu;
  3. Script, que deverá ser executado quando o evento acontecer na entidade;

CRIANDO SUA PRIMEIRA TRIGGER

Para criar sua primeira trigger entre no Funifier Studio, acesse uma das suas gamificações, e clique no menu Integration > Trigger no canto inferior esquerdo da tela.

Nesta sessão você poderá ver a administração de triggers, aqui você poderá criar uma trigger. Clique no botão “New” para criar sua primeira trigger.

Agora vamos criar uma trigger muito simples, a única coisa que ela faz é imprimir no log de execução da trigger a palavra “Hello World!”. Preencha o campo Name com o valor Hello World, o campo Entity com o valor Action, o campo Action com o valor “After Win” e no campo Script adicione o código a seguir conforme imagem abaixo, e em seguida clique em Save:

void trigger(event, entity, player, database){

      println("Hello World!");

}

Após esta operação a sua trigger será listada na página de configuração de triggers. Existem três botões junto ao registro da sua trigger. O botão script apresenta o código do script da trigger. O botão Errors apresenta eventuais erros capturados durante a execução da trigger; E o botão Logs apresenta informações que você tenha registrado durante a execução da trigger através do método “println”, que estamos inclusive utilizando no script da nossa trigger. Clique no botão Logs para conferir se existe algum log atual.

Você verá uma tela conforme imagem abaixo, mostrando que não existe ainda nenhum log de execução pois esta trigger ainda não foi executada.

ACIONANDO SUA PRIMEIRA TRIGGER

As triggers são acionadas quando um evento de gamificação acontece em um objeto determinado. Na trigger criada anteriormente escolhemos a Entidade “Action” e o Evento “After Win”. Veremos posteriormente em detalhes as entidades e eventos disponíveis. Mas neste momento só precisamos saber que esta trigger será acionada logo após um jogador executar alguma ação dentro da gamificação. Então para disparar esta trigger vamos precisar de uma ação e um jogador cadastrados nesta gamificação.

Então neste caso vamos começar, criando uma ação dentro da plataforma, acesse o menu Actions no Funifier Studio e clique no botão New.

Vamos criar uma ação de vendas. No título da ação informe o nome “sell” e adicione 2 atributos clicando no botão amarelo da sessão atributos. O primeiro atributo se chama “product” e escolha no combo lado o valor string. O segundo atributo se chama “price” e escolha no combo ao lado o valor number. No final clique no botão salvar.

Após esta operação a sua ação será listada na página de configuração de ações. Agora vamos acessar a sessão de jogadores para fazer um jogador realizar esta ação que você acabou de criar e assim acionar a nossa trigger. Clique no menu Players na lateral esquerda da tela.

Selecione o jogador, marcando o checkbox que está do lado esquerdo do nome do jogador e em seguida clique no botão “Action” acima da lista de jogadores.


Agora vamos informar ao Funifier que o jogador executou a ação de venda. Selecione a ação “sell”, preencha os atributos “product” com valor “bicycle”, atributo “price” com valor 350, e clique em registrar ação do jogador.

Uma notificação de que a ação foi registrada com sucesso será apresentada. Isso significa que o evento de registrar ação ocorreu e nossa trigger deverá ter sido acionada.

Agora volte para a sessão de Integration > Triggers e clique no botão Logs da trigger que você criou anteriormente para vermos o log de execução da trigger.

Caso a configuração da trigger esteja correta você deverá ver o texto “Hello World!” aparecendo na tela. Parabéns você acabou de executar a sua primeira Trigger Funifier.

EVENTO DA TRIGGER

Os eventos determinam quando uma trigger deve ser executada. Os eventos são expressões compostas de um prefixo que informa o momento e um sufixo que informa a operação de banco de dados. Existem dois tipos de prefixos de eventos das triggers, que são:

  1. Before: Pré-acionadores são usados para atualizar ou validar valores de registro antes que eles sejam salvos no banco de dados.
  2. After: Pós-acionadores são usados para acessar os valores de campo que são definidos pelo sistema (tal como a Id de um registro) e para realizar alterações em outros registros. Os registros que disparam o pós-acionador são de somente leitura.

Além disso existem os sufixos para definir qual o tipo de operação de banco de dados, como cadastrar, atualizar ou excluir um registro do banco. E também existem sufixos especiais dedicados a eventos de conquistas e perdas de um jogador. Segue os sufixos existentes:

  1. Create: Acionado na operação de inclusão de registros.
  2. Update: Acionado na operação de alteração de registros.
  3. Delete: Acionado na operação de exclusão de registros.
  4. Win: Acionado quando o jogador conquista algo na gamificação.
  5. Loose: Acionado quando o jogador perde algo na gamificação.

ENTIDADE DA TRIGGER

A entidade diz a plataforma qual informação deve ser observada para disparar uma trigger. A maioria das entidades podem ser configuradas no Funifier Studio. Alguns exemplos de entidades são jogadores, equipes, pontos, ações, desafios, leaderboards e vários outros. Você poderá escolher a entidade que deseja no combo de seleção na configuração de trigger.

Quando combinamos o evento e entidade informamos para a plataforma o momento exato em que a trigger deverá ser executada. Segue alguns exemplos de como utilizar esta configuração:

Evento

Entidade

Exemplo

Before_Create

Player

Será executado logo antes de um novo jogador ser cadastrado no banco de dados.

Before_Update

Player

Será executado quando um jogador existente estiver sendo modificado. Logo antes do novo estado ser registrado no banco de dados.

After_Delete

Player

Será executado logo após um jogador e todos os seus registros vinculados ser removido da gamificação.

After_Create

Win-State

Será executado logo após o administrador da gamificação criar um novo desafio.

After_Win

Win-State

Será executado logo após o jogador completar um desafio dentro da gamificação.

Before_Create

Action

Será executado quando o administrador criar um novo tipo de ação no funifier studio logo antes desta ação ser armazenada no banco de dados.

Before_Win

Action

Será executado após o jogador executar uma ação dentro da gamificação, antes da action log ser registrada no banco de dados.

After_Create

Point

Será executado quando o administrador criar um novo tipo de ponto no funifier studio logo após este ponto ser armazenado no banco de dados.

After_Win

Point

Será executado logo após o jogador conquistar algum ponto dentro da gamificação. Quando um achievement do tipo point  for registrado no banco.

SCRIPT DA TRIGGER

O script a ser executado pela trigger deve declarar um método chamado “trigger” que recebe os parâmetros event, entity, player e database. O código dentro do método pode ser escrito utilizando a sintaxe groovy muito similar a linguagens como Java e Javascript.

Volte agora na administração de triggers para modificar a trigger que você criou anteriormente para apresentar o evento, a entidade e o jogador que está acionando uma trigger, utilize o script abaixo:

void trigger(event, entity, player, database){
         println("\n Event:" + event);
         println("\n Entity:" + entity);
         println("\n Player:" + player);
}

Agora volte para a sessão de jogadores, selecione novamente o jogador e clique no botão “Action” para registrarmos uma nova ação de vendas para este jogador.


Selecione a ação “sell”, preencha os atributos “product” com valor “bicycle”, atributo “price” com valor 350, e clique em registrar ação do jogador, para acionarmos a trigger novamente.

Volte para a sessão de Integration > Triggers e clique no botão Logs da trigger para vermos o resultado do log de execução. Agora você deverá ver os parâmetros event, entity e player.

PARÂMETRO ENTITY

O parâmetro “entity” que recebemos no script da trigger contém a informação que está sendo observada no momento em que a trigger foi acionada. A entidade pode ser uma realização de um jogador ou uma configuração feita pelo administrador. As realizações de um jogador são ações realizadas por ele dentro da gamificação ou a conquista de pontos e medalhas dentro da gamificação. As configurações são aquelas que o administrador da gamificação registra no Funifier Studio como por exemplo um jogador, uma equipe ou uma técnica de jogo.

As realizações de um jogador são observadas utilizando eventos com o sufixo “Win”. A trigger com a configuração, Entity = “Action” e Event = “After_Win” irá passar no parâmetro “entity” do script um objeto do tipo ActionLog. Uma trigger com a configuração, Entity = “Action” e Event = “After_Create” irá passar no parâmetro “entity” do script um objeto do tipo Action. Cada objeto tem uma estrutura própria, e você pode consultar as estruturas JSON de cada entidade na documentação da REST API da Funifier. Segue abaixo alguns exemplos de estruturas:

Evento

Entidade

Exemplo de objeto entity recebido no script

Before_Create

Player

{
 "_id" : "player@funifier.com",
 "name" : "Player Name",
 "email" : "player@funifier.com",
 "image" : {
   "small" : {"url" : "http://me.com/photo.png"},
   "medium" : {"url" : "http://me.com/photo.png"},
   "original" : {"url" : "http://me.com/photo.png"}
 },
 "friends" : [ "ricardo", "sandra" ],
 "teams" : [ "funifier", "octalysis" ],
 "extra" : {
   "gender" : "male",
   "mobile" : "+18895687914"
 }
}

After_Win

Action

{
 "_id" : "5a3a6cb0d5327c7c0ba69f27",
 "actionId" : "5a3a3c41347fd9910fb22eb1",
 "time" : 1513778352559,
 "userId" : "jerry.mouse@funifier.com",
 "attributes" : {
   "product" : "bicycle",
   "price" : 350
 }
}

After_Win

Point

{
 "_id" : "5a3a6cb0d5327c7c0ba69f27",
 "player":"player@funifier.com",
 "total":100,
 "type":0,
 "item":"544279769fbc0ab38ddd765d"
}

Volte agora na administração de triggers para modificar a trigger que você criou anteriormente para apresentar a estrutura da entidade no formato JSON, o script abaixo usa o método JsonUtil.toJson para apresentar o objeto no formato JSON e assim poder ver todos os atributos, utilize o script abaixo na sua trigger para ver o resultado:

void trigger(event, entity, player, database){
     println("\n Event:" + event);
     println("\n Entity:" + JsonUtil.toJson(entity));
}

Agora volte para a sessão de jogadores, selecione novamente o jogador e clique no botão “Action” para registrarmos uma nova ação de vendas para este jogador.


Selecione a ação “sell”, preencha os atributos “product” com valor “bicycle”, atributo “price” com valor 350, e clique em registrar ação do jogador, para acionarmos a trigger novamente.

Volte para a sessão de Integration > Triggers e clique no botão Logs da trigger para vermos o resultado do log de execução. Agora você deverá ver a estrutura de dados completa do objeto entity que foi utilizado no parâmetro do script desta trigger.

PARÂMETRO DATABASE

Operações de crud, de objetos customizados. Exemplo de acesso ao banco.

O último parâmetro recebido no script da trigger é o “database”. Este parâmetro dá acesso ao banco de dados da gamificação. Sempre que uma gamificação é criada na funifier, um banco de dados é criado especificamente para esta gamificação. É neste banco de dados que ficam armazenadas todas as configurações, conquistas etc. O objeto “database” permite a você realizar consultas, cadastrar, alterar e excluir objetos do banco de dados da gamificação. Este objeto dá acesso única e exclusivamente ao banco de dados da gamificação em que a trigger foi criada.

PESQUISA

Um dos métodos de pesquisa é o findById que permite localizar um registro em uma coleção através do identificador único daquele registro. Por exemplo, suponha que você precise descobrir o nome e o total de amigos do jogador no momento em que ele executar uma ação. Para descobrir estas informações nós podemos utilizar o método findById para recuperar o jogador e acessar estas informações, passando para isso o identificador do jogador que recebemos como parâmetro do script. Veja exemplo abaixo de como acessar tais informações.

void trigger(event, entity, player, database){

        Object p = database.findById(player, "player");

        println("\n Player: " + player);

        println("\n Name: " + p.name);

        println("\n Friends: " + p.friends.size());

}

E como resultado temos o seguinte log registrado após a trigger ser acionada:

CADASTRO

O método responsável pela inclusão de registros no banco de dados é o database.add. Ele permite que você possa salvar um objeto em uma coleção. Esta operação pode ser usada tanto para inserir como para atualizar um objeto existente. Um detalhe importante de utilização deste método é que você precisa declarar o valor do identificador único que deseja salvar. Este método não cria o identificador único para você. Para criar identificadores únicos você pode utilizar o método utilitário Guid.newShortGuid(). O script abaixo está registrando 10 pontos do tipo “coins” para o jogador que disparou a trigger. Outro detalhe importante é que estamos declarando o tipo do objeto “Achievement”.

void trigger(event, entity, player, database){

        Achievement a = new Achievement();

        a.player = player;

        a.total = 10;

        a.type = 0;

        a.time = new Date();

        a.item = "coins";

        a.id = Guid.newShortGuid();

        database.add(a, "achievement");

}

EXCLUSÃO

Para excluir um objeto você deverá informar o identificador único e a coleção utilizando o método database.delete. Veja abaixo um exemplo de como realizar esta operação:

void trigger(event, entity, player, database){

  database.delete("ID", "COLLECTION");  

}

MANIPULANDO OBJETOS CUSTOMIZADOS

No exemplo anterior cadastramos um objeto padrão da plataforma de gamificação, que foi o objeto “Achievement” que representa uma conquista dentro da gamificação. Porém eventualmente você precisará registrar informações que dizem respeito única e exclusivamente ao contexto de gamificação do seu negócio. Para montar objetos customizados você pode usar um Mapa para definir os campos do objeto. O campo de identificador único deve ser declarado como “_id”. Por exemplo imagine que você queira cadastrar os departamentos da sua empresa e utilizar esta informação de alguma forma na sua gamificação, veja abaixo um script que cria, consulta e exclui este objeto customizado:

void trigger(event, entity, player, database){
 Map o = new HashMap();
 o.put("_id", "1");
 o.put("name", "Tecnologia");
 database.add(p, "departamento");

 //find
 Object p = database.findById("1", "departamento");

 //delete
 database.delete("1", "departamento");  
}

PESQUISA AVANÇADA

O método find permite a consulta de registros em uma coleção usando os todas as funcionalidades do sistema de pesquisa e agregação disponíveis na API FUNIFIER. Se vocë ainda não está familiarizado veja os documentos "03 - Funifier Rest API - Query Language" e "04 - Funifier Rest API - Aggregation". O método find tem a seguinte sintaxe, database.find('collection', 'q', 'aggregation1', 'aggregation2', ...); No primeiro parâmetro recebe o nome da coleção onde a pesquisa será feita. O segundo parâmetro recebe o filtro de pesquisa igual ao parâmetro  "q" da API REST. E os parâmetros seguintes são as expressões de agregação que por ventura sejam necessárias na consulta. Como resultado da consulta o método retorna uma lista de objetos.

Por exemplo, suponha que você queira localizar todos os jogadores da que tenham o campo extra.company igual a disney e ordenar o resultado por ordem decrescente da data de criação. Neste caso podemos usar o seguinte código:

void trigger(event, entity, player, database) {

        List all = database.find('player', 'extra.company:"disney"', '{$sort : {created: -1}}');

        for(Object o : all) {

                println(JsonUtil.toJson(o));

        }

}

Você também pode realizar consultas avançadas como esta e retornar apenas um registro, neste caso você poderia incluir uma instrução na consulta para estipular o limite de registros que deseja retornar e em seguida capturar apenas o primeiro registro da lista de resultado. Veja o código a seguir de como poderia ser feito esta operação.

void trigger(event, entity, player, database){

Object o = database.find('player', 'developer:true', '{$sort:{created: -1}}', '{$limit: 1}').get(0);

println(JsonUtil.toJson(o));

}

ENTIDADES E COLEÇÕES

Como vimos nos exemplos anteriores existem várias entidades padrão da plataforma de gamificação, como por exemplo player e achievement. Para cada entidade existe uma coleção onde esta informação fica armazenada. Segue abaixo uma lista de algumas entidades e suas respectivas coleções para que você possa manipular estas informações via triggers.

Entidade

Colecao

Descricao

Player

player

Jogador com informações cadastrais básicas

PlayerStatus

player_status

Jogador com estatísticas atual na gamificação

Team

team

Equipe com nome e identificador da equipe

Action

action

Acao configurada pelo administrador no studio

ActionLog

action_log

Log de uma ação feita por um jogador

Challenge

challenge

Desafio cadastrado pelo administrador no studio

Achievement

achievement

Conquista alcançada por um jogador

Notification

notification

Mensagem pública ou privada para os jogadores

PointCategory

point_category

Tipo de ponto configurado pelo administrador

Level

level

Nivel configurado pelo administrador

Catalog

catalog

Nome e identificador de um catalogo de premios

CatalogItem

catalog_item

Item virtual ou fisico de um catalogo, ex. caneta

Lottery

lottery

Sorteio configurado pelo administrador no studio

LotteryTicket

lottery_ticket

Cupons para participar de um determinado sorteio

OBJETO UNIREST

Para fazer requisições http voce pode utilizar o objeto Unirest disponivel dentro do contexto da trigger. Este objeto permite realizar requisições utilizando os métodos GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS. Ele suporta envio de parâmetros via querystring, via form, upload de arquivos e corpo de requisições customizadas. Além disso você pode customizar os parâmetros a serem enviados no cabeçalho da requisição e muito mais. Segue abaixo um exemplo de código para realizar uma requisição com o método get, informando um token de autorização e imprimindo o resultado da requisição:

void trigger(event, entity, player, database){

  HttpResponse<String> get = Unirest.get("https://yourserver.com/endpoint?player=" + player)

  .header("Authorization", "Basic NTcwNTFmNjQwYzXXX==")

  .asString();

  println(post.getBody());

  println(post.getStatus());

}

Para realizar uma requisição com o método post, basta mudar a chamada para Unirest.post. Veja abaixo um exemplo de como enviar uma requisição post, enviando no cabeçalho o token de acesso e o tipo do conteúdo, e no corpo da requisição um objeto no formato json.

void trigger(event, entity, player, database){
 HttpResponse<String> post = Unirest.post("https://yourserver.com/endpoint")
 .header("Authorization", "Basic NTcwNTFmNjQwYzXXX==")
 .header("Content-Type", "application/json")
 .body("{\"player\" : \"+player+\"}")
 .asString();
 println(post.getBody());
 println(post.getStatus());
}

OBJETO CONTEXT

O objeto Context contém algumas informações muito específicas do momento em que o evento está ocorrendo. Por exemplo, ao conquistar um desafio o objeto context possui a informação de qual ação do jogador disparou o processo de avaliar a conquista deste desafio. Ao ganhar pontos o objeto context possui a informação de qual desafio deu origem aquela pontuação e assim por diante.

Imagine o seguinte cenário, você precisa criar um extrato de pontos para apresentar ao jogador, e para fazer isso você quer descobrir qual o desafio deu origem aos pontos que um jogador está ganhando e registrar esta informação juntamente com a conquista do ponto. Neste caso você poderia criar uma trigger para ser disparada no momento Event: BeforeWin, Entity: Point. O script a seguir acessa o objeto context para descobrir o id do desafio que originou a pontuação e adiciona esta informação na entidade de achievement do ponto o atributo origem no campo extra.

void trigger(event, entity, player, database){

        if(entity.type == 0 && context.extra.parentAchievement != null) {

                entity.extra = new HashMap<>();

                entity.extra.put("origem", context.extra.parentAchievement.item);

        }

}

Imagine que agora você precisa exibir todos os desafios que o jogador conquistou e qual foi a ação que disparou a avaliação daquela conquista. Neste caso você poderia criar uma trigger para ser disparada no momento Event: BeforeWin, Entity: Win-State.

void trigger(event, entity, player, database){

        if(entity.type == 0 && context.extra.parentActionLog != null) {

                entity.extra = new HashMap<>();

                entity.extra.put("action", context.extra.parentActionLog.action);

        }

}

OBJETO MANAGER

O objeto ManagerFactory atua na camada de negócios da plataforma de gamificação Funifier. Cada entidade possui um Manager que pode ser recuperado através da ManagerFactory, e o Manager de cada entidade é capaz de realizar operações relacionadas aquela entidade. Por exemplo, a entidade Lottery, que trata da técnica de engajamento de sorteios na plataforma, possui um Manager capaz de criar sorteios, adicionar tickets a um sorteio, executar um sorteio para saber que são os ganhadores e muito mais. Outra característica dos managers é que eles trabalham com o tipo  de dados específico da plataforma ou seja, ao recuperar e salvar um jogador usando o manager você deverá trabalhar com o tipo Player e não com um Object como é feito no parâmetro database. Segue abaixo um exemplo de como consultar e salvar um jogador utilizando o manager desta entidade.

void trigger(event, entity, player, database) {

        Player p = manager.getPlayerManager().findById(player);

        p.setName(p.getName().toUpperCase());

        manager.getPlayerManager().insert(p);

}

Segue abaixo uma relação de alguns dos managers e operações disponíveis:

Entidade

Manager

Operações

Player

getPlayerManager()

findById(id)

insert(player)

delete(id)

Achievement

getAchievementManager()

addAchievement(achievement)

deleteAchievement(id)

Action

getActionManager()

findActionById(id)

addAction(action)

deleteAction(id)

ActionLog

getActionManager()

track(actionLog)

Challenge

getChallengeManager()

findById(id)

add(challenge)

delete(id)

Lottery

getLotteryManager()

find(id)

insert(lottery)

delete(id)

execute(id)

LotteryTicket

getLotteryManager()

insertTicket(ticket)

deleteTicket(ticket)

PACOTE JAVA.LANG.*

Utilizando os objetos padrão da linguagem java. Math, Collection, Date etc.

CLASSES UTILITÁRIAS

Classes utilitárias da Funifier JsonUtil, DateUtil, Guid e etc.

MÉTODOS ANINHADOS

As triggers são classes com o método trigger, e você pode criar métodos adicionais no script para organizar melhor o processamento das informações. Segue abaixo como você poderia criar um novo método e chamar este método de dentro do método trigger.

void trigger(event, entity, player, database) {

        update(entity);

}

void update(entity) {

        //do something

}

EXECUÇÃO E DEBUG DE TRIGGERS

Você pode utilizar a REST API durante o processo de construção de uma trigger para debugar a trigger sem precisar por exemplo executar uma ação do jogador para disparar a trigger. Esta é uma forma de acelerar o processo de desenvolvimento. Acesse a documentacao da REST API em http://api.funifier.com e localize o recurso TRIGGER, e a operação Execute Trigger.

Veja que para executar uma trigger você precisa informar na URL o id da trigger que irá executar. Entre no Funifier Studio e abra uma das triggers que você construiu. Na url da página de edição da trigger você vai encontrar o id da sua trigger como último parâmetro.

Abra o Postman, escolha o método POST, cole a url de execução de trigger no postman e troque o id pelo código que está no Funifier Studio. Na aba body, inclua o objeto json com a estrutura esperada no parâmetro entity do script. No caso desta trigger temos a entidade Action e evento AfterWin, então o parâmetro entity do script espera um objeto do tipo ActionLog. Entre outros campos o objeto ActionLog contém os campos actionId e userId. Lembre-se que cada configuração de trigger irá exigir um tipo de objeto diferente no parâmetro entity. Ao final clique no botão Send para executar esta trigger e ver o resultado.

Como resultado da requisição você receberá algumas informações. O primeiro campo e’ o outputs, este é’ o resultado das chamadas ao método println. Você também recebe o campo millis que informa o tempo em milisegundos gasto na execução desta trigger. O último campo e’ o exceptions que apresenta qualquer tipo de erro na execução da trigger.

ERROS DE COMPILAÇÃO

Antes de serem armazenadas dentro da plataforma, as triggers passam por um processo de validação, para garantir que foram corretamente construídas. Caso a trigger tenha algum defeito aparente a plataforma irá retornar uma mensagem com a descrição do erro que deve ser corrigido. Veja abaixo um exemplo de trigger com defeito e sua respectiva mensagem:

RESTRIÇÕES NAS TRIGGERS

O tempo máximo de execução de uma trigger é 5 segundos.

BOAS PRÁTICAS

Construa apenas uma trigger por entidade/evento.

EXEMPLO: INSTALANDO TRIGGERS DO MARKETPLACE

Veja o seguinte exemplo, suponha que você queira implementar uma técnica de engajamento conhecida como “Aura Effect”. Esta técnica permite que o esforço ou ação de um jogador possa beneficiar outros jogadores dentro da sua rede de relacionamento. Podemos criar uma trigger que dê pontos para todos os amigos de um jogador que fizer algo extraordinário. A trigger poderia por exemplo dar 1 ponto para cada um dos amigos do jogador que por algum motivo ganhar 100 pontos ou mais como recompensa por realizar algo dentro da gamificação. Felizmente esta trigger já está pronta e pode ser instalada através do Marketplace da Funifier. Vamos aprender como instalar esta trigger. Acesse http://marketplace.funifier.com.

O Marketplace da Funifier é um local onde você pode escolher componentes pré-configurados para instalar na sua gamificação. Estes componentes estão dentro de pacotes publicados no Marketplace. Um pacote pode conter um ou mais componentes. Os componentes podem ser qualquer tipo de objeto criado usando a plataforma Funifier, como por exemplo uma trigger. Para instalar pacotes do marketplace na gamificação que criamos você deverá se logar com o mesmo usuario e senha utilizados para entrar no Funifier Studio. Clique em login, informe seu usuário e senha.

Selecione a sua gamificação clicando no botão “Select”. Por que você precisa selecionar a gamificação? Por que dentro de uma conta Funifier você pode possuir várias gamificações.

Agora procure o pacote “Aura Effect Trigger” e clique no botão “More” para ver os detalhes.

Nos detalhes do pacote você vai encontrar algumas informações muito importantes. Por fim clique no botão INSTALL NOW para instalar este componente na sua gamificação.

Antes de finalmente instalar o pacote na sua gamificação, a plataforma irá lhe apresentar o que você está instalando e em qual gamificação o pacote será instalado. Clique no botão “Confirm and Install” para concluir a instalação deste pacote.

Após a instalação você será direcionado para a página de pacotes instalados. Nela você poderá ver detalhes do pacote e até mesmo desinstalar o pacote que você instalou.

Agora vamos volte para o Funifier Studio, na sessão Integration > Triggers para ver a trigger que você acabou de instalar na sua gamificação.

Clique em editar para ver o código da trigger que você acabou de instalar. Veja que o código está recuperando o registro do jogador e verificando se o jogador está conquistando mais de 100 pontos, independente do tipo de ponto. Em seguida o script está percorrendo o id de todos os amigos deste jogador e cadastrando uma nova conquista para cada um deles, neste caso está creditando 1 ponto do mesmo tipo de ponto que o jogador corrente está recebendo, como recompensa por ser amigo deste jogador.

/* when a player earn 100+ points, all friends will also receive 1 extra point, entity=point_category, event=after_win */
void trigger(event, entity, player, database){
        Object p = database.findById(player, 'player');
        if(entity.type == 0 && entity.total >= 100) {
                for(String friend : p.friends) {
                        Achievement a = new Achievement();
                        a.player = friend;
                        a.total = 1;
                        a.type = 0;
                        a.time = new Date();
                        a.item = entity.item;
                        database.add(a, 'achievement');
                }
        }
}

EXEMPLO: REGISTRO DE CUPONS DE SORTEIO

Imagine que você deseja criar um desafio, e quando um jogador completar este desafio você deseja adicionar um cupom para este jogador participar de um sorteio. Mas existem vários sorteios cadastrados na gamificação. Então você quer incluir um cupom de participação no sorteio mais recentemente cadastrado e que ainda não tenha sido executado, ou seja que ainda está ativo no sistema. A quantidade de cupons que o jogador irá ganhar também pode variar por desafio. Então na configuração do desafio também vamos incluir um parâmetro para informar quantos cupons o jogador irá receber. A trigger deverá ler esta configuração e adicionar o número de cupons especificados para o jogador no sorteio mais recente e aberto.

Para fazer isso vamos entrar no Funifier Studio e criar um desafio, conforme imagem a seguir:

Agora abra a sessão avançada do desafio e no campo extra adicione o campo tickets e informe a quantidade de tickets para participar do sorteio que o jogador deverá ganhar com o desafio. A trigger irá ler estes campos para estipular o total de tickets. No final clique em Save.

Volte na sessão de integration > triggers e crie uma nova trigger conforme imagem abaixo:

Utilize o script a seguir na sua configuração da trigger. Este script irá localizar o desafio que está sendo executado e localizar o campo tickets no desafio. Em seguida o script irá verificar qual é a última lottery cadastrada que ainda irá ser executada. Na sequência o script cria os LotteryTickets para o jogador partcipar do sorteio:

void trigger(event, entity, player, database) {

Challenge c = manager.getChallengeManager().findById(entity.item);

Object tickets = c.extra.get("tickets");

if(tickets != null) {

        int total = Integer.parseInt(tickets);

        Object lottery = database.find('lottery', 'executedDate:null', '{$sort : {createdDate: -1}}', '{$limit: 1}').get(0);

        for (int i=0; i<total; i++) {

                LotteryTicket ticket = new LotteryTicket();

                ticket.lottery = lottery._id;

                ticket.player = player;

                manager.getLotteryManager().insertTicket(ticket);

                println("player:" + player + ", ticket:" + ticket.id);

        }

}

}

Depois disso você precisa criar a configuração dos seus sorteios Configuration > Lottery.

EXEMPLO: PONTUAÇÃO REGRESSIVA

Imagine o seguinte cenário, você deseja criar alguns desafios em que os jogadores irão ganhar pontos de forma decrescente, ou seja, o jogador que completar o desafio primeiro irá ganhar mais pontos do que os jogadores que completarem o mesmo desafio após ele. E precisamos para todo desafio que tiver este comportamento precisamos definir uma pontuação máxima e a pontuação mínima que os jogadores irão ganhar. Estes parâmetros deverão estar estabelecidos na configuração de cada desafio. A trigger deverá ler esta configuração e creditar os pontos para o jogador, decrementando pontos até atingir o menor valor possível de pontos.

Para fazer isso vamos entrar no Funifier Studio e criar um desafio. Este desafio deverá especificar o tipo de pontos que desejamos distribuir, mas vamos deixar o total de pontos com o valor 0 (zero) conforme imagem a seguir:

Agora abra a sessão avançada do desafio e no campo extra adicione dois campos. decreasing_points_max = 100 e decreasing_points_min = 50. A trigger irá ler estes campos para estipular o valor máximo e mínimo de pontuação. No final clique em Save.

Volte na sessão de integration > triggers e crie uma nova trigger conforme imagem abaixo:

Utilize o script a seguir na sua configuração da trigger. Este script irá localizar o desafio que está sendo executado e localizar os campos decreasing_points_max e decreasing_points_min configurados no desafio. Em seguida o script irá verificar qual foi a última pontuação creditada para um jogador para este desafio, este controle é feito criando um objeto customizado chamado decremental_control. Na sequência o script cria um objeto do tipo Achievement, com o total de pontos atual e adiciona no banco de dados. Em seguida o script diminui um ponto do total que deverá ser creditado para o próximo jogador.

/* before_win, win-state, decremental points */
void trigger(event, entity, player, database) {
        //find the challenge and see if it has the max and min fields
        Object c = database.findById(entity.item, 'challenge');
        String max = (String) c.extra.get("decreasing_points_max");
        String min = (String) c.extra.get("decreasing_points_min");

        if(max != null && min != null) {
                for(Object p : c.points) {

                        //search the last total points used or create a new
                        String id = entity.item + '_' + p.category;
                        Object o = database.findById(id, 'decremental_control');
                        if(o == null) {
                                o = new HashMap();
                                o.put("_id", id);
                                o.put("total", Integer.parseInt(max));
                        }

                        //add points to the player if total greater than zero
                        if(o.total > 0) {
                                Achievement a = new Achievement();
                                a.id = Guid.newShortGuid();
                                a.player = player;
                                a.total = o.total;
                                a.type = 0;
                                a.time = new Date();
                                a.item = p.category;
                                database.add(a, 'achievement');

                                //return the total
                                context.extra.achievements.add(a);

                                //decrement points for the next player only if total > min
                                if(o.total > Integer.parseInt(min)) {
                                        o.total = o.total - 1;
                                        database.add(o, 'decremental_control');
                                }
                        }
                }
        }
}

Agora abra o Postman e vamos executar a ação de vendas para ver quantos pontos o jogador irá receber ao completar este desafio. Registre a ação passando parâmetro async=false via querystring conforme imagem abaixo. Como resultado você verá achievement de 100 pontos.

Ao executar a mesma operação novamente, você verá que a pontuação deverá ser diferente, agora o achievement deve ser igual a 99. E isso irá continuar até o valor mínimo de 50 pontos.

EXEMPLO: ENVIO DE EMAILS

Dentro do script da trigger você pode enviar emails utilizando a biblioteca “Simple Java Mail”, para maiores informações acesse http://www.simplejavamail.org. A criação de emails é feita a partir do objeto Email. E o envio de emails é feito a partir do objeto MailerBuilder. A criação e envio de emails é muito intuitiva, veja abaixo um exemplo de como enviar um email no Funifier através de uma trigger que é acionada quando uma ação for executada:

void trigger(event, entity, player, database){
   Email email = EmailBuilder.startingBlank()
   .from("Ricardo", "ricardo@funifier.com")
   .to("Igor", "igor@funifier.com")
   .to("Sandra", "sandra@funifier.com")
   .withSubject("Funifier Demo in San Francisco!")
   .withPlainText("We have a Funifier Techtalk in San Francisco with Google next week!!!")
   .buildEmail();

   MailerBuilder
   .withSMTPServer("server", 25, "username", "password")
   .buildMailer()
   .sendMail(email);
}

Você pode enviar seu email para várias pessoas, informando todos os emails dos destinatários separando cada email com virgula ou ponto e vírgula. Veja a baixo o exemplo.

// or add comma / semicolon separated addresses (without names)
String list = "ricardo@funifier.com,sandra@funifier.com;beatriz@funifier.com";
currentEmailBuilder.bcc(list);

Enviando email com SSL e TLS, para ativar o ssl ou tls você pode usar o enum TransportStrategy apropriado. Veja abaixo um exemplo:

MailerBuilder
 .withSMTPServer("smtp.gmail.com", 25, "your user", "your password")
 .withTransportStrategy(TransportStrategy.SMTP_TLS)
 // or
 .withSMTPServer("smtp.gmail.com", 587, "your user", "your password")
 .withTransportStrategy(TransportStrategy.SMTP_TLS)
 // or
 .withSMTPServer("smtp.gmail.com", 465, "your user", "your password")
 .withTransportStrategy(TransportStrategy.SMTPS);

EXEMPLO: REGISTRANDO ACTION LOG AO CRIAR UM JOGADOR

Imagine que você deseja criar um desafio que deve ser completado assim que um jogador se registra na sua gamificação. Neste caso precisamos registrar um action log assim que o jogador for criado na gamificação. Para fazer isso vamos criar uma action chamada “register” e uma trigger que adiciona um log da ação register para o jogador que estiver sendo criado. Utilizando a API REST crie uma ação conforme exemplo abaixo:

POST https://service2.funifier.com/v3/action

{
 "_id": "register",
 "action" : "register"
}

Em seguida crie uma nova trigger com a seguinte configuração:

Em seguida adicione o seguinte script para a sua trigger:

void trigger(event, entity, player, database){
   ActionLog log = new ActionLog();
   log.id = Guid.newShortGuid();
   log.actionId = "register";
   log.userId = player;
   log.time = new Date();
   manager.getActionManager().track(log);
}

ATRIBUTOS : Caso você queira incluir atributos adicionais em um action log, você pode declarar o campo attributes e em seguida incluir os novos campos, veja o exemplo abaixo:

void trigger(event, entity, player, database){
  ActionLog log = new ActionLog();
  log.id = Guid.newShortGuid();
  log.actionId = "buy";
  log.userId = player;
  log.time = new Date();

  //add new attributes
  log.attributes = new HashMap<String, Object>();
  log.attributes.put("product", "book");
  log.attributes.put("price", 10.5);
  manager.getActionManager().track(log);
}

EXEMPLO: ENVIANDO UMA NOTIFICAÇÃO POR UM CANAL CUSTOMIZADO

Imagine que você deseja enviar as notificações geradas na gamification para um canal diferente. Por exemplo, você pode apresentar as notificações instantâneas via push notification, ou em um canal do facebook, ou por email, ou até mesmo em um outro sistema. Nestes casos você poderá utilizar suas triggers para chamar uma API e enviar assim sua notificação para onde você desejar. Suponha que você configurou a seguinte notificação no seu challenge.

Você poderia criar uma trigger com o código abaixo para enviar a notificação para seu endpoint, neste caso a trigger deve ser configurada para executar na entidade win-state, no evento after_win. Ou seja após completar um desafio na gamification.

/** win-state, after_win, send push notification */

void trigger(event, entity, player, database) {

if(entity.type == Achievement.TYPE_CHALLENGE) {

Challenge c = database.manager.getChallengeManager().findById(entity.item);

List<NotificationDefinition> list = NotificationDefinition.getNotifications(c.getNotifications(), 0, 99, "push");

for(NotificationDefinition n : list) {

if(n != null) {

        Player p = database.manager.getPlayerManager().findById(player);

        Map<String, Object> values = new HashMap<>();

        values.put("item", c);

        values.put("player", p);

        String message = MustacheUtils.parse(n.getContent(), values);

        Map<String, Object> body = new HashMap<>();

        body.put("to", p.email);

        body.put("message", message);

        HttpResponse<String> response = Unirest.post("https://your.system.com/send")

        .header("Content-Type", "application/json")

        .body(JsonUtil.toJsonRemoveNullFields(body))

        .asString();

        println("\n" + response.getBody());

}

}

}

}

Você também pode enviar notificações em outros eventos, como após o jogador comprar um item na gamification. Neste caso você poderia configurar a seguinte notificação em um dos catalogos de incentivos. Nesta notificação temos o evento “On Purchase”, “Custom”, “Congratulations {{player.name}} purchased {{item.name}}” e “push”.

Você poderia criar uma trigger com o código abaixo para enviar a notificação para seu endpoint, neste caso a trigger deve ser configurada para executar na entidade catalog_item, no evento after_win. Ou seja após comprar um item na gamification.

/** catalog_item, after_win, send push notification */
void trigger(event, entity, player, database) {
if(entity.type == Achievement.TYPE_CATALOG_ITEM) {
CatalogItem c = database.manager.getCatalogManager().findItemById(entity.item);
List<NotificationDefinition> list = NotificationDefinition.getNotifications(c.getNotifications(), 0, 99, "push");
for(NotificationDefinition n : list) {
if(n != null) {
        Player p = database.manager.getPlayerManager().findById(player);
        
        Map<String, Object> values = new HashMap<>();
        values.put("item", c);
        values.put("player", p);
        String message = MustacheUtils.parse(n.getContent(), values);

        Map<String, Object> body = new HashMap<>();
        body.put("to", p.email);
        body.put("message", message);
        
        HttpResponse<String> response = Unirest.post("https://your.system.com/send")
                .header("Content-Type", "application/json")
                .body(JsonUtil.toJsonRemoveNullFields(body))
                .asString();

        println("\n" + response.getBody());
}
}
}
}

EXEMPLO: CUSTOMIZANDO MENSAGEM DE ALTERAÇÃO DE SENHA

Existe um endpoint específico para alterar a senha de um jogador caso ele tenha esquecido a senha e não tenha mais como se logar no sistema. O endpoint é o seguinte:

GET https://service2.funifier.com/v3/player/password/change?player=PLAYER_ID

Ao acionar o endpoint o Funifier envia um email para o jogador com um código que o jogador deverá utilizar em outro endpoint para efetuar a alteração da senha. O endpoint seguinte é:

PUT https://service2.funifier.com/v3/player/password?player=PLAYER_ID

&new_password=123&code=CODE_SENT_TO_PLAYER_EMAIL

O email enviado para o jogador possui um título e um conteúdo default, mas você pode alterar estes conteúdos através das triggers Funifier. Abaixo estão os valores padrão:

subject

{{gamification.name}} | Change Your Password

message

Dear {{player.name}}
To change your password use the code below:
{{code}}

Para criar uma trigger que execute antes do envio do email de alteração de senha, você deverá criar uma trigger através da funifier rest api com a entidade “password_change_message”.

entity

password_change_message

event

before_create

script

/** password_change_message, before_create */

void trigger(event, entity, player, database){

    entity.message = "Olá {{player.name}},<br/><br/>Para alterar sua senha use o código abaixo:<br/><br/>{{code}}<br/><br/>";

    entity.subject = "Tamo Junto 9Bi - Alteração de Senha";

}

EXEMPLO: REGISTRANDO UM BADGE PARA JOGADOR NA PRIMEIRA POSIÇÃO DE UM LEADERBOARD

Vamos supor que na sua significação você tenha definido uma estratégia em que aqueles jogadores que alcançarem a qualquer momento a primeira posição de um ranking, então estes deverão receber uma medalha para registrar este grande feito. Em uma gamificação vários jogadores podem ocupar a primeira posição de um ranking ao longo do tempo. Hoje o jogador A pode estar na primeira posição do ranking, amanhã o jogador B pode estar na primeira posição e depois de amanhã jogador C. Para dar uma medalha para este jogadores quando cada um deles alcançar a primeira posição de um determinado ranking você pode utilizar uma trigger a ser executada logo após a renderização e apuração dos líderes do ranking. Esta trigger pode identificar se existe um jogador na primeira posição, e então cadastrar a medalha para este jogador. Mas este registro só será feito caso o jogador ainda não tenha conquistado a tal medalha junto ao ranking em questão. Veja abaixo como poderia ser construído a trigger para resolver este problema. Nesta situação vamos criar uma trigger vinculada à entidade leaderboard e ao evento after_render.

O código abaixo é o script utilizado no corpo da trigger. A primeira instrução tenta localizar um jogador na primeira posição do leaderboard em questão, utilizando para isso o parâmetro context.extra.expire.id que contém a referência para o cache dos líderes previamente calculados. Caso exista um jogador na primeira posição então ele passa para a próxima instrução, tentando identificar se este jogador já conquistou anteriormente a medalha de primeiro lugar referente a este leaderboard. Esta verificação é particularmente importante para evitar que esta medalha seja creditada de hora em hora, pois esta é a periodicidade de renovação do cache do leaderboard. E apenas no caso do jogador ainda não ter conquistado a medalha para este leaderboard é que a conquista é adicionado no banco de dados.

entity

leaderboard

event

after_render

script

void trigger(event, entity, player, database){

    //finds the player in the first position of the leaderboard

    List first = database.find('leader', 'position:1, extra.cache:"'+context.extra.expire.id+'"', '{$limit: 1}');

    if(first != null && first.size() > 0) {

        Object leader = first.get(0);

        //identifies whether the player has previously won this badge for this leaderboard

        List have = database.find('achievement', 'player:"'+leader.player+'", extra.leaderboard:"'+leader.boardId+'"', '{$limit: 1}');

        if(have == null || have.size() == 0) {

            Achievement a = new Achievement();

            a.player = leader.player;

            a.total = 1;

            a.type = 1;

            a.time = new Date();

            a.item = "badge_first_position";

            a.id = Guid.newShortGuid();

            a.extra = new HashMap<>();

            a.extra.put("leaderboard", entity.id);

            database.add(a, "achievement");

        }

    }

}

EXEMPLO: ENVIANDO UMA NOVA NOTIFICAÇÃO

Caso você precise criar notificações customizadas diretamente dentro da trigger, você poderá usar o NotificationBuilder para configurar sua notificação e enviar para os jogadores. Veja abaixo como criar uma notificação para ser publicada na newsfeed da gamification.

void trigger(event, entity, player, database){

    Notification n = NotificationBuilder.startingBlank()

    .setScope(NotificationDefinition.SCOPE_NEWSFEED)

    .setContent("My custom newsfeed message!")

    .buildNotification();

   

    manager.getNotificationManager().send(n);

}

E caso você queira enviar uma mensagem privada para o jogador que executou a trigger você pode configurar a notification da seguinte forma.

void trigger(event, entity, player, database){

    Notification n = NotificationBuilder.startingBlank()

    .setScope(NotificationDefinition.SCOPE_PRIVATE)

    .setContent("My private notification!")

        .setPlayerId(player)

    .buildNotification();

   

    manager.getNotificationManager().send(n);

}