[VBA] Requête API pour demander mon authorization token

Hello le forum, c'est encore moi avec des problèmes toujours plus complexes

Suite à mes derniers post, j'ai compris que le site sur le quel je souhaite récupérer des données mises à jour tous les jours utilise les APIs (je suis complètement new dans ce milieu)

En cherchant sur le net je trouve de très nombreux sujet qui montre comment envoyer une requête avec l'URL et l'authorization token

Mon problème c'est que je n'ai pas ce authorization token et je dois le "demander" via API justement :

image

Et là bah je suis bloqué, impossible de comprendre et de trouver un code qui me permettrais d'effectuer une requête avec URL + MonMail + MonMDP afin de recevoir mon token.

Voici le code de base que l'on retrouve sur de nombreux forums, ça peut servir de base..

Sub test()
Dim hReq As Object   ', Json As Dictionary
Dim sht As Worksheet
Dim authKey As String
Dim response As String

authKey = "L'endroit ou je met mon token"

Set sht = Sheets(1)

Dim strUrl As String
strUrl = "https://api.safetyculture.io/auth"
Set hReq = CreateObject("MSXML2.XMLHTTP")
With hReq
.Open "GET", strUrl, False
.SetRequestHeader "Authorization", "Bearer " & authKey
.Send
response = hReq.ResponseText
End With

MsgBox response

End Sub

J'espère que quelqu'un ici saura m'aider.

A + dans le bus

Re, petit update:

Sub Get_Token()
Dim objHTTP  As Object   ', Json As Dictionary
Dim sht As Worksheet
Dim authKey As String
Dim response As String

UserName = InputBox("iAuditor Username:")
Password = InputBox("iAuditor Password:")

Set sht = Sheets(1)

Dim strUrl As String
URL = "https://api.safetyculture.io/auth"
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
With objHTTP
.Open "POST", URL, False
.SetRequestHeader "data-urlencode", "username=" & UserName
.SetRequestHeader "data-urlencode", "password=" & Password
.SetRequestHeader "data-urlencode", "grant_type=password"
.Send
response = objHTTP.ResponseText
End With

MsgBox response
End Sub

J'ai compris qu'il fallait utiliser "POST" pour questionner le serveur.. bien sûre le code ne marche pas. Je pense que le problème viens du .SetRequestHeader je n'arrive pas à traduire ce que l'on peut voir dans la screenshot du premier post :

 --data-urlencode username=example@safetyculture.io \
  --data-urlencode password=your_password \
  -d grant_type=password \

Voici le message d'erreur:

image

J'ai réussis !!

En fait, j'ai généré mon Token Privée directement sur le site, Ensuite avec ce code j'arrive à extraire mes données au format Json je croit, donc la ca va être la partie pas très fun pour traiter efficacement les données. Mais au moins je peux mettre à jour mes données en 1 clic sans avoir à DL le CSV tout les jours etc...

Sub Get_Data()
Dim hReq As Object ', Json As Dictionary
Dim sht As Worksheet
Dim authKey As String

authKey = "d8a0df7d7e1XXXXXXXXXXXXXXXXXXXXXXXXXXX7c65ec9eff3c765cf2fcf"

Set sht = Sheets(1)

Dim strUrl As String
    strUrl = "https://api.safetyculture.io/tasks/v1/actions/list"
Set hReq = CreateObject("MSXML2.XMLHTTP")
    With hReq
        .Open "POST", strUrl, False
        .SetRequestHeader "Authorization", "Bearer " & authKey
        .Send
    End With

Dim response As String
    response = hReq.ResponseText
    sht.Range("A1") = hReq.ResponseText
End Sub

Un dernier petit problèmes... J'ai trouvé comment envoyé des données en "Header" soit -H en HTTP traduit en .SetRequestHeader en VBA

Mais j'aimerais ajouter des filtres à ma requête donc ajouter une information "data" :

En HTTP ca donne ça :

