Réaction du front-end à une modification Directus

Bonjour,

Dans mon architecture d’application j’ai :

  • un Directus (forcément installé en local)
  • une app flutter Windows (qui pilote le directus)
  • une série de smartphone (connectée au réseau local) qui envoient des datas au Directus (simple requête post dans DirectusAPI)

J’aimerais déclencher des actions de l’app Flutter lorsqu’il y a une nouvelle entrée (dans une table qui m’intéresse) dans Directus.

Savez-vous comment on peut procéder ?

Merci beaucoup !

Bonjour @StuntmanMike

Oui, on peut le faire avec les webhooks (qui va être ‹ deprecated › bientôt) ou en passant par les Flows (recommandé).
Tu peux définir un trigger et ensuite effectuer des opérations. C’est assez simple à mettre en oeuvre mais faut passer un peu de temps pour comprendre comment ça fonctionne (et malheureusement la doc est pas super). Je pense que tu peux l’utiliser pour envoyer une requête sur ton app Flutter pour la mettre à jour quand y’a une nouvelle entrée dans ta base.

1 « J'aime »

Bonjour @Mrt1 !

J’ai pas mal regardé la doc et différents tuto, si envoyer des emails ou passer des logs est assez simple et documenté, faire réagir une app Flutter reste une autre paire de manches… Pour le moment ma seule hypothèse reste d’utiliser un run script et d’envoyer des messages TCP, mais c’est peut-être un peu lourd pour une notification ?

Salut @StuntmanMike,

Effectivement, tu veux faire quoi exactement ? T’as essayé de regardé sur le discord officiel de Directus? C’est une peu le fouillis, mais tu peux avoir pas mal d’informations dessus.

En réalité j’ai 2 apps Flutter qui doivent fonctionner de concert : une app de gestion (PC) et une app mobile présente chez une petite flotte d’utilisateurs (15 max). L’app PC créer une session et je cherche à savoir quand tous les utilisateurs s’y sont connectés et ont saisis les bonnes données. Effectivement, je peux aller jeter un coup d’œil au Discord !

ça peut être sous forme de requete API qui réclame la liste des connectés? Ou faut que ce soit en temps réel ?

Disons que je ne sais jamais à quel moment les utilisateurs seront connectés, cela peut varier en minutes

En passant par un WebSocket peut-être ?

Je me suis donc penché sur la question. Créer un socket sur une app flutter Windows n’est pas problématique, mais faut-il encore que Directus envoie le message à travers un Flows. J’ai donc essayé avec le runScript, mais pour envoyer un message en Js il faut la librairie Net… c’est dommage, car la solution semble toute trouvée !

Je jette une bouteille à la merci, au cas où :

La création du serveur ws en flutter :

  void createWebSocketServer() async {
    server = await ServerSocket.bind('127.0.0.1', 8080);
    print('Socket server listening on port 8080');

    await for (Socket client in server!) {
      print(
          'Client connected: ${client.remoteAddress.address}:${client.remotePort}');

      client.listen(
        (Uint8List data) {
          final message = utf8.decode(data);
          print(message);
          print('Received message from client: $message');
        },
        onError: (error) {
          print('Socket error: $error');
          client.close();
        },
        onDone: () {
          print(
              'Client disconnected: ${client.remoteAddress.address}:${client.remotePort}');
          client.close();
        },
      );
    }
  }

et le code de test js :

<!DOCTYPE html>
<html>
<head>
  <title>Socket Message Sender</title>
</head>
<body>
  <script>
    var socket = new WebSocket('ws://127.0.0.1:8080');

    socket.onopen = function() {
      console.log('Socket connection established');
      var message = 'client upgrade';
      socket.send(message);
    };

    socket.onerror = function(error) {
      console.error('Socket error: ' + error);
    };

    socket.onclose = function(event) {
      console.log('Socket connection closed');
    };
  </script>
</body>
</html>

le client web indique qu’il ne parvient pas à se connecter et l’app Flutter voit bien le client et affiche toutes les données de connexion (sauf le message lui-même).

flutter: Client connected: 127.0.0.1:65504
flutter: GET / HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0
...

Finalement, j’arrive à faire communiquer ma page web avec le server Flutter utilisant ce code :

    var socket = new WebSocket('ws://127.0.0.1:8080');

    socket.onopen = function() {
      console.log('Socket connection established');
      var message = 'client upgrade';
      socket.send(message);
    };

Mais le même dans les runScript de directus me renvoie toujours la même erreur :

"message": "WebSocket is not defined"

Effectivement, cela semble vraiment être la solution, mais tous les exemples sont implémentés en web et non en Flutter

Je ne fais pas de flutter pour les webSocket.
Mais je pense que si tu regardes les trucs pour le web, ça doit être adaptable à Flutter sans soucis.

J’ai donc fait ça, converti le html en dart :

 const url = 'wss://127.0.0.1:8055/websocket';
    final accessToken = useCaseSession.getToken();
    const collection = 'player';

    final channel = IOWebSocketChannel.connect(url);

    channel.stream.listen((message) {
      final data = jsonDecode(message);
      print({'event': 'onmessage', 'data': data});
    }, onError: (error) {
      print({'event': 'onerror', 'error': error});
    }, onDone: () {
      print({'event': 'onclose'});
    });

    channel.sink.add(jsonEncode({
      'type': 'auth',
      'access_token': accessToken,
    }));

    subscribe() {
      channel.sink.add(jsonEncode({
        'type': 'subscribe',
        'collection': collection,
        'query': {
          'fields': ['*']
        },
      }));
    }

    // createItem(String text, String user) {
    //   channel.sink.add(jsonEncode({
    //     'type': 'items',
    //     'collection': collection,
    //     'action': 'create',
    //     'data': {'text': text, 'user': user},
    //   }));
    // }

    readLatestItem() {
      channel.sink.add(jsonEncode({
        'type': 'items',
        'collection': collection,
        'action': 'read',
        'query': {'limit': 1, 'sort': '-date_created'},
      }));
    }

    subscribe();
    //createItem('Hello', 'John');
    readLatestItem();

mais il semble y avoir un souci de compatibilité avec le wss (certainement du à import 'package:web_socket_channel/io.dart)

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: HandshakeException: Handshake error in client (OS Error:
	WRONG_VERSION_NUMBER(../../third_party/boringssl/src/ssl/tls_record.cc:242))