Kucowanie API

Już któryś raz staję przed samemu sobie stworzonym problemem, który chciałem raz na zawsze zakończyć, bo zawsze odpadałem na milionie poradników, które albo były dla mnie za trudne, albo za proste - nigdy w punkt. :smiley:

PROBLEM:
Mam dostęp do REST API (umiem wygenerować klucz, potrafię mu nadać uprawnienia odczytu, bo te wystarczą) jakiegoś serwisu opartego na Wordpressie. Chcę je pytać raz na minutę (tu już wiem, że pomaga CRON), czy przypadkiem nie pojawił się nowy rekord w bazie spełniający określone warunki (załóżmy, że w tytule pojawia się fraza “dupa”, albo post należy do kategorii “tyłki”).

Jeżeli zwrotnie dostaniemy info, że tak - jest nowy wpis (albo więcej niż jeden) to chciałbym np. webhooksem puścić dalej info do dowolnego serwisu (np. IFTTT), tyle razy ile razy dostałem potwierdzenie, że jest nowa pozycja w bazie. Kwestię jak zbudować webhooks mam ogarniętą więc to nie powinien być problem.

ROZWIĄZANIE:
Chcę dostać prostą instrukcję, w której będą odpowiedzi na moje nieogarnięte pytania:

  1. jak się do tego zabrać - tj. w jakim języku się pisze takie “apki” (pobrałem sobie na Maca program Insomnia, który pozwala budować różne zapytania i pokazuje co to API zwraca) [jak już będę znał język w jakim piszę, to będę wiedział gdzie szukać pomocy jak coś nie będzie działać xD] - patrząc po dokumentacji, REST API Woocommerce dotyka tych bibliotek: Python, Node.js, PHP, Ruby, ale ja nie wiem zupełnie jaka jest relacja między nimi, co jest czym i z czego miałbym skorzystać… ;/
  2. jak mam już język, to potrzebuję jakiegoś środowiska serwerowego, żeby to gówno tam postawić - gdzie, jak i za ile (chyba nie muszę mówić, że najlepiej za darmo?)?
  3. jak już wiem gdzie to postawić to przyjąłbym chętnie link do jakiegoś prostego poradnika, który bazuje na REST API najlepiej wystawianym przez Wordpressa (a Woocommerce to już w ogóle idealnie).

Będę wdzięczny bardzo za pomoc - uważam, że jak przejdziemy przez ten bardzo konkretny problem, to dużo łatwiej mi (czy innym czytelnikom) będzie przejść przez podobny case, budując inne automatyzacje z wykorzystaniem jakiegoś API, czyli rzeczy troszkę bardziej skomplikowane niż zwykłe If This Then That, ale już If This Meets Criteria Then That.

Jeżeli napisałem jakieś głupoty, to tylko z mojej głupoty, więc nie przejmujcie się.

1lajk

Zrobiłem pierwszy krok i zapytałem o wszystkie itemy na danym endpoincie (linku, który się odpytuje) i dostaję zwrotkę, której struktura wygląda tak:

