require 'net/http'
require 'uri'
require 'json'
ENDPOINT = URI('https://demarche.numerique.gouv.fr/api/v2/graphql')
### that's the GraphQL part.
# We store the query in a flat file because it's easier to read
def query
File.read("getDemarche.listOnlyFilesUrl.graphql")
end
### that's the HTTP part
# open an http connexion to our GraphQL endpoint
def open_http_connection
http = Net::HTTP.new(ENDPOINT.host, ENDPOINT.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http
end
# the headers of our http query, include auth
def request_headers
{
"Content-Type" => "application/json",
"Authorization" => "Bearer #{ENV['API_TOKEN']}"
}
end
# given an http connexion, request the API for page
def request_page(http)
# the data of our query
data = {
"query" => query,
"operationName" => "getDemarche",
"variables" => {
"demarcheNumber": ENV['DEMARCHE_NUMBER'].to_i,
"first": 100
}
}
req = Net::HTTP::Post.new(ENDPOINT, request_headers)
req.body = data.to_json
response = http.request(req)
data = JSON.parse(response.body)
data
end
http = open_http_connection
# check if we persisted a cursor so we continue polling
data = request_page(http)
dossiers = data.dig('data', 'demarche', 'dossiers', 'nodes')
puts "Info: fetched dossiers ids: #{dossiers.map{ _1['number'] }.join(', ')}"
all_champs = dossiers.flat_map { |dossier| dossier['champs'] }
all_champs_pj = all_champs.filter { |champ| champ['files'] }
all_url_to_download = all_champs_pj.flat_map { |pj| pj['files'].map{ |file| file['url'] } }
puts "Info: now you can download each of those url: #{all_url_to_download.join(', ')}"