request method

Future<Map<String, Object?>> request(
  1. RequestType type,
  2. String action, {
  3. dynamic data = '',
  4. String contentType = 'application/json',
  5. Map<String, Object?>? query,
})

Used for all Matrix json requests using the c2s API.

Throws: FormatException, MatrixException

You must first set this.homeserver and for some endpoints also this.accessToken before you can use this! For example to send a message to a Matrix room with the id '!fjd823j:example.com' you call:

final resp = await request(
  RequestType.PUT,
  '/r0/rooms/!fjd823j:example.com/send/m.room.message/$txnId',
  data: {
    'msgtype': 'm.text',
    'body': 'hello'
  }
 );

Implementation

Future<Map<String, Object?>> request(
  RequestType type,
  String action, {
  dynamic data = '',
  String contentType = 'application/json',
  Map<String, Object?>? query,
}) async {
  if (homeserver == null) {
    throw ('No homeserver specified.');
  }
  dynamic json;
  (data is! String) ? json = jsonEncode(data) : json = data;
  if (data is List<int> || action.startsWith('/media/v3/upload')) json = data;

  final url = homeserver!
      .resolveUri(Uri(path: '_matrix$action', queryParameters: query));

  final headers = <String, String>{};
  if (type == RequestType.PUT || type == RequestType.POST) {
    headers['Content-Type'] = contentType;
  }
  if (accessToken != null) {
    headers['Authorization'] = 'Bearer $accessToken';
  }

  late http.Response resp;
  Map<String, Object?>? jsonResp = <String, Object?>{};

  switch (type) {
    case RequestType.GET:
      resp = await httpClient.get(url, headers: headers);
      break;
    case RequestType.POST:
      resp = await httpClient.post(url, body: json, headers: headers);
      break;
    case RequestType.PUT:
      resp = await httpClient.put(url, body: json, headers: headers);
      break;
    case RequestType.DELETE:
      resp = await httpClient.delete(url, headers: headers);
      break;
  }
  var respBody = resp.body;
  try {
    respBody = utf8.decode(resp.bodyBytes);
  } catch (_) {
    // No-OP
  }
  if (resp.statusCode >= 500 && resp.statusCode < 600) {
    throw Exception(respBody);
  }
  var jsonString = String.fromCharCodes(respBody.runes);
  if (jsonString.startsWith('[') && jsonString.endsWith(']')) {
    jsonString = '{"chunk":$jsonString}';
  }
  jsonResp = jsonDecode(jsonString)
      as Map<String, Object?>?; // May throw FormatException

  if (resp.statusCode >= 400 && resp.statusCode < 500) {
    throw MatrixException(resp);
  }

  return jsonResp!;
}