WadRobotFramework : les robots Wave faciles
Date de publication : 18/06/2010 , Date de mise à jour : 18/06/2010
Présentation des robots de Google Wave et notamment d'une librairie alternative permettant de générer extrêmement rapidement un robot pour Google Wave.
I. Introduction
II. Des robots pour Google Wave ?
III. Google Wave ?
IV. Pré-requis
V. Robots - la méthode Google
V-A. Exemple de code standard
VI. WadRobotFramework
VI-A. Principe
VI-B. Historique
VI-C. API spécifique
VI-D. Générateur
VII. Utilisation du générateur
VII-A. Configuration du générateur
VII-A-1. Configuration générale
VII-A-2. Configuration pour un robot
VII-B. Exécuter le générateur
VIII. Les types de robots
VIII-A. Robots simples (RS)
VIII-A-1. Modifieurs-BlipModifierRobot
VIII-A-2. Ajouteur-BlipAppenderRobot
VIII-B. Robots avancés (RA)
VIII-B-1. Définition d'un RA
VIII-B-2. Définition d'un Worker
VIII-B-2-a. Worker sans papier (WSP)
VIII-B-3. Relation RA-Worker
VIII-B-4. Différence avec les robots simples
VIII-B-5. Exemple de RA
VIII-B-6. Utilisation des RA
VIII-B-7. Les différents types de RA
IX. Utilisation : pas à pas
X. La suite
XI. Conseils
XII. Liens
XIII. Remerciements
I. Introduction
Cet article va vous apprendre à utiliser le WadRobotFramework (WRF) pour créer des robots destinés à Google Wave avec un minimum d'efforts.
Il n'a pas pour vocation d'expliquer l'utilisation de Google Wave.
WRF vous permettra d'écrire un robot simple en moins de cinq minutes.
II. Des robots pour Google Wave ?
Google Wave est un système de collaboration permettant une communication instantanée entre les participants.
Ces participants pouvant être humains ou non.
Dans ce dernier cas, l'on nomme robots des programmes exécutés côté serveur, qui peuvent réagir à différents évènements d'une conversation.
Google fournit une API pour écrire des robots en Java (et en Python).
Un robot est un sous-ensemble d'une application Web, répondant à une URL établie.
Le mois de mars 2010 a vu arriver la v2 de l'API Java. Wave étant toujours un outil récent, son API n'est pas figée et susceptible de changements d'importance. Le WadRobotFramework est compatible avec cette nouvelle API.
Les deux versions de l'API Robots de Google cohabiteront jusqu'au 30 juin 2010. Après cette date, seule la v2 sera utilisable en ligne.
III. Google Wave ?
Pour décrire Wave à l'emporte-pièce, disons que c'est un grand forum mondial qui possède des fonctionnalités proches de la messagerie instantanée et de la messagerie classique (e-mail). De ce fait, ce mélange novateur possède son propre vocabulaire.
La Wave, c'est le forum, chaque fil (thread) est nommé wavelet, et se compose de blips. Chaque wavelet possède un ou plusieurs participants, ce sont soit des humains soit des robots.
Incroyablement novateur non ? A première vue, non, mais notons pour ultérieurement la possibilité d'ajouter des gadgets dans une conversation, ce qui ouvre un large panorama de possibilités.
IV. Pré-requis
Les pré requis pour pouvoir utiliser le WRF sont les mêmes que ceux pour l'API de Google.
- Avoir accès à Google Wave (Depuis la conférence Google IO, GW est ouvert à tous sur inscription)
- Avoir un compte développeur sur App Engine Java
- Pouvoir y créer une application
- Disposer d'Eclipse et du plugin Google
- Télécharger l'API Google
Lors de Google I/O 2010, outre l'ouverture à tous et l'intégration à l'offre Google Apps Entreprise, il a été annoncé que désormais, les robots pour GW pourraient être hébergés en dehors de Google App Engine (GAE). Dans cet article, ce ne sera pas le cas.
V. Robots - la méthode Google
V-A. Exemple de code standard
Ci-dessous le code d'un robot minimal possédant deux fonctions:
- dire qu'il est vivant (I'm alive) lorsqu'il est ajouté à une conversation.
- saluer tous les participants (Hi, everybody!)lorsqu'un participant est ajouté
| java |
package parroty;
import com.google.wave.api.*;
import com.google.wave.api.event.*;
public class ParrotyServlet extends AbstractRobot {
@Override
protected String getRobotName() {
return "Parroty";
}
@Override
protected String getRobotAvatarUrl() {
return "http://code.google.com/apis/wave/extensions/robots/images/robot_avatar.png";
}
@Override
protected String getRobotProfilePageUrl() {
return "http://code.google.com/apis/wave/extensions/robots/java-tutorial.html";
}
@Override
public void onWaveletSelfAdded(WaveletSelfAddedEvent event) {
Blip blip = event.getWavelet().reply("\nHi everybody!");
}
@Override
public void onWaveletParticipantsChanged(WaveletParticipantsChangedEvent event) {
for (String newParticipant: event.getParticipantsAdded()) {
Blip blip = event.getWavelet().reply("\nHi : " + newParticipant);
}
}
}
|
Rien de très compliqué en apparence. En partie parce que cela s'est grandement simplifié par rapport à la v1 de l'API.
Ce code n'est pas des plus excitant pour vos neurones, mais... il y a encore moins excitant.
Pour que ce code soit exécuté lorsque vous ajoutez un robot à une conversation, il faudra au préalable :
- avoir un environnement de programmation prêt
- récupérer le Jar de l'API des robots et ses dépendances (Json)
- déclarer la servlet avec son path spécifiques à respecter (web.xml)
- écrire le fichier de déploiement (appengine-web.xml)
- écrire le code "métier"
- configurer le projet sous Eclipse (classpath)
Sachez qu'avec la v1, il y avait plusieurs étapes supplémentaires.
Bien entendu, du copier-coller à partir des tutoriels fait l'affaire techniquement, mais cela apporte une faible satisfaction.
De plus, c'est à répéter pour chaque nouveau robot.
Heureusement, le WadRobotFramework est là !
Voici un exemple de code WRF
| java |
import org.wadael.waverobotfrmwrk.simple.BlipModifierRobot;
@author
@SuppressWarnings("serial")
public class RTFMRobotServlet extends BlipModifierRobot {
@Override
protected String modifyBlipText(String actualText) {
if(actualText.indexOf("?") == -1) return null;
else {
return actualText.replaceAll("?", "? (RTFM!!") ;
}
}
}
|
VI. WadRobotFramework
VI-A. Principe
Le WRF est destiné à des programmeurs, il se présente sous la forme d'un projet pour Eclipse.
Ce projet contient les deux composantes du WRF :
Chaque composant est lié à une étape du projet et rend plus rapide son déroulement.
Le générateur rend plus rapide la création du robot et l'API rend plus rapide l'écriture.
VI-B. Historique
Ce projet a suivi un développement incrémental depuis décembre 2009
Au début, fût l'API, elle permit de moins coder, puis vint le projet exemple qui permit
de ne plus avoir à recréer tous les fichiers de configuration, puis l'API fût complétée par les robots avancés
et enfin, arriva le générateur.
VI-C. API spécifique
L'API du WRF est une surcouche de l'API fournie par Google, elle définit un ensemble de classes notamment
celles correspondant aux différents types de robots proposés par le WRF.
Elle s'utilise par simple héritage comme nous le verrons ultérieurement.
VI-D. Générateur
Le générateur est constitué d'un script Ant secondaire et de son fichier de configuration.
Il s'utilise à partir du script Ant principal (build.xml), où l'on choisit la cible (target) Ant à exécuter,
correspondante au type de robot voulu.
Quelques secondes plus tard, vous disposerez d'un squelette de robot où seule la logique métier restera à implémenter.
VII. Utilisation du générateur
 | Pour utiliser le générateur, il est préférable de d'abord le configurer. |
