Skip to content
This repository has been archived by the owner on Dec 28, 2021. It is now read-only.

API dell'app Trenitalia

Jacopo Jannone edited this page Sep 15, 2018 · 9 revisions

Nota bene: in tutte le richieste presentate qui bisogna avere cura di sostituire AppVersion con la versione dell'app che si sta usando e DeviceId con un UUID univoco da utilizzare in tutte le richieste a partire dall'autenticazione.

Autenticazione

Uno studio dettagliato sul processo di autenticazione può essere trovato nel post sul mio blog. Qui si riassume brevemente come procedere.

Prima richiesta non autenticata

POST /Trenitalia50/apps/services/api/Trenitalia/android/init HTTP/1.1
Content-type: application/x-www-form-urlencoded; charset=UTF-8
x-wl-app-version: 5.0.1.0004
Host: gw71.mplat.trenitalia.it:444

Risposta

{
    "challenges": {
        "wl_antiXSRFRealm": {
            "WL-Instance-Id": "e81721e39345450298539c176d"
        },
        "wl_deviceNoProvisioningRealm": {
            "token": "5f1aa92653944e668d1f79df88"
        }
    }
}

### Richiesta di autenticazione

POST /Trenitalia50/apps/services/api/Trenitalia/android/init HTTP/1.1
Content-type: application/x-www-form-urlencoded; charset=UTF-8
x-wl-app-version: 5.0.1.0004
Host: gw71.mplat.trenitalia.it:444
WL-Instance-Id: e81721e39345450298539c176d
Authorization: {"wl_deviceNoProvisioningRealm":{"ID":{"token":"5f1aa92653944e668d1f79df88","app":{"id":"Trenitalia","version":"5.0.1.0004"},"device":{"id":"8d593fde-ea26-4191-a487-23ac82a7c36c","os":"6.0.1","model":"Nexus 5","environment":"android"},"custom":{}}}}

Nota: preservare i cookie impostati durante la prima richiesta.

Successive richieste autenticate

POST /Trenitalia50/apps/services/api/Trenitalia/android/init HTTP/1.1
Content-type: application/x-www-form-urlencoded; charset=UTF-8
x-wl-app-version: 5.0.1.0004
Host: gw71.mplat.trenitalia.it:444
WL-Instance-Id: e81721e39345450298539c176d

Nota: preservare i cookie impostati durante la prima richiesta.

Informazioni generali

Tutte le richieste dell'API sono POST al seguente endpoint:

https://gw71.mplat.trenitalia.it:444/Trenitalia50/apps/services/api/Trenitalia/android/query

Il corpo della richiesta richiede tre parametri: adapter, procedure e parameters. Quest'ultimo è una stringa contenente dati in formato JSON. Le risposte sono file JSON puri o racchiusi in tag di tipo /*-secure-[payload]*/ con la seguente struttura:

{
    "statusCode": 200,
    "errors": [],
    "isSuccessful": true,
    "Envelope": {
        "Body": {
            "NOME_RISPOSTA": {
                "Body": {
                    "CORPO_RISPOSTA"
                }
                "AdditionalInformation": {
                    "nil": "true"
                }
            }
        },
        "Header": {
            "ResponseHeader": {
                "MessageInfo": {
                    "nil": "true"
                },
                "mustUnderstand": "1",
                "UnitOfWork": "101808532219417696"
            }
        }
    },
    "statusReason": "OK",
    "responseHeaders": {
        "Date": "Tue, 04 Sep 2018 15:56:23 GMT",
        "Content-Length": "113306",
        "Content-Type": "text\/xml; charset=utf-8",
        "Server": "Microsoft-IIS\/7.5",
        "X-Powered-By": "ASP.NET",
        "x-SCR-APM": "09"
    },
    "warnings": [],
    "responseTime": 211,
    "totalTime": 215,
    "info": []
}

La risposta in sé, quindi ciò che interessa, si trova in corrispondenza del placeholder "CORPO_RISPOSTA" alla riga 9.

