https://d226lax1qjow5r.cloudfront.net/blog/blogposts/next-web-voice-journal-python-vue-javascript-dr/p2p-voice-journal-featured.png

Création d'un journal Voice pour le prochain Web

Publié le May 13, 2021

Temps de lecture : 7 minutes

Le web est une chose merveilleuse. Nous pouvons créer et partager des informations plus facilement que jamais dans l'histoire de l'humanité.

Rédaction d'un tutoriel pour le site @NexmoDev à 35 000 pieds au-dessus de l'Atlantique #devrellife pic.twitter.com/mvxGDuEDky

- Aaron Bassett - Quel est le fuseau horaire ? (@aaronbassett) 15 mai 2018

Cependant, une grande partie de ce que nous créons vit à l'intérieur de jardins clos, ce qui est l'antithèse de l'idée originale du www. La suppression de ces jardins clos est un sujet dont Tim Berners Lee parle depuis au moins 2009 !

En fait, les données concernent nos vies. Il vous suffit de vous connecter à votre site de réseautage social, votre site préféré, et de dire : "Voici mon ami". Relation. Données. Vous dites : "Cette photographie représente cette personne". Bing ! Ce sont des données. Données, données, données. Chaque fois que vous faites quelque chose sur le site de réseautage social, le site de réseautage social prend des données et les utilise - les réaffecte - et les utilise pour rendre la vie des autres plus intéressante sur le site. Mais lorsque vous allez sur un autre site de données liées - disons qu'il s'agit d'un site sur les voyages - et que vous dites "Je veux envoyer cette photo à toutes les personnes de ce groupe", vous ne pouvez pas franchir les murs.

- Sir Tim Berners-Lee

En fait, la décentralisation est un aspect fondamental du www depuis sa création.

La décentralisation : Il n'est pas nécessaire d'obtenir l'autorisation d'une autorité centrale pour publier quoi que ce soit sur le web, il n'y a pas de nœud de contrôle central, et donc pas de point de défaillance unique ... ni de "kill switch" (interrupteur d'arrêt) ! Cela implique également l'absence de censure et de surveillance aveugles.

- Web Foundation, Histoire du Web

Présentation du web de personne à personne

Voice Journal ScreenshotVoice Journal Screenshot

Avec le web de personne à personne, aucun serveur n'est nécessaire. Chaque visiteur de votre site devient un pair dans l'essaim. Ils se connectent directement les uns aux autres et partagent les fichiers de votre site. Cela permet non seulement de maintenir votre site en ligne, mais aussi de se libérer d'une censure aveugle.

Voyons comment nous pouvons utiliser le protocole protocole Dat avec l'API Voice API de Nexmo de Nexmo pour créer un site web distribué qui hébergera un journal audio. Vous pouvez télécharger le code de cet exemple sur Github.

Déroulement du processus

Le déroulement de notre application est simple. Lorsque nous appelons notre numéro virtuel Nexmo, il enregistre l'audio au format MP3 et notifie notre serveur qu'il y a un nouvel enregistrement. Ensuite, lorsque notre serveur reçoit la notification de Nexmo, il télécharge le fichier MP3 et l'ajoute à notre archive, et il est automatiquement partagé avec tous les pairs utilisant le protocole Dat.

L'objet Nexmo Call Control et l'action d'enregistrement

L'enregistrement de l'audio est exceptionnellement simple avec Nexmo. Nous créons un fichier NCCO en une seule record action. Vous pouvez également utiliser la fonctionnalité TTS pour diffuser un message avant l'enregistrement ; j'ai choisi de ne pas le faire et de demander à Nexmo d'émettre un signal sonore lorsqu'il est prêt à enregistrer. Un peu comme un répondeur téléphonique.

@hug.get('/')
def ncco():
    return [
        {
            "action": "record",
            "eventUrl": ["<SERVER URL>/recordings"],
            "endOnKey": "*",
            "beepStart": True
        }
    ]