[
  {
    "id": 40233,
    "parent_id": 0,
   <...>
 },
"line_items": [
<...>
{"product_id": 35,
<...>
},

Gdzie <…> oznaczyłem rzeczy, które tam jeszcze są, ale nieistotne (duuuużo różnych parametrów), ale załóżmy, że chodzi właśnie o ten jeden konkretny product id - w jaki sposób w treści zapytania powiedzieć mu: policz mnie ile razy we wszystkich itemach tego endpointu pojawia się “product_id”: 35.

To takie pytanie na start - później będziemy próbować kombinować z cross-filtrami (np. jest tam też parametr “data utworzenia”, którą chciałbym później zaprzęc do tego, żeby pytać o itemy, które mają product_id=35, ale spełniają warunek "utworzone nie dawniej niż dzisiaj o 14.

Mogę Ci apke w swift zrobić do odpytania tego i zrobienia tam co chcesz. Na iPhonixa zainstalujesz z Xcode’a :stuck_out_tongue:

To co potrzebujesz zrobić to odpytać API zgodnie z wymogami, czyli przygotować zapytanie do endpointa z określonymi parametrami. Nie wiem jakie tam jest zabezpieczenie, ale załóżmy, źe minimalne, więc API_KEY oraz parametry.

W odpowiedzi otrzymujesz JSONa - to co wkleiłeś to JSON, którego trzeba przetłumaczyć na obiekty które zawiera (sparsować - słowo klucz jeśli dalej chciałbyś eksplorować).

Sparsowany JSON będzie zawierał obiekt/-y. Np produkt_id wygląda jak Int, będący częścią tablicy w line items

Nie ma znaczenia język. Wybierz to co będzie dla Ciebie prostsze. Generalnie pythona powinieneś podołać z tutorialami w necie bez spiny. Jeśli nie python to może JavaScript bo łatwiej Ci to będzie zdeployować.

W każdym razie takie odpytanie - zgodnie z wymogami API - może się odbywać w pętli w dowolnym interwale. Filtry może można w zapytaniu ustawiać, jak nie to już lokalnie po sparsowaniu.

1lajk

Pewnie najszybciej by było zrobic plugin na event O stworzeniu wpisu w bazie o danym typie z jedną zmienną konfiguracyjną z adresem.
Z tego co widzę to funkcja save_post jest od tego

Wojtek, ale właściwie udało Ci się coś tam wykucować? Zrobiłeś to?

Nie, jednak odłożyłem - pojawiło się kilka innych ważniejszych rzeczy i olałem, ale mejbi kiedyś do tego wrócę! :smiley:

1lajk

no ja pomóc mogę jak coś, ale to nie też na tym powinno polegać, że ktoś zrobi za Ciebie :slight_smile: chyba, że chcesz, aby Ci ktoś wyklikał to co innego, ale jak chcesz pokucować to chętnie dam wskazówki jakieś :slight_smile:

2lajki

Jak temat wróci to zobaczymy czy będę chciał sam, czy po prostu to zrobić. :smiley: Ale potwierdzam - im więcej zrobi się samemu tym człowiek więcej rozumie i później łatwiej zrobić coś podobnego. :wink:

Jak to nie będzie duże to mogę Ci pewnie napisać hobbystyczne. Jak duże to na pewno nie chciałbym kasy, a z kolei Ty nie chciałbyś nie płacić, więc ewentualnie mogę kogoś polecić jak nie znajdziesz racjonalnego wykonawcy bo tu ceny mogą być czasem kosmiczne.

Jak chcesz sam to beam me up Scotty…

1lajk

UWAGA - poradziłem sobie z problemem. :slight_smile:

Po pierwsze - przestudiowałem sobie bardziej dokładnie dokumentację REST Api dla WooCommerce (z którego chciałem zaciągać dane) i okazało się, że mogę częściowo obejść kwestię przeliczania danych, bo wśród tzw. endpointów (po prostu URL na którym leżą sobie różne dane) jest całe drzewko “reports”, w którym dane które mnie interesują się znajdują.

Żeby jednak je odpowiednio zaciągnąć - potrzebujemy jakiejś aplikacji / miejsca które się tym zajmie, więc wpadłem na pomysł wykorzystania Google Sheets i dodatkowego skryptu ImportJSON. Obsługa jest banalnie prosta - klikasz w Sheets na “Narzędzia” -> “Edytor skryptów”. W nowo otwartym oknie po prostu zaznaczasz cały kod i w jego miejsce wklejasz po prostu kod z GitHuba (TEN). Zapisujesz go i zamykasz okienko wracając do Sheetsów. :slight_smile:

Teraz trzeba w jednej z komórek wpisać formułę
=ImportJSONBasicAuth("https://link/zktorego/zaciagasz/dane?dodatkoweParametry=CośTam&NaPrzykładJeszczeJedenParametr=CośTam;"TutajWklejaszKluczUsera";"TutajWklejaszKlucz/HasłoUsera")

Link z endpointem wynika z dokumentacji API WooCommerce.

Przykładowo - żeby otrzymać tzw. “raport sprzedaży” to wykorzystujemy endoint: https://adressklepu.com/wp-json/wc/v3/reports/sales

A żeby go ograniczyć do danych z przykładowo całego lipca, wystarczy, że do endpointu dopiszemy parametry (zgodne znowu z tym jakie możliwości daje samo API):
https://adressklepu.com/wp-json/wc/v3/reports/sales?date_min=2019-07-01&period=month

Jeżeli chodzi o klucze (user/hasło) dostępowe to generuje się je już z poziomu Wordpressa w zaawansowanych ustawieniach WooCommerce.

Do tego - w Google Sheets dzięki tej nowej formule (skryptowi ImportJSON) dane zaciągane przez API nie są zwykłym ciągiem znaków, a ładnie układają się w tabelę, więc później można z nimi zrobić co się chce.

Co do kwestii odpytywania co jakiś czas - temat też rozwiązują Google Sheets, bo zapytanie jest generowane za każdym razem kiedy otwieram ten Arkusz (akurat to na moje potrzeby wystarczy w zupełności, bo za każdym otwarciem mam po prostu aktualne dane!).

Podsumowując - jestem już odrobinę mądrzejszy w temacie - odblokował mnie pomysł wykorzystania Google Sheets i każdemu kto zaczyna od zera chyba bym poradził właśnie Arkusze Googlowe. :slight_smile:

EDIT: w formule jest ImportJSONBasicAuth, a nie zwykły ImportJSON, bo akurat API WooCommerce wymaga autentykacji (niektóre, np. otwarte dane pogodowe nie wymagają logowania żadnego), dlatego trzeba tam podać dodatkowo klucze. Ale w ramach jednego skryptu ImportJSON jest kilka formuł do wykorzystania, m.in. taka, która pozwala na prostą autentykację, co ratuje dupkę. :slight_smile:

5lajków

Dobrze, że się nie poddałeś i usiadłeś do tematu, a jak sam opowiadałeś, nie było to łatwe :smiley:

2lajki

Jeszcze jeden update zrobię, A CO! :smiley:

Przypomniało mi się, że kiedyś sam sobie zrobiłem skrót (Apple Shortcut w sensie), który robił podobną rzecz, ale korzystał z nieco innego API - ale zadanie było proste - zapytaj konkretny link o dane, pobierz dane, zagłębiając się troszkę w drzewo odpowiedzi. Pokaż te dane. Koniec.

Okazało się, że właściwie to jest dość proste i dzisiaj spróbowałem sobie zrobić dokładnie to samo z tym kejsem, który opisałem powyżej. Działa. :slight_smile:

Myślę, że do Skrótów powinniśmy zrobić w ogóle oddzielny ogromny temat kiedyś, ale opiszę jak to wygląda teraz:

  1. Pierwszy klocek to [URL] - tu wklejamy cały link, który będziemy pytać. Musi mieć on tylko lekko zmodyfikowaną strukturę, bo żeby dokonać autentykacji z wykorzystaniem tylko zapytania http wystarczy dodać mu oba klucze w linku w taki sposób:

https://link/zktorego/zaciagasz/dane?consumer_key=TutajWklejaszKluczUsera&consumer_secret=TutajWklejaszKlucz/HasłoUsera&dodatkoweParametry=CośTam&NaPrzykładJeszczeJedenParametr=CośTam

[UWAGA] Jest wielce prawdopodobne, że podawanie kluczy w linku nie jest najbezpieczniejszą metodą - powinno tam się zostawić dziury na wklejenie kluczy podczas uruchamiania Skrótu, ale że to jest mój prywatny skrót i nie mam zamiaru się nim z nikim dzielić - zrobiłem tak, żeby działało. :wink:

  1. Pobierz zawartość URL - rozwijamy “więcej” i wybieramy metodę pobierania na GET

Możemy sobie na tym etapie odpalić skrót i w odpowiedzi dostaniemy zawartość tego URL - nie jest on za ładny, bo to niemal czysty tekst, ale można w nim poszukać tego co chcemy z niego wyciągnąć - zwykle poszczególne pozycje mają swoje nazwy i wartości.

  1. Pobierz Wartość dla nazwa_itemu_ktory_cie_interesuje w Zawartość URL

W tym punkcie ważne jest to w jakiej pozycji “drzewa” itemów jest ta, która nas interesuje. Bo jeżeli jest na górze - to nie ma problemu, wystarczy ten jeden krok, ale jeżeli mamy np. items - item1 - wartość, to musimy powtórzyć ten krok *3, zmieniając nazwa_itemu_ktory_cie_interesuje w pierwszym kroku na items, w drugim kroku na item1, a w trzecim kroku na wartość - każde sięgnięcie głębiej to jeden krok. Nie wiem, czy to dobrze wytłumaczyłem, ale mam nadzieję, że łapiecie. :smiley:

  1. Pokaż: Elo mordo Wartość ze słownika <- tyle jest tego co szukałeś!

Zapisujemy skrót, nadajemy mu nazwę - jak nazwa będzie po angielsku to mówiąc do Siri: “Hey Siri, nazwa skrótu” - odpali się skrót i Siri powie całą treść punktu 4, razem z wartością (jeżeli jest w miarę standardowa - u mnie akurat liczba).

To też pokazuje, że generalnie proste zapytania do API, niezależnie, czy otwartego, czy zamkniętego za kluczami rzeczywiście można robić za pośrednictwem skrótów + dalej można to rozbudowywać jak ktoś się zacznie bawić Skrótami. Ja nadal mam poczucie, że dopiero co dotykam powierzchni ich możliwości. :smiley:

W sumie chyba piszę to głównie dlatego, żeby mieć do czego wrócić, ale jeżeli ktoś się zainspiruje do odkrywania Skrótów na nowo dzięki temu to super! :slight_smile:

4lajki