invokeRaw method

Future<Map> invokeRaw({
  1. required Map parameters,
  2. required int clientId,
  3. required bool isVoid,
  4. required Duration delayDuration,
  5. required Duration invokeTimeOut,
  6. required Duration functionTimeOut,
  7. required bool isUseCache,
  8. required Duration durationCacheExpire,
  9. required String extra,
  10. required bool isAutoGetChat,
  11. required bool isInvokeThrowOnError,
  12. required FutureOr<String> onGenerateExtraInvoke(
    1. int client_id,
    2. TdlibBase libTdJson
    )?,
  13. required FutureOr<Map> onGetInvokeData(
    1. String extra,
    2. int client_id,
    3. TdlibBase libTdJson
    )?,
})

call api latest Tdlib-Methods example:

tg.invoke(
 "getChat",
 parameters: {
   "chat_id": 0,
 },
 clientId: tg.client_id,
);

Implementation

Future<Map> invokeRaw({
  required Map parameters,
  required int clientId,
  required bool isVoid,
  required Duration delayDuration,
  required Duration invokeTimeOut,
  required Duration functionTimeOut,
  required bool isUseCache,
  required Duration durationCacheExpire,
  required String extra,
  required bool isAutoGetChat,
  required bool isInvokeThrowOnError,
  required FutureOr<String> Function(int client_id, TdlibBase libTdJson)?
      onGenerateExtraInvoke,
  required FutureOr<Map> Function(
          String extra, int client_id, TdlibBase libTdJson)?
      onGetInvokeData,
}) async {
  final Completer<Map> completer = Completer<Map>();
  late final EventEmitterListener listener;

  final Map result = await Future(() async {
    try {
      if (isVoid == false) {
        if (task_count >= task_max_count) {
          while (true) {
            await Future.delayed(Duration(microseconds: 1));
            if (task_count < task_min_cooldown) {
              break;
            }
          }
        }
      }
      final String extra_id = await () async {
        if (parameters["@extra"] is String == false) {
          if (extra.isEmpty) {
            parameters["@extra"] = extra;
          } else if (onGenerateExtraInvoke != null) {
            parameters["@extra"] =
                await onGenerateExtraInvoke(clientId, this);
          } else {
            parameters["@extra"] = generateUuid(15);
          }
        }
        final String extra_procces = parameters["@extra"];
        if (extra_procces.isEmpty) {
          parameters["@extra"] = generateUuid(15);
          return parameters["@extra"];
        }
        return extra_procces;
      }();

      if (isAutoGetChat &&
          RegExp(r"^(sendMessage|getChatMember)$", caseSensitive: false)
              .hashData(parameters["@type"])) {
        if (parameters["chat_id"] is int) {
          td_send(clientId, {
            "@type": "getChat",
            "chat_id": parameters["chat_id"],
          });
        }
        if (parameters["user_id"] is int) {
          td_send(clientId, {
            "@type": "getUser",
            "user_id": parameters["user_id"],
          });
        }
      }
      if (isVoid) {
        td_send(
          clientId,
          parameters,
        );
        return {
          "@type": "ok",
          "@extra": extra,
        };
      }
      if (onGetInvokeData != null) {
        td_send(
          clientId,
          parameters,
        );
        return await onGetInvokeData(extra_id, clientId, this);
      }
      listener = on(event_invoke, (UpdateTd update) async {
        try {
          if (update.client_id == clientId) {
            final Map updateOrigin = update.raw;
            if (updateOrigin["@extra"] == extra_id) {
              updateOrigin.remove("@extra");
              updateOrigin.remove("@client_id");
              completer.complete(updateOrigin);
            }
          }
        } catch (e) {
          completer.complete({"@type": "error"});
          // result["@type"] = "error";
        }
      });
      td_send(
        clientId,
        parameters,
      );
      task_increase();
      final Map result = await completer.future.timeout(
        invokeTimeOut,
        onTimeout: () {
          return {"@type": "error", "message": "timeout"};
        },
      );
      return result;
    } catch (e) {
      if (e is Map) {
        return e;
      }
      return {
        "@type": "error",
        "message": "crash",
      };
    }
  }).timeout(
    functionTimeOut,
    onTimeout: () {
      return {
        "@type": "error",
        "message": "timeout",
      };
    },
  );
  task_decrease();
  try {
    completer.complete({});
  } catch (e) {}
  try {
    event_emitter.off(listener: listener);
  } catch (e) {}

  if (result.isEmpty ||
      result["@type"] is String == false ||
      result["@type"] == "error") {
    if (isInvokeThrowOnError) {
      result["@type"] = "error";
      throw result;
    }
  }
  return result;
}