-d '{
      "filters": [
        {
          "inspection_id": {
            "value": ["72d83a19-71b2-44da-856e-c91d7296a096"]
          }
        },
          {
              "modified_at": {
                  "from": {
                      "value": "2021-08-11T07:00:25.464490Z"
                  },
                  "to": {
                      "value": "2021-08-11T07:34:23.828360Z"
                  }
              }
          }
      ] 
    }'

Comment traduire ce -d en VBA ? Je trouve rien à ce sujet sur le net...

Résultat de ma journée de torture mental sur ce sujet :

Il semblerait que les informations "data" se place dans la commande .Send comme on peut le voir dans ce code:

Sub Get_Data()
Dim hReq As Object
Dim sht As Worksheet
Dim authKey As String
Dim response As String
Dim response_objet As Object
Dim Body As String

authKey = "d8a0df7d7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx65cf2fcf"
Body = "{""template_id"": {""operator"": 7,""value"": [""fc2e53f6-4712-4ca5-b681-aba3ac954217""]}}"

Set sht = Sheets(1)
sht.Range("A3") = Body
Dim strUrl As String
    strUrl = "https://api.safetyculture.io/tasks/v1/actions/list"
Set hReq = CreateObject("MSXML2.XMLHTTP")
    With hReq
        .Open "POST", strUrl, False
        .SetRequestHeader "Authorization", "Bearer " & authKey
        .SetRequestHeader "Content-Type", "application/json"
        .Send Body
    End With

    response = hReq.ResponseText
    sht.Range("A1") = response
End Sub

J'ai recus de l'aide sur Stackoverflow ici

https://stackoverflow.com/questions/72828037/translate-d-in-vba-when-doing-an-http-request

Je sent que je me rapproche de la solution... Allez courage Gabin

Bonjour Gabin37,

Courage... tu devrais t'en sortir.

Ce message pour ne pas te laisser discuter tout seul...

Et cela devrait intéresser quelques-uns ?

Salut X Cellus merci pour ton message de soutiens !

Je n'avais pas l'intention de faire un monologue mais je préfère donner suite à ma demande pour pas recevoir une réponse à une problème que j'aurais résolut, et peut être que cela pourras aider quelqu'un qui à un problème similaire.

Je suis certains qu'il me manque une tout petit bout de quelques chose dans ma variable "Body" je teste un peu toutes les combinaisons...

Salut à tous !

Il ne faut jamais rien lâcher

Body = "{ ""filters"": [ { ""template_id"": { ""value"": [""884b95df35104f4792a3c1fdfed63f0e""]}}]}"

Voici le contenue de ma variable (voir mon précédent code)

Ne trouvant quasiment rien du tout sur le net, j'ai cherché à tâtons en testons une multitude de "combinaison" et en essayant de comprend les messages d'erreurs toujours différents

J'obtiens donc toutes mes données au format "JSON Text" filtré correctement avec "Template_id"

Maintenant je dois traiter mon JSON pour extraire ce que je souhaite, c'est un autre sujet j'espère y arriver sans trop de difficultés !

Bonne semaine le forum

Salut Gabin,

Bravo pour la persévérance !

Pour cette partie la :

Maintenant je dois traiter mon JSON pour extraire ce que je souhaite, c'est un autre sujet j'espère y arriver sans trop de difficultés !

Power query devrait être ton ami.

Hello Valentin comment-vas tu ?

Tu pourrais m'en dire un peu plus ? Car pour le moment je termine mon code avec une variable qui contient tout mon JSON :