VII-A. Configuration du générateur
La configuration du générateur se fait en deux étapes. La première, que j'appelle "configuration générale" doit être réalisée une seule fois par station.
Quant à la "configuration pour un robot", elle est à faire pour chaque nouveau robot.
La durée cumulée de ces deux étapes est inférieure à deux minutes.
VII-A-1. Configuration générale
J'ai fait le choix qu'à chaque génération de robot, la librairie est compilée et son archive recréée. Cela m'a permis d'être certain que les robots successivement créés dans le cadre du développement de WRF l'étaient bien avec la dernière version.
La dépendance vers l'API de Google implique que cette dernière doit être dans le CLASSPATH utilisé par Ant lors de la compilation.
Il vous faut donc renseigner le fichier build.properties situé à la racine du projet pour que la clef plugin.lib.dir ait pour valeur le chemin du répertoire du plugin Eclipse où se trouvent les JAR de Google App Engine (exemple de JAR: appengine-local-runtime-shared.jar).
Exemple de chemin : c://tools//IDEs//eclipse35//plugins//com.google.appengine.eclipse.sdkbundle_1.2.6.v200910131704//appengine-java-sdk-1.2.6//lib//shared
Vient ensuite une configuration pour chaque robot que vous souhaitez créer.
VII-A-2. Configuration pour un robot
La personnalisation de la création d'un robot se fait également par l'utilisation d'un fichier de propriétés Java standard. Celui-ci a pour chemin generator/generator.properties, à partir de la racine du projet.
La configuration indique :
- le package à utiliser
- le nom du robot
- son numéro de version
- le nom de l'application de déploiement
- le domaine de l'application de déploiement
Des explications (en anglais) sont intégrées dans le fichier lui-même, mais comme le fichier proposé est déjà valorisé, il vous suffit de modifier les valeurs existantes par des valeurs 'correctes' correspondant à ce que vous souhaitez.
 | Après l'exécution, la configuration pour un robot est ensuite sauvegardée à la racine du répertoire dédié au robot généré. |