Dans le code ci-dessus, j'utilise Hug pour créer un endpoint JSON pour servir mon fichier NCCO à l'API Nexmo. Pour plus d'informations sur la création d'applications vocales avec Nexmo (et pour plus de détails sur ce qu'est un fichier NCCO), veuillez lire certains de mes tutoriels précédents :

J'explique également plus en détail les Applications Voice de Nexmo dans mes webinaires de codage en direct ; cela dure environ 20 minutes :

Sauvegarde de l'enregistrement

Une fois que l'appel est terminé ou que l'utilisateur a appuyé sur la touche ""* Nexmo nous informe du nouvel enregistrement via le webhook que nous avons spécifié comme l'élément eventUrl dans le code ci-dessus. La demande adressée à notre webhook contient le code recording_url que nous pouvons utiliser pour télécharger le fichier MP3. Cependant, nous devons d'abord nous authentifier auprès de Nexmo pour nous assurer que nous avons la permission de télécharger l'enregistrement. Nous utilisons des JWTs pour l'authentification.

@hug.post('/recordings')
def recordings(recording_url, recording_uuid):
    iat = int(time.time())
    now = datetime.datetime.now()

    with open('nexmo_private.key', 'rb') as key_file:
        private_key = key_file.read()

    payload = {
        'application_id': os.environ['APPLICATION_ID'],
        'iat': iat,
        'exp': iat + 60,
        'jti': str(uuid.uuid4()),
    }

    token = jwt.encode(payload, private_key, algorithm='RS256')

    recording_response = requests.get(
        recording_url,
        headers={
            'Authorization': b'Bearer ' + token,
            'User-Agent': 'voice-journal'
        }
    )
    if recording_response.status_code == 200:
        recordingfile = f'./site/recordings/{now.year}/{now.month}/{recording_uuid}.mp3'
        os.makedirs(os.path.dirname(recordingfile), exist_ok=True)

        with open(recordingfile, 'wb') as f:
            f.write(recording_response.content)

La plupart du code ci-dessus est pour l'authentification JWT [*oui, quelqu'un devrait vraiment rendre cela plus facile à faire dans le client Python... ?]. Après avoir téléchargé l'enregistrement, nous sauvegardons le fichier MP3, en veillant à ce que notre archive soit bien organisée.

/recordings/<current year>/<current month>/<recording uuid>.mp3

En structurant nos enregistrements de cette manière sur le disque, même sans notre application frontale, nous pouvons facilement trouver et écouter un enregistrement d'un jour particulier.

Distribuer nos enregistrements

Il y a deux façons principales de distribuer notre site via Dat; en utilisant le CLI Datou via le navigateur Beaker. Pour des raisons de simplicité, nous allons utiliser Beaker dans cet exemple. Cependant, si vous souhaitez exécuter votre webhook sur un serveur, ou en tant que fonction sans serveur, utilisez le CLI Dat. Tara Vancil a publié un excellent article sur la façon dont ils utilisent le Dat CLI pour publier des mises à jour sur leur blog (dat version). Une chose à garder à l'esprit est que notre application frontale utilise certaines API spécifiques à API spécifiques à Beaker pour interagir avec notre archive et afficher des informations sur l'essaim ; contrairement au site de Tara, il ne fonctionne pas dans un navigateur normal, vous n'avez donc pas besoin de l'API dathttpd.

Si vous ne l'avez pas encore fait, vous devriez télécharger Beaker maintenant.

Rejoignez mon essaim

Remarque : à l'instar de BitTorrent et d'autres protocoles P2P, les membres d'un essaim peuvent nécessairement voir les adresses IP des autres membres. N'oubliez pas qu'il s'agit d'une distribution d'égal à égal, qui ne passe pas par un service centralisé. Vous pouvez sauter la section suivante si vous n'êtes pas à l'aise avec le fait de partager votre adresse IP avec d'autres participants à l'essaim.

