> ## Documentation Index
> Fetch the complete documentation index at: https://developers.hubspot.fr/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Démarrer avec les fonctions sans serveur

> Créez votre première fonction sans serveur sur le CMS Hub et obtenez une réponse à partir de celle-ci.

'Créez votre première fonction sans serveur sur le CMS Hub et obtenez une réponse à partir de celle-ci.';

<ProductTier tiers={['cms-enterprise']} />

Les fonctions sans serveur permettent d'exécuter du code JavaScript via HubSpot côté serveur, évitant ainsi toute exposition au client. Cela peut être particulièrement important pour effectuer des requêtes d'API contenant des informations sensibles, telles qu'une clé d'API ou d'autres informations d'identification. Lorsque la fonction est appelée, HubSpot l'exécute sur son back-end, ce qui signifie également que vous n'avez pas besoin de fournir vos propres serveurs back-end pour effectuer des requêtes pour votre site web sur le CMS Hub. Les fonctions sans serveur de HubSpot utilisent l'environnement d'exécution [NodeJS](https://nodejs.org/en/about/).

Dans ce guide, vous allez découvrir comment créer une fonction sans serveur simple qui récupère un devis auprès d'un service tiers, puis affiche ce devis sur une page de site web. Pour créer et déployer la fonction sans serveur sur votre compte, vous utiliserez un projet développeur HubSpot.

<Alert type="warning" titleText="Remarque :">
  Bien que la méthode précédemment documentée de chargement de fonctions sans serveur dans le gestionnaire de conception soit toujours prise en charge, il est recommandé d'utiliser des projets développeur, car ils incluent une application privée pour une authentification plus facile tout en autorisant les dépendances tierces.

  Le contenu de ce guide a été mis à jour pour utiliser la méthode la plus récente. Vous pouvez trouver des informations de référence pour les fonctions sans serveur basées sur le gestionnaire de conception dans la [section de référence](/cms/reference/serverless-functions/serverless-functions).
</Alert>

Pour un aperçu de haut niveau des fonctions sans serveur, consultez la [présentation des fonctions sans serveur](https://developers.hubspot.com/docs). Vous pouvez également consulter la [chaîne YouTube des développeurs HubSpot](https://www.youtube.com/watch?v=N0arXQOyfXo) pour découvrir comment utiliser des fonctions sans serveur dans un projet CMS.

## Conditions préalables

Avant de commencer ce tutoriel, vous aurez besoin des éléments suivants :

* Un compte ***Content Hub** Entreprise* ou un [compte CMS sandbox développeur](https://app.hubspot.com/signup-hubspot/cms-developers).
* L'[ILC HubSpot](/developer-tooling/local-development/hubspot-cli/reference#install-the-cli) (dernière version recommandée), qui devra être installée et authentifiée avec le compte que vous utilisez. Pour vérifier quels comptes sont authentifiés, vous pouvez exécuter `hs accounts list`. En savoir plus sur les [premiers pas avec le développement local](/developer-tooling/local-development/hubspot-cli/install-the-cli).

## 1. Créer un projet local

Commencez par créer un projet localement afin de pouvoir le générer et le déployer sur votre compte.

* Dans le terminal, accédez au répertoire dans lequel vous stockerez votre projet à l'aide de la commande `cd`.

```shell theme={null}
cd Documents/Dev/serverless-function-project
```

* Exécutez `hs project create` pour créer un nouveau projet.

```shell theme={null}
hs project create
```

* Suivez les invites du terminal pour créer votre projet. Pour le modèle, sélectionnez **Créer un projet vide (pas de modèle)**.

![Option d'invite de terminal pour créer un projet vide sans modèle](https://www.hubspot.fr/hubfs/Knowledge_Base_2023-24-25/terminal-select-empty-project.png)

* Accédez au nouveau répertoire du projet à l'aide de la commande `cd`. Par exemple, si vous avez nommé votre projet *mon nouveau projet* :

```shell theme={null}
cd my-new-project
```

## 2. Ajouter une fonction sans serveur au projet

Une fois votre projet créé, ouvrez-le dans l'éditeur de votre choix, tel que [VS Code](https://developers.hubspot.com/docs). HubSpot aura automatiquement créé un répertoire de projet avec un répertoire `src` vide et un fichier de configuration `hsproject.json`. Pour ajouter une fonction sans serveur au projet, créez un répertoire `app` dans le répertoire `src`, puis ajoutez-y les répertoires et fichiers suivants :

* `app/app.json` : le fichier de configuration de l'application.
* `app/app.functions` : le répertoire des fonctions sans serveur. Vous pouvez utiliser le nom de votre choix, tant qu'il se termine par `.functions`.
* `app/app.functions/function.js` : le code JavaScript qui sera exécuté lors de l'appel de la fonction.
* `app/app.functions/serverless.json` : le fichier de configuration de la fonction sans serveur.
* `app/app.functions/package.json` : inclut les dépendances nécessaires.

![Structure du projet après l'ajout des fichiers et dossiers ci-dessus au répertoire du projet](https://www.hubspot.fr/hubfs/Knowledge_Base_2023-24-25/project-serverless-functions-structure.png)

* Copiez l'exemple de code ci-dessous dans vos fichiers locaux respectifs `app.json`, `function.js`, `serverless.json` et `package.json`. Sous chaque bloc de code `.json`, vous trouverez également un tableau contenant les définitions des champs.

<Tabs defaultSelected="0">
  <Tab tabId="0" title="app.json">
    ```json theme={null}
    {
      "name": "Serverless function app",
      "description": "This app runs a serverless function to fetch a quote using the Zen Quotes API.",
      "scopes": ["crm.objects.contacts.read", "crm.objects.contacts.write"],
      "uid": "serverless-function-app",
      "public": false
    }
    ```

    | Champ         | Type    | Description                                                                                                                                                                                                                                                                                                                                                                            |
    | ------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `name`        | Chaîne  | Le nom de l'application, qui s'affichera dans l'interface utilisateur de HubSpot.                                                                                                                                                                                                                                                                                                      |
    | `description` | Chaîne  | La description de l'application, qui s'affichera dans l'interface utilisateur de HubSpot.                                                                                                                                                                                                                                                                                              |
    | `scopes`      | Tableau | Les domaines auxquels l'application a accès pour authentifier les requêtes avec le jeton d'accès de l'application privée. Les deux domaines ci-dessus sont les domaines minimum requis. Aucun domaine supplémentaire n'est ajouté pour ce tutoriel, car vous n'aurez pas besoin d'utiliser le jeton d'accès de l'application privée pour la requête que vous effectuerez.              |
    | `uid`         | Chaîne  | L'identifiant unique de l'application. Il peut s'agir de n'importe quelle chaîne, mais doit permettre d'identifier l'application de manière significative l'application. HubSpot identifiera l'application par cet ID afin que vous puissiez modifier le `name` de l'application localement ou dans HubSpot sans supprimer les données historiques ou d'état, telles que les journaux. |
    | `public`      | Chaîne  | Défini sur `false` pour les applications privées.                                                                                                                                                                                                                                                                                                                                      |
  </Tab>

  <Tab tabId="1" title="function.js">
    Cette fonction extraira un devis aléatoire à partir de l'[API Zen Quotes](https://zenquotes.io/).

    ```js theme={null}
    const axios = require("axios");

    exports.main = async context => {
      try {
        // Make GET request to the ZenQuotes API
        const response = await axios.get("https://zenquotes.io/api/random");

        // Extract the quote data (first item in the array)
        const quoteData = response.data[0];

        // Log the quote and author to console
        console.log(`"${quoteData.q}" — ${quoteData.a}`);

        // Return a properly formatted response with status code and body
        return {
          statusCode: 200,
          body: quoteData,
          headers: {
            "Content-Type": "application/json",
          },
        };
      } catch (error) {
        // Handle any errors that occur during the request
        console.error("Error fetching quote:", error.message);

        // Return an error response
        return {
          statusCode: 500,
          body: { error: "Failed to fetch quote" },
          headers: {
            "Content-Type": "application/json",
          },
        };
      }
    };
    ```
  </Tab>

  <Tab tabId="2" title="serverless.json">
    ```js theme={null}
    {
      "appFunctions": {
         "quote-function": {
          "file": "function.js",
          "secrets": [],
          "endpoint": {
            "path": "fetch-quote",
            "method": ["GET"]
           }
        }
      }
    }

    ```

    | Champ            | Type    | Description                                                                                                                                                                                                                                                          |
    | ---------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `quote-function` | Objet   | Un objet contenant les détails de configuration de la fonction sans serveur. Cet objet peut avoir n'importe quel nom, mais il doit correspondre au nom du champ associé que vous référencez dans le champ `appFunctions` de votre fichier `serverless.json`.         |
    | `file`           | Chaîne  | Nom du fichier JavaScript contenant le code de la fonction sans serveur à exécuter.                                                                                                                                                                                  |
    | `secrets`        | Tableau | Un tableau contenant les noms des secrets que la fonction utilisera pour authentifier les requêtes. Aucun secret n'est nécessaire pour ce tutoriel.                                                                                                                  |
    | `endpoint`       | Objet   | Un objet contenant des informations sur le point de terminaison que vous pouvez utiliser pour appeler la fonction. Le champ `path` définit la dernière valeur du chemin d'accès `/hs/serverless/<path>`, tandis que le champ `method` définit la méthode de requête. |
  </Tab>

  <Tab tabId="3" title="package.json">
    ```json theme={null}
    {
      "name": "example-serverless-function",
      "version": "0.1.0",
      "author": "HubSpot",
      "license": "MIT",
      "dependencies": {
        "@hubspot/api-client": "^7.0.1",
        "axios": "^0.27.2"
      }
    }
    ```

    | Champ          | Type  | Description                                             |
    | -------------- | ----- | ------------------------------------------------------- |
    | `dependencies` | Objet | Les dépendances incluses dans la fonction sans serveur. |
  </Tab>
</Tabs>

* Après avoir ajouté le code ci-dessus, enregistrez vos modifications.

## 3. Charger le projet sur HubSpot

Une fois vos modifications enregistrées, vous pouvez maintenant charger le projet sur HubSpot pour créer et déployer l'application et la fonction sans serveur.

* Dans le terminal, exécutez `hs project upload`.

```shell theme={null}
hs project upload
```

* Confirmez que vous souhaitez créer le projet dans le compte. Vous n'aurez pas besoin de le confirmer une fois la création initiale terminée. Le terminal affichera l'état actuel des étapes de création et de déploiement au fur et à mesure de leur progression.
* Une fois le chargement terminé, exécutez `hs project open` pour afficher le projet dans HubSpot.

```shell theme={null}
hs project open
```

Dans HubSpot, vous pouvez afficher les détails du projet, créer et déployer des journaux, des journaux de fonctions sans serveur ou encore gérer le projet et l'application. En savoir plus sur [la gestion de projets dans HubSpot](https://developers.hubspot.com/docs#view-the-project-in-hubspot).

## 4. Tester la fonction

Une fois la fonction sans serveur déployée, vous pouvez l'invoquer en accédant à son URL publique. Les fonctions sans serveur créées avec des projets développeur ont la structure d'URL publique suivante : `https://<domain>/hs/serverless/<endpoint-path-from-config>`.

* `<domain>` : vous pouvez utiliser n'importe quel domaine connecté au compte. Par exemple, si siteweb.com et sous-domaine.brand.com sont tous deux connectés au compte, vous pouvez appeler la fonction en utilisant `https://website.com/hs/serverless/<path>` ou `https://subdomain.brand.com/hs/serverless/<path>`.
* `<endpoint-path-from-config>` : la valeur dans le champ `path` dans `serverless.json`.

Sur la base de l'exemple de code fourni dans ce tutoriel, l'URL publique pour appeler la fonction sera : `https://<domain>/hs/serverless/fetch-quote`.

<Alert type="info">
  Dans l'URL d'appel de la fonction, le chemin du point de terminaison est global plutôt que limité à l'application ou au projet. Si vous avez des points de terminaison identiques dans plusieurs applications ou projets, la fonction de point de terminaison la plus récemment déployée sera prioritaire.
</Alert>

Pour afficher le résultat de la fonction, accédez à cette URL dans votre navigateur, en remplaçant le domaine par l'un de vos domaines hébergés par HubSpot. Si vous n'avez pas connecté de domaine personnalisé, vous pouvez utiliser l'un des domaines par défaut fournis par HubSpot : `<hubId>.hs-sites.com` (par exemple, `123456.hs-sites.com`). Votre navigateur devrait afficher les données renvoyées par l'API Zen Quotes.

![Navigateur affichant les données renvoyées par l'API Zen Quotes](https://www.hubspot.fr/hubfs/Knowledge_Base_2023-24-25/zen-quotes-api-return.png)

## 5. Appeler la fonction depuis une page de site web

Maintenant que vous avez créé la fonction sans serveur et confirmé qu'elle renvoie des données, implémentez-la dans une page pour voir les données renvoyées dans un contexte plus réaliste. Pour ce tutoriel, vous allez créer un modèle de page contenant du code JavaScript et HTML personnalisés pour exécuter la fonction et afficher les données de réponse.

Tout d'abord, créez un nouveau modèle de page :

* Dans votre environnement local, créez un nouveau répertoire pour contenir votre modèle de page. Pour les besoins de ce tutoriel, créez ce répertoire en dehors du répertoire de projet créé par `hs project create`.

* Dans le terminal, accédez à ce répertoire à l'aide de la commande `cd`.

```shell theme={null}
cd Documents/Dev/serverless-page
```

* Exécutez `hs create template "serverless-template"` pour créer un nouveau modèle nommé `serverless-template`.

```shell theme={null}
hs create template "serverless-template"
```

* Sélectionnez le type de modèle de **page**.
* Ouvrez le fichier de modèle de page que vous venez de créer dans votre éditeur, puis remplacez le code du boilerplate par le code ci-dessous. Veillez à remplacer `<domain>` dans la fonction l'URL de point de terminaison (`fetch('http://<domain>/hs/serverless/fetch-quote')`) par un domaine connecté à votre compte HubSpot.

```html theme={null}
<!--
    templateType: page
    label: Serverless function example template
    isAvailableForNewContent: true
-->
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>{{ content.html_title }}</title>
    <meta name="description" content="{{ content.meta_description }}" />
    {{ standard_header_includes }}
  </head>
  <body>
    {% module "page_template_logo" path="@hubspot/logo" label="Logo" %}
    <!-- Button to fetch quote via serverless function -->
    <div class="serverless-container">
      <h2>Get quote</h2>
      <p class="subtitle">Click the button to fetch and display a quote.</p>
      <button id="data-button" type="button">Get quote!</button>
      <div id="data-container">
        <p class="data"></p>
      </div>
    </div>
    <!-- End button section -->

    {{ standard_footer_includes }}

    <!-- JavaScript that invokes the serverless function
     and adds returned data into the "data" text element -->
    <script>
      const dataButton = document.getElementById("data-button");
      const dataContainer = document.getElementById("data-container");

      dataButton.addEventListener("click", function (e) {
        console.log("Button clicked!");

        // Show loading state
        dataContainer.innerText = "Loading...";
        // Replace <domain> with your own domain
        fetch("http://<domain>/hs/serverless/fetch-quote")
          .then(response => {
            if (!response.ok) {
              throw new Error(`HTTP error! Status: ${response.status}`);
            }
            // Parse the JSON response
            return response.json();
          })

          .then(data => {
            console.log("Raw data received:", data);

            // Clear container
            dataContainer.innerText = "";

            // Create the paragraph element
            const newDataElement = document.createElement("p");
            newDataElement.innerText = `"${data.q}" — ${data.a}`;
            dataContainer.appendChild(newDataElement);
          });
      });
    </script>
  </body>
</html>
```

* Enregistrez le fichier, puis exécutez `hs upload` pour le charger dans HubSpot. Suivez les invites du terminal pour sélectionner la source locale et le chemin de destination. Pour ce didacticiel, appuyez simplement sur **Entrée** pour chaque requête afin d'utiliser les chemins par défaut.

Ensuite, créez une nouvelle page à partir du modèle dans HubSpot.

* Accédez au tableau de bord des pages du site web de votre compte HubSpot en exécutant la commande `hs open website-pages`.

```shell theme={null}
hs open website-pages
```

<Alert type="info">
  Consultez la liste complète des raccourcis ouverts disponibles en exécutant
  `hs open --list`.
</Alert>

* Dans votre navigateur, cliquez sur **Créer** dans l'angle supérieur droit pour créer une nouvelle page.
* Dans la boîte de dialogue, sélectionnez un **domaine** à utiliser, puis attribuez un **nom de page**. Le domaine de la page devra correspondre au domaine que vous utilisez pour appeler la fonction sans serveur afin d'éviter les erreurs d'origine croisée (CORS). Vous pouvez sélectionner ce domaine dans le menu déroulant ou mettre à jour l'URL du point de terminaison dans le code de modèle de page (`fetch('http://<domain>/hs/serverless/fetch-quote')`) pour utiliser le domaine que vous sélectionnez lors de cette étape.
* Cliquez sur **Créer une page**.
* Sur l'écran de sélection de modèle, recherchez votre nouveau modèle. Vous pouvez utiliser le libellé ou le nom de fichier pour rechercher le modèle (par exemple, « Page d'exemple de fonction sans serveur »). Le modèle apparaîtra dans *Autres modèles*, car il ne fait pas partie d'un thème.

![Section Autres modèles montrant le modèle de page nouvellement créé](https://www.hubspot.fr/hubfs/Knowledge_Base_2023-24-25/select-new-template.png)

* Cliquez sur **Sélectionner un modèle**.
* Dans l'éditeur de page, cliquez sur **Aperçu** dans l'angle supérieur droit.

![Bouton d'aperçu de l'éditeur de page](https://www.hubspot.fr/hubfs/page-preview.png)

* Cliquez sur **Ouvrir dans un nouvel onglet**.

Dans le nouvel onglet, vous devriez désormais pouvoir cliquer sur le bouton pour récupérer et afficher des devis.

![Exemple de bouton qui récupère et affiche des devis à partir de l'API Zen Quotes](https://www.hubspot.fr/hubfs/Knowledge_Base_2023-24-25/quote-button-demonstration.gif)

## Étapes suivantes

Maintenant que vous avez créé et implémenté une fonction sans serveur qui interagit avec une API tierce, il existe plusieurs façons de continuer à développer votre utilisation des fonctions sans serveur, telles que :

* [Inclure l'authentification dans une requête](/cms/reference/serverless-functions/serverless-functions-in-projects#authentication) pour effectuer des appels aux API de HubSpot ou à d'autres API authentifiées par des tiers.
* Implémenter le bouton et le code JavaScript dans un module plutôt que de les coder en dur dans le modèle de page. Cela vous donnerait une option plus portable, permettant à la fonction d'être appelée à partir de n'importe quelle page à laquelle le module est ajouté. Pour ce faire, vous devez créer un module, puis ajouter le HTML dans le fichier `module.html` du module et le JavaScript dans le fichier `module.js`.

<Tabs defaultSelected="0">
  <Tab tabId="0" title="module.html">
    ```html theme={null}
    <div class="serverless-container">
      <h2>Get quote</h2>
      <p class="subtitle">Click the button to fetch and display a quote.</p>
      <button id="data-button" type="button">Get quote!</button>
      <div id="data-container">
        <p class="data"></p>
      </div>
    </div>
    ```
  </Tab>

  <Tab tabId="1" title="module.js">
    ```js theme={null}
    const dataButton = document.getElementById("data-button");
    const dataContainer = document.getElementById("data-container");

    dataButton.addEventListener("click", function (e) {
      console.log("Button clicked!");

      // Show loading state
      dataContainer.innerText = "Loading...";

      fetch("http://meowmix-2272014.hs-sites.com/hs/serverless/fetch-quote")
        .then(response => {
          if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
          }
          // Parse the JSON response
          return response.json();
        })

        .then(data => {
          console.log("Raw data received:", data);

          // Clear container
          dataContainer.innerText = "";

          // Create the paragraph element
          const newDataElement = document.createElement("p");
          newDataElement.innerText = `"${data.q}" — ${data.a}`;
          dataContainer.appendChild(newDataElement);
        });
    });
    ```
  </Tab>
</Tabs>