{
  "actions":  [
    {
      "task":  {
        "task_id":  "5a95ec6e-a923-4405-8f69-9afea34b014e",
        "creator":  {
          "user_id":  "0c532b77-d6fb-4f68-a637-c591c6f04472",
          "firstname":  "XXX",
          "lastname":  "XXXXX"
        },
        "title":  "Susan to investigate, fix and catch-up lost production ",
        "description":  "",
        "created_at":  "2022-06-28T07:04:09.155083Z",
        "due_at":  "2022-06-28T12:00:00Z",
        "priority_id":  "02eb40c1-4f46-40c5-be16-d32941c96ec9",
        "status_id":  "7223d809-553e-4714-a038-62dc98f3fbf3",
        "collaborators":  [
          {
            "collaborator_id":  "b88ec7a5-366e-431d-a297-3880a15013ec",
            "collaborator_type":  "USER",
            "assigned_role":  "ASSIGNEE",
            "user":  {
              "user_id":  "b88ec7a5-366e-431d-a297-3880a15013ec",
              "firstname":  "XXX",
              "lastname":  "XXXX"
            }
          }
        ],
        "template_id":  "884b95df-3510-4f47-92a3-c1fdfed63f0e",
        "inspection":  {
          "inspection_id":  "3538f795-48f8-45f3-a2c8-e4b798656c5d",
          "inspection_name":  "28 Jun 2022 / XXXXXXX"
        },
        "inspection_item":  {
          "inspection_item_id":  "1085b3fa-166c-46cb-9949-d0b1455f0bfb",
          "inspection_item_name":  "Production Target Achieved",
          "inspection_item_type":  "",
          "inspection_item_response_values":  []
        },
        "site":  {
          "id":  "811c7fdf-0dc2-4621-af78-9814694869c6",
          "name":  "Nitra",
          "region":  "",
          "area":  ""
        },
        "modified_at":  "2022-06-29T12:05:29.073155Z",
        "references":  [],
        "completed_at":  "2022-06-29T12:05:29.073155Z",
        "template_name":  "Plant Manager - Daily Plant tour",
        "status":  {
          "status_id":  "7223d809-553e-4714-a038-62dc98f3fbf3",
          "key":  "COMPLETE",
          "label":  "Complete",
          "display_order":  3
        }
      }
    },
    {
      "task":  {
        "task_id":  "8d50d782-7469-4778-bf32-31b99956f75f",
        "creator":  {
          "user_id":  "0c532b77-d6fb-4f68-a637-c591c6f04472",
          "firstname":  "XXXX",
          "lastname":  "XXXXX"
        },
        "title":  "Lubo to fix 5S issues",.........................................

En voici un extrait, en fait c'est le bloc "Task:" qui se répètent avec je pense toujours le même format. De cette variable VBA donc, j'aimerais extraires ces données pour chaques "task" :

• task_id
• key
• due_at
• firstname + lastname
• inspection_item_name
• Created_at
• modified_at
• completed_at

Aussi, le format de la date risque de poser problème ? D'après mes infos les égalités suivantes sont vraies:

"2022-06-28T12:00:00Z" = 28/06/2022 14h00
"2022-06-28T07:04:09.155083Z" = 28/06/2022 09h04

As-tu déjà rencontré ce format de date ?

Je ferais peut être mieux de créer un nouveau sujet là ^^'

Par Power Query je ne sais pas par où commencer, sinon j'allais me lancer dans un fastidieux code VBA qui parcours ma chaine de charactère et enregistre les valeurs dans des tableaux..

La victoire était trop belle.. Si je reviens sur mon extraction, je remarque que j'extrait une chaine de caractère de 210 000 caractères. Un bloc "task" contient environ 2000 caractère ce qui veut dire que théoriquement j'extrait 100 tasks. Et normalement je devrais en avoir 1000 tasks.

Une idée de comment rapidement afficher l'intégralité de ma variable string dans un bloc note / word ou autre ?

Voir post suivant

J'ai extrait l'intégralité de mon JSON.. Et voici ce que je trouve à la toute fin... :

image

Donc il a bien trouvé les 996 résultats attendus cool, Mais toutes les données ne sont pas présentes ici. Je doit utiliser le next_page_token pour extraire la suite

Et bien allez.. c'est reparti !

image

Bonjour Gabin,

Je n'ai peut être pas bien compris, tu te retrouves avec un Json où tu souhaites pourvoir seulement extraire certaines données ? tu en fait quoi des données après ?

Power query est capable d'importer dans excel des Json et de le transformer avant importation.

Cdt

Salut Valentin,

à la fin de mon code VBA qui lance une requête HTTP je me retrouve avec une variable string qui contient l'intégralité de la réponse au format "String" mais si je copy cette chaine de caractère dans notepad++ par exemple on voit bien que c'est du JSON. Le fait que le JSON soit dans une variable je ne voyais pas bien comment l'exploiter via PQ.. ? (Sinon ouvrir manuellement un fichier JSON avec PQ j'ai réussis )

Sinon dans mon cas, j'ai trouvé un code super puissant ICI qui permet de facilement extraire toutes mes données !! Ensuite avec ces données je crée un planning avec des tâches à faire en fonctions des dates et des priorités etc.

J'ai tout juste finit mon programme il y a 30 min a peine ! Sans passer par PQ du coup.

4 Jours de programmations non-stop mais bon sang qu'est-ce que j'ai appris de choses ! C'était plaisant. Encore 2 trois peaufinages à faire mais plus rien d'insurmontable.

Pour info si à l'avenir quelqu'un se sert de ce post voici ma requête:

authKey = sht_main.Range("B5")

next_page_token = "{""page_token"": """ & sht_main.Range("B1") & """}"
If sht_main.Range("B1") = "" Then next_page_token = ""
Body = next_page_token & "{ ""filters"": [ { ""template_id"": { ""value"": [""884b95df-3510-4f47-92a3-c1fdfed63f0e""]}}]}"

Dim strUrl As String
    strUrl = "https://api.safetyculture.io/tasks/v1/actions/list"
Set hReq = CreateObject("MSXML2.XMLHTTP")
    With hReq
        .Open "POST", strUrl, False
        .SetRequestHeader "Authorization", "Bearer " & authKey
        .SetRequestHeader "Content-Type", "application/json"
        On Error GoTo retry
        .Send Body
    End With

Set response_objet = JsonConverter.ParseJson(hReq.ResponseText)

Grace au programme JSONConverter mentionné plus haut dans ce post, je me retrouve avec une variable "Dictionnary" Une sorte d'énorme tableau qui contient toutes les données c'est magique, je l'utilise comme cela par exemple:

On Error Resume Next
For Each Value In response_objet("actions")
    Tablo(i, 0) = Value("task")("task_id")
    temp = ""
    temp = Value("task")("created_at")
    Tablo(i, 1) = CDate(Format(ISODATE(temp), "dd/mm/yyyy"))
    temp = ""
    temp = Value("task")("due_at")
    Tablo(i, 2) = CDate(Format(ISODATE(temp), "dd/mm/yyyy"))
    temp = ""
    temp = Value("task")("modified_at")
    Tablo(i, 3) = CDate(Format(ISODATE(temp), "dd/mm/yyyy"))
    temp = ""
    Tablo(i, 4) = temp
    temp = Value("task")("completed_at")
    Tablo(i, 4) = CDate(Format(ISODATE(temp), "dd/mm/yyyy"))
    For Each Value2 In Value("task")("collaborators")
    Tablo(i, 5) = Tablo(i, 5) & Value2("user")("firstname") & " " & Value2("user")("lastname") & " & "
    Tablo(i, 5) = Tablo(i, 5) & Replace(Left(Value2("external_user")("email"), InStr(1, Value2("external_user")("email"), "@") - 1), ".", " ") & " & "
    Next Value2
    Tablo(i, 6) = Value("task")("status")("key")
    Tablo(i, 7) = Value("task")("inspection_item")("inspection_item_name")
    Tablo(i, 8) = False
    Tablo(i, 9) = Value("task")("template_id")
    Tablo(i, 5) = Left(Tablo(i, 5), Len(Tablo(i, 5)) - 3)
    i = i + 1
Next Value
On Error GoTo 0

Pour trier un peu ce dont j'ai besoin et avoir mon Tablo(x,y) avec ce qui m'interesse.

Bonne journée à tous.

Gabin

PS: J'ai également trouvé un code tout fait sur le net pour gérer les dates au format ISO 8601 JSON

Rechercher des sujets similaires à "vba requete api demander mon authorization token"