constructRequest method

Future constructRequest(
  1. String endpoint, {
  2. Map<String, dynamic> body = const {},
  3. Map<String, String> query = const {},
})

Constructs and performs an API request to the specified endpoint with optional body and query parameters.

Implementation

Future<dynamic> constructRequest(
  String endpoint, {
  Map<String, dynamic> body = const {},
  Map<String, String> query = const {},
}) async {
  final headers = <String, String>{
    ...dio.options.headers,
    "x-origin": "https://music.youtube.com/",
    "X-Goog-Visitor-Id": config['VISITOR_DATA'] ?? "",
    "X-YouTube-Client-Name": config['INNERTUBE_CONTEXT_CLIENT_NAME'] ?? '',
    "X-YouTube-Client-Version": config['INNERTUBE_CLIENT_VERSION'] ?? '',
    "X-YouTube-Device": config['DEVICE'] ?? '',
    "X-YouTube-Page-CL": config['PAGE_CL'] ?? '',
    "X-YouTube-Page-Label": config['PAGE_BUILD_LABEL'] ?? '',
    "X-YouTube-Utc-Offset":
        (-DateTime.now().timeZoneOffset.inMinutes).toString(),
    "X-YouTube-Time-Zone": DateTime.now().timeZoneName,
  };

  final searchParams = Uri.parse("?").replace(queryParameters: {
    ...query,
    "alt": "json",
    "key": config['INNERTUBE_API_KEY'],
  });

  try {
    final response = await dio.post(
      "youtubei/${config['INNERTUBE_API_VERSION']}/$endpoint${searchParams.toString()}",
      data: {
        "context": {
          "capabilities": {},
          "client": {
            "clientName": config['INNERTUBE_CLIENT_NAME'],
            "clientVersion": config['INNERTUBE_CLIENT_VERSION'],
            "experimentIds": [],
            "experimentsToken": "",
            "gl": config['GL'],
            "hl": config['HL'],
            "locationInfo": {
              "locationPermissionAuthorizationStatus":
                  "LOCATION_PERMISSION_AUTHORIZATION_STATUS_UNSUPPORTED",
            },
            "musicAppInfo": {
              "musicActivityMasterSwitch":
                  "MUSIC_ACTIVITY_MASTER_SWITCH_INDETERMINATE",
              "musicLocationMasterSwitch":
                  "MUSIC_LOCATION_MASTER_SWITCH_INDETERMINATE",
              "pwaInstallabilityStatus": "PWA_INSTALLABILITY_STATUS_UNKNOWN",
            },
            "utcOffsetMinutes": -DateTime.now().timeZoneOffset.inMinutes,
          },
          "request": {
            "internalExperimentFlags": [
              {
                "key": "force_music_enable_outertube_tastebuilder_browse",
                "value": "true",
              },
              {
                "key": "force_music_enable_outertube_playlist_detail_browse",
                "value": "true",
              },
              {
                "key": "force_music_enable_outertube_search_suggestions",
                "value": "true",
              },
            ],
            "sessionIndex": {},
          },
          "user": {
            "enableSafetyMode": false,
          },
        },
        ...body,
      },
      options: Options(headers: headers),
    );
    final jsonData = response.data;

    if (jsonData.containsKey("responseContext")) {
      return jsonData;
    } else {
      return jsonData;
    }
  } on DioException catch (e) {
    print(
        'Failed to make request to ${e.requestOptions.uri} - ${e.response?.statusCode} - [${e.response?.data}]');
  }
}