VII-B. Exécuter le générateur
Dans le fichier build.xml à la racine du projet WRF, vous trouverez trois " target " Ant qui sont :
- generate_SimpleAppenderRobot
- generate_SimpleModifierRobot
- generate_AdvancedRobot
Exécutez celle qui correspond le mieux au robot que vous souhaitez créer.
Les différents types de robots sont expliqués ci-après.
VIII. Les types de robots
WRF définit plusieurs types de robots.
A ce jour, il existe trois types de robots dont deux types simples et un type avancé.
VIII-A. Robots simples (RS)
Les robots simples réagissent à chaque blip ajouté à une conversation.
Ils sont limités à du texte simple, sans mise en style.
VIII-A-1. Modifieurs-BlipModifierRobot
Un robot "modifieur" n'aura comme possibilités que
- modifier le blip
- ne pas modifier le blip
Dans le code source de votre robot, héritant de BlipModifierRobot, il vous faudra implémenter la méthode abstraite :
| java |
protected abstract String modifyBlipText(String actualText) ;
|
Si votre implémentation renvoie une chaîne non nulle, alors le blip sera modifié, avec pour contenu la chaine renvoyée par votre implémentation et votre robot sera ajouté comme auteur supplémentaire du blip.
Si votre robot renvoie null alors le blip restera inchangé sur les deux points.
VIII-A-2. Ajouteur-BlipAppenderRobot
Un robot "ajouteur" n'aura comme possibilités que
- ajouter un blip après le blip reçu
- ne pas ajouter de nouveau blip à la conversation
Dans le code source de votre robot, héritant de BlipAppenderRobot, il vous faudra implémenter la méthode abstraite :
| java |
protected abstract String getTextToAppend(String textOfTheBlipToReactFrom);
|
Si votre implémentation renvoie une chaîne non nulle, alors un nouveau blip sera créé, avec votre robot pour auteur.
Si votre robot renvoie null, alors la conversation restera inchangée (ni nouveau blip, ni le robot en tant que participant à la conversation).
VIII-B. Robots avancés (RA)
VIII-B-1. Définition d'un RA
Un RA est à voir comme une chaîne de production tayloriste basée sur la division du travail,
car sa nature est d'être composé de plusieurs Workers chainés, qui réagissent chacun à une commande (ou non)
mais peuvent aussi interrompre la chaine du traitement.
Un RA possède un identifiant (méthode getRobotIdentifier à surcharger) dont l'utilité est de permettre l'utilisation de plusieurs RA au sein d'une même conversation.
VIII-B-2. Définition d'un Worker
Un worker correspond à une tâche, une unité de travail. On les programmera à priori, de façon à ce qu'ils soient sans état.
Dans l'implémentation, cela correspond à l'interface RobotWorker
Voici le code source de cette interface
| java |
public interface RobotWorker {
public String getInstruction();
@return
public String getDescription();
@param
@param
@param
@param
@return
public boolean doWork(RobotMessageBundle bundle, Blip blip, Event event, String parameters);
}
....
|
On y lit qu'une implémentation de worker doit définir les méthodes
- getInstruction
- getDescription et,
- doWork
Les noms sont assez explicites.
Il faut savoir que getInstruction et getDescription sont utilisées dans le cas où l'utilisateur demande de l'aide en créant un blip débutant par /help.
Quant à doWork, c'est dans cette méthode que vous définirez la logique du worker. En paramètres, vous disposez de tous les objets mis à disposition par l'API Google.
VIII-B-2-a. Worker sans papier (WSP)
Un WSP est un worker dont l'instruction est délibérément null c'est à dire que getInstruction() renvoie null.
Dans ce cas, le WSP sera exécuté pour chaque blip de la conversation à laquelle participe le RA et le WSP n'apparaitra pas dans les instructions déclarées par le RA en réaction à la demande d'aide de l'utilisateur.
VIII-B-3. Relation RA-Worker
Un RA peut posséder plusieurs workers, chacun pouvant être utilisé au sein de plusieurs RA.
D'où l'attention à porter à ce qu'il soit sans état par défaut.
 | Les RA montrent leurs RobotWorkerlorsqu'un blip commence par /help |