Le date sono in formato 1970-01-01T12:00:00+02:00 (nell'ordine: anno, mese, giorno, ora, minuto, secondo, offset rispetto a UTC in ore e minuti), oppure talvolta senza l'offset rispetto a UTC; tutte le durate sono in formato ISO 8601. Il valore null in alcuni casi viene rappresentato come un dizionario {"nil": true}. Molto spesso, ma non sempre, gli interi sono passati sotto forma di stringa. Prestate attenzione agli esempi.

Ricerca stazioni

Parametri richiesta

  • adapter: StationsAdapter
  • procedure: GetStations
  • parameters:
[
  {
    "UnitOfWork": 0,
    "Language": "IT",
    "Credentials": null,
    "PlantId": "android",
    "PointOfSaleId": 3,
    "CredentialsAlias": null,
    "AppVersion": "5.0.1",
    "DeviceId": "8d593fde-ea26-4191-a487-23ac82a7c36c"
  },
  {
    "GetStationsRequest": {
      "Body": {
        "Name": "milano"
      }
    }
  },
  {
    "extractOnlyItalianStations": false
  }
]
  • Name è il nome (anche parziale) della stazione da cercare;
  • extractOnlyItalianStations determina se i risultati devono essere solo stazioni italiane o meno.

Corpo risposta (qui viene mostrato solo un risultato):

{
  "StationDetail": [
    {
      "name": "Milano Affori",
      "longitude": "9.165794",
      "stationcode": "830025005",
      "latitude": "45.518497",
      "favorite": 0,
      "railwaycode": "83",
      "zoomlevel": 1
    }
  ]
}

Ricerca soluzioni di viaggio

Parametri richiesta

  • adapter: SearchAndBuyAdapter
  • procedure: SearchTravels
  • paramters:
[
  {
    "UnitOfWork": 0,
    "Language": "IT",
    "Credentials": null,
    "PlantId": "android",
    "PointOfSaleId": 3,
    "CredentialsAlias": null,
    "AppVersion": "5.0.1",
    "DeviceId": "8d593fde-ea26-4191-a487-23ac82a7c36c"
  },
  {
    "SearchTravelsRequest": {
      "Body": {
        "PagingCriteria": {
          "StartIndex": 0,
          "EndIndex": 9,
          "SortDirection": null
        },
        "OriginStationId": "830008409",
        "DestinationStationId": "830000219",
        "DepartureDateTimeRange": {
          "Start": "2018-09-05T05:00:00+02:00",
          "End": null
        },
        "ArrivalDateTimeRange": null,
        "ReturnDateTimeRange": null,
        "ArrivalReturnDateTimeRange": null,
        "IsReturn": false,
        "Passengers": {
          "PassengerQuantity": [
            {
              "Type": "Adult",
              "Quantity": 1
            },
            {
              "Type": "Child",
              "Quantity": 0
            }
          ]
        },
        "FidelityCardCode": null,
        "PostSaleCriteria": null,
        "TrainType": "All",
        "MaxNumberOfChanges": "99",
        "CompatibleFares": {
          "OutwardSelectedFare": {
            "ServiceId": "30005"
          }
        }
      }
    }
  }
]
  • StartIndex e EndIndex indicano la porzione di soluzioni da mostrare. La prima ha indice 0;
  • OriginStationId è il codice della stazione di partenza;
  • DestinationStationId è il codice della stazione di arrivo;
  • DepartureDateTimeRange indica l'intervallo di date di partenza per cui mostrare soluzioni. Il parametro End è sempre null e viene ignorato;
  • ArrivalDateTimeRange indica l'intervallo di date di arrivo per cui mostrare soluzioni. Valgono le stesse considerazioni fatte sopra;
  • ReturnDateTimeRange: come DepartureDateTimeRange ma per il viaggio di ritorno;
  • ArrivalReturnDateTimeRange: come ArrivalDateTimeRange ma per il viaggio di ritorno;
  • IsReturn indica se si sta cercando il viaggio di ritorno (come parte di un viaggio andata e ritorno);
  • PassengerQuantity indica la quantità di ogni tipologia di passeggero (adulti e bambini);
  • TrainType indica il tipo di treno da cercare; può essere null per tutti i tipi di treno, Frecce, o Regional per cercare solo treni regionali;
  • MaxNumberOfChanges indica il massimo numero di cambi. Se non si imposta un limite, l'app invia il valore di default "99";
  • CompatibleFares è presente solo se si sta cercando il viaggio di ritorno. Contiene il codice della soluzione selezionata per il viaggio di andata in modo da mostrare solo soluzioni compatibili (a livello tariffario).

Corpo risposta (qui viene mostrato solo un risultato):

Informazioni su un treno in tempo reale

Parametri richiesta

  • adapter: TrainRealtimeInfoAdapter
  • procedure: TrainRealtimeInfo
  • parameters:
[
  {
    "UnitOfWork": 0,
    "Language": "IT",
    "Credentials": null,
    "PlantId": "android",
    "PointOfSaleId": 3,
    "CredentialsAlias": null,
    "AppVersion": "5.0.1",
    "DeviceId": "8d593fde-ea26-4191-a487-23ac82a7c36c"
  },
  {
    "TrainRealtimeInfoRequest": {
      "Body": {
        "Train": {
          "Number": "9600",
          "CategoryCode": null,
          "CategoryName": null,
          "Notifiable": null
        },
        "DepartureStationId": null,
        "DepartureDate": null,
        "ArrivalStationId": null
      }
    }
  }
]
  • Number è il numero del treno da cercare, come stringa;
  • ArrivalStationId è il codice della stazione di arrivo, facoltativo;
  • DepartureStationId è il codice della stazione di partenza, facoltativo;
  • DepartureDate è la data di partenza, facoltativa.

Gli altri parametri sembrano essere sempre ignorati.

Corpo risposta (qui viene mostrata solo una fermata):

{
  "RealtimeTrainInfoWithStops": {
    "ScheduledTrack": "9",
    "Train": {
      "CategoryCode": "FR",
      "CategoryName": "FRECCIAROSSA",
      "Number": "9600",
      "Notifiable": true
    },
    "ActualTrack": "",
    "DepartureStation": {
      "Name": "ROMA TERMINI",
      "Latitude": "41.900503",
      "Longitude": "12.502027",
      "Id": "8409"
    },
    "ScheduledArrival": "2018-09-05T10:05:00+02:00",
    "LastReachedCheckPoint": "TORINO PORTA NUOVA",
    "ScheduledDeparture": "2018-09-05T06:00:00+02:00",
    "ScheduledDuration": "PT4H5M",
    "Stops": {
      "RealtimeTrainStop": [
        {
          "Station": {
            "Name": "ROMA TERMINI",
            "Latitude": "41.900503",
            "Longitude": "12.502027",
            "Id": "8409"
          },
          "Reached": true,
          "StopType": "Departure",
          "ActualInfo": {
            "Departure": "2018-09-05T06:02:00+02:00",
            "Arrival": {
              "nil": true
            },
            "Track": ""
          },
          "ScheduledInfo": {
            "Departure": "2018-09-05T06:00:00+02:00",
            "Arrival": {
              "nil": true
            },
            "Track": "9"
          }
        }
      ]
    },
    "ArrivalStation": {
      "Name": "TORINO PORTA NUOVA",
      "Latitude": "45.060971",
      "Longitude": "7.677471",
      "Id": "219"
    },
    "LastReachedCheckPointBase": {
      "nil": true
    },
    "Delay": "PT12M",
    "LastCheckPointTime": "2018-09-05T10:17:00",
    "IsViaggiaTreno": true
  }
}
  • se la ricerca trova più di un treno, RealtimeTrainInfoWithStops identifica una lista con le informazioni di ogni treno; altrimenti identifica direttamente le informazioni dell'unico treno trovato (non una lista con un solo elemento);
  • se il treno non è valido o se è stato cancellato, il parametro generale statusCode è 500 e statusReason spiega il motivo dell'errore, tuttavia il codice di risposta HTTP è sempre 200 OK;
  • le fermate possono essere di quattro tipi Departure, Arrival, Stop, Transit. L'ultimo caso indica che il treno non ferma nella località in questione, ma ci transita solamente. Le fermate di tipo Transit normalmente sono nascoste nell'interfaccia dell'applicazione;
  • i dati mostrati sono, naturalmente, gli stessi di ViaggiaTreno. Si tratta di un sistema più affidabile, tuttavia le informazioni sono molto meno dettagliate.

Gli altri endpoint

Qui si trova una lista degli altri endpoint usati dall'applicazione, che non sono stati approfonditi perché poco utili o interessanti. I nomi sono abbastanza chiari e dovrebbero lasciar intuire a grandi linee il loro scopo.

  • /Trenitalia50/authorization/v1/clients/instance
  • /Trenitalia50/authorization/v1/authorization
  • /Trenitalia50/apps/services/api/Trenitalia/android/notifications
  • /Trenitalia50/apps/services/api/Trenitalia/android/login
  • /Trenitalia50/apps/services/api/Trenitalia/android/heartbeat
  • /Trenitalia50/apps/services/api/Trenitalia/android/friendlyname
  • /Trenitalia50/apps/services/configprofile
  • /Trenitalia50/apps/services/loguploader
  • /Trenitalia50/apps/services/j_security_check
  • /Trenitalia50/invoke
Clone this wiki locally