Ouvrez le lien suivant dat:// lien suivant dans Beaker : dat://8354c381e6f859e57ef6979af7e287acf3d528d8463f54774c36b6bc8aa514d6/

Félicitations, vous êtes maintenant membre de mon essaim et pouvez distribuer les enregistrements audio à d'autres visiteurs. Vous êtes (l'un de) mes serveurs web, merci !

Cependant, lorsque vous fermez votre navigateur, vous quittez l'essaim. Les fichiers restent sur votre ordinateur, mais vous ne les distribuez plus aux autres visiteurs. Pour s'assurer qu'il y a toujours au moins un pair disponible, j'ai ajouté l'archive à #_hashbase.

L'application frontale

Vous n'avez pas besoin de créer une interface utilisateur pour accéder à vos enregistrements. Beaker crée une interface simple à utiliser si notre répertoire d'archives ne contient pas de fichier d'index. C'est fonctionnel, mais pas très joli. Nous pouvons faire mieux.

Directory listing rendered by Beaker BrowserDirectory listing rendered by Beaker Browser

Notre interface est une application application Vuequi utilise le système de conception Volta de Vonage. Volta est le même système de conception que que nous avons utilisé pour la récente refonte du tableau de bord de Nexmo. Malheureusement, Volta n'est pas open source, du moins pas encore.

Nous utilisons également des API spécifiques à Beaker pour interagir avec nos archives.

const archive = new DatArchive(window.location)
let allRecordings = await archive.readdir('/recordings', {recursive: true, stat: true})

Dans le code ci-dessus, nous interrogeons notre archive, en lisant le contenu de notre répertoire d'enregistrements et en filtrant tous les fichiers qui ne sont pas des MP3. L'option stat demande à Beaker d'exécuter stat() sur chaque entrée et de revenir avec {name:, stat:}.

Une autre partie remarquable de la page est constituée par les cases d'information situées en haut de la page.

Screenshot of swarm information UIScreenshot of swarm information UI

Nous utilisons une autre API Beaker pour pour récupérer ces informations, getInfo()

async peers () {
    return await this.archiveInfo.peers
},
async version () {
    return await this.archiveInfo.version
},
async mtime () {
    let timestamp = await this.archiveInfo.mtime
    return moment(timestamp).startOf().fromNow()
},
async filesize () {
    let size = await this.archiveInfo.size
    return filesize(size, {round: 2})
}

Historique des archives

Le protocole Dat garantit que l'archive est signée par l'auteur et que son exactitude peut être vérifiée en interrogeant les pairs du réseau (uniformité de la distribution). Une seule version de l'historique de l'archive peut être distribuée. Si une archive Dat signée diffère de la copie signée d'un pair, elle est considérée comme corrompue, car le contenu différent pourrait indiquer une attaque ciblée de l'auteur de la Dat. Il est important que tous les utilisateurs reçoivent le même contenu, et c'est pourquoi Dat dispose d'une vérification d'intégrité intégrée.

- Beaker Browser, publier des logiciels en toute sécurité

History log screenshotHistory log screenshot

En utilisant les API Web de Beaker, nous pouvons interroger et afficher ce journal des modifications apportées à nos archives ; ce journal indique même si l'auteur a supprimé des entrées du journal.

archiveHistory: {
    async get () {
    const archive = new DatArchive(window.location)
    const completeHistory = archive.history({start: 0, reverse: true})
    return completeHistory
    }
},

En savoir plus

Partager:

https://a.storyblok.com/f/270183/150x150/a3d03a85fd/placeholder.svg
Aaron BassettAnciens de Vonage

Aaron était défenseur des développeurs chez Nexmo. Ingénieur logiciel chevronné et artiste numérique en herbe, Aaron est souvent amené à créer des choses avec du code ou de l'électronique, parfois les deux. On peut généralement savoir qu'il travaille sur quelque chose de nouveau grâce à l'odeur de composants brûlés qui flotte dans l'air.