VIII-B-4. Différence avec les robots simples
Les RA diffèrent des RS sur deux points essentiels.
Le premier point est l'accès aux mêmes objets que l'API proposée par Google. Les RS les masquent pour une raison de simplicité
Le deuxième est la différence d'utilisation. Les RS ont des possibilités bien plus réduites que les RA.
VIII-B-5. Exemple de RA
Je vais reprendre ici une francisation de l'exemple que j'ai mis sur le wiki du projet. Sa valeur est uniquement pédagogique.
| java |
package org.wadael.generated.advRobot.advAppender;
import org.wadael.waverobotfrmwrk.advanced.RobotWorker;
import org.wadael.waverobotfrmwrk.advanced.WithWorkersRobot;
import com.google.wave.api.Blip;
import com.google.wave.api.Event;
import com.google.wave.api.RobotMessageBundle;
@author
@SuppressWarnings("serial")
public class ExampleAjouteurAvanceServlet extends WithWorkersRobot {
public ExampleAjouteurAvanceServlet(){
super();
addRobotWorker( new LengthWorker() );
addRobotWorker( new CapitalWorker() );
}
@Override
public String getRobotIdentifier() {
return "RA";
}
@Override
protected String getRobotSelfIntroduction() {
return "Salutations.";
}
@Override
protected String getDisplayName() {
return "Robot avancé d'exemple pour Developpez.com";
}
}
public class LengthWorker implements RobotWorker {
@Override
public String getInstruction() {
return "taille";
}
@Override
public String getDescription() {
return "Affiche la taille du blip.";
}
@Override
public boolean doWork(RobotMessageBundle bun, Blip bli, Event eve,String params)
{
Blip lengthChild = bli.createChild();
lengthChild.getDocument().append("taille : " + bli.getDocument().getText().length() + " caractères");
return true;
}
}
public class CapitalWorker implements RobotWorker {
@Override
public String getInstruction() {
return "capi";
}
@Override
public String getDescription() {
return "Capitalise le texte du blip";
}
@Override
public boolean doWork(RobotMessageBundle bun, Blip bli, Event eve,String params)
{
Blip lengthChild = bli.createChild();
String capiTexte = bli.getDocument().getText().toUpperCase();
lengthChild.getDocument().replace(capiTexte);
return true;
}
}
|
 | Les Worker doivent être définis dans leur propre fichier |
VIII-B-6. Utilisation des RA
Là où les RS ont un comportement automatisé, les RA réagissent surtout à des commandes insérées par l'utilisateur au sein d'un blip.
L'objectif principal de ce type de robot est qu'un même RA puisse réagir à plusieurs commandes différentes.
Les RA seront codés de telle manière que leur utilisation soit expliquée lorsqu'ils se présentent, en pointant vers un site web par exemple.
Les RA sont riches, riches de commandes.
Ils ont leurs commandes
officielles
(1 commande utilisateur = 1 worker implémenté).
Ce sont celles qui sont listées lorsqu'un utilisateur valide un blip commençant par /help (valeur par défaut, reconfigurable).
Ils peuvent aussi avoir des commandes officieuses, de l'ombre. Elles correspondent aux workers faisant partie d'un RA mais retournant null comme instruction (méthode getInstruction() ).
Ils ont aussi des commandes standard, avec "/help" actuellement seule de cette catégorie mais qui sait ...
VIII-B-7. Les différents types de RA
Une sous-classe de RA a été créée afin d'obéir à la wavetiquette.
A savoir que l'usage est de ne se permettre d'ajouter un robot à une conversation uniquement si l'on est le créateur de la conversation.
Pour appliquer cela, il y a la classe CreatorObedientWithWorkersRobot.
Un autre type de RA est en préparation.
IX. Utilisation : pas à pas
Pour continuer ce tutoriel, il est temps d'abandonner la théorie pour passer à la pratique et créer un robot via le générateur.
Le point de départ est que tous les pré-requis sont satisfaits.
Sous Eclipse, vous avez donc un project WadRobotFramework ouvert, créé à partir d'une archive ZIP récupérée sur le site.
1/ Adapter le fichier build.properties
2/ Configurer le générateur pour un résultat personnalisé, en adaptant le fichier generator/generator.properties
3/ Choisir un type de robot
4/ Lancer la tache Ant voulue (revoir le paragraphe 7)
Après ces quatre premières étapes, vous verrez dans la console d'Eclipse un message vous indiquant où trouver le squelette de robot généré.
Votre écran ressemble à la capture ci-dessous.
Le projet du robot que vous venez de créer se trouve dans generated_Robots. Il faut maintenant créer un nouveau projet pour votre robot afin qu'il soit pris en compte dans votre workspace.
Si votre Eclipse est en anglais, faites un clic droit dans la partie " Package Explorer " (à gauche) et choisissez " Import ".
Puis " Existing project into workspace ", comme sur la capture ci-dessous.
Choisissez en " root directory " la racine du répertoire de votre robot fraichement généré.
L'astuce est de cocher la case "Copy projects into workspace".
Cela permet de dupliquer l'arborescence (qui est générée dans $WRF_HOME$/generated_robots) à l'endroit voulu du workspace.
Ci-dessus, choix du répertoire "racine" du robot généré.
Dans cet exemple, mon robot était nommé "dev" comme on peut le voir dans la zone "Projects".
En cliquant sur "Finish", vous avez désormais votre projet de robot prêt à être terminé puis déployé.
Le déployement se fait comme pour les autres applications web à la Google, à savoir qu'il est initié par le bouton à l'icone d'avion.
X. La suite
Que va-t'il se passer pour le WRF dans l'avenir ?
Pour répondre à cette question, le wiki possede une page WhatsNext sur laquelle j'essaie de centraliser les différents points qui seront traités ultérieurement, qu'ils soient des ajouts ou des modifications.
De nouvelles fonctionnalités seront ajoutées, parmi lesquelles :
- ne répondre qu'à une liste limitée d'utilisateurs (mise en place souscription)
- les commandes d'administration correspondantes
- générer des bots XMPP (utilisables dans Google Chat) et des robots ajouteurs en même temps (avec le même code métier) via un nouveau type de robot.
- Effacer les commandes (ou non) des blips
- Éventuellement, intégrer de nouveaux développeurs sur le projet.
- la création d'un nouveau type de robot (schizophrène)
XI. Conseils
Inscrivez-vous au groupe pour avoir des informations fraîches et/ou poser des questions.
Utilisez SVN plutôt que les distributions car une fois que vous aurez créé un projet WadRobotFramework dans votre workspace, il sera si simple de mettre WRF à jour.
XII. Liens
Tutoriels en anglais, par Romin Irani :
 | Je pense devoir préciser que Romin est un ami, mais cela ne change en rien la qualité de ses tutoriaux.
Il a publié un PDF regroupant l'ensemble des tutoriels (en anglais) qu'il a écrit sur Google App Engine et ses APIs.
Ce PDF est disponible à l'adresse suivante :
http://gaejexperiments.wordpress.com/gaej-experiments-ebook/
|
XIII. Remerciements
Je remercie chaleureusement Wachter d'avoir effectué la relecture de cet article,
ainsi que l'équipe de la rédaction de Developpez.com, Eric Siber, Caro-Line, Ricky81 et Hornetbzz pour leur accueil et leur aide.


Copyright © 2010 Jérôme BATON. Aucune reproduction, même partielle, ne peut être faite
de ce site et de l'ensemble de son contenu : textes, documents, images, etc.
sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 €
de dommages et intérêts.
Cette page est déposée.