docs: def func(command, description, link, params_string, returns="On success, the sent Message is returned.", return_type="Message"):
      """
      Live template for pycharm:
  
      y = func(command="$cmd$", description="$desc$", link="$lnk$", params_string="$first_param$", returns="$returns$", return_type="$returntype$")
      """
      description_with_tabs = "\t\t" + description.strip().replace("\n", "\n\t\t")
      param_list_args = []
      param_list_kwargs = []
      args = []
      args2 = []
      kwargs = []
      kwargs2 = []
      asserts = []
      str_args = ""
      str_kwargs = ""
      param_strings = params_string.split("\n")
      for param in param_strings:
          assert_commands, assert_comments, param_name, param_type, table, non_buildin_type, param_name_input = parse_param_types(param)
          param_required = table[2].strip()
          param_needed = None
          if param_required == "Yes":
              param_needed = True
          elif param_required == "Optional":
              param_needed = False
          param_description = table[3].strip()
          if param_needed:
              param_list_args.append(Param(param_name, param_type,param_needed, param_description))
              args.append(param_name)
              args2.append("{param_name}={param_name}".format(param_name=param_name))
              str_args += '\t\t:param {key}: {descr}\n\t\t:type  {key}: {type}\n\n'.format(key=param_name, descr=param_description, type=param_type)
              if assert_commands:
                  asserts.append("assert({var} is not None)".format(var=param_name))
                  asserts.append("assert({ass})".format(ass=" or ".join(assert_commands)) + (("  # {comment}".format(comment=", ".join(assert_comments))) if assert_comments else ""))
          else:
              param_list_kwargs.append(Param(param_name, param_type,param_needed, param_description))
              kwargs.append("{param_name}=None".format(param_name=param_name))
              kwargs2.append("{param_name}={param_name}".format(param_name=param_name))
              str_kwargs += '\t\t:keyword {key}: {descr}\n\t\t:type    {key}: {type}\n\n'.format(key=param_name, descr=param_description, type=param_type)
              if assert_commands:
                  asserts.append("assert({var} is None or {ass})".format(var=param_name, ass=" or ".join(assert_commands)) + (("  # {comment}".format(comment=", ".join(assert_comments))) if assert_comments else ""))
      args.extend(kwargs)
      args2.extend(kwargs2)
      asserts_string = "\n\t\t" + "\n\t\t".join(asserts)
      text = ""
      if len(str_args)>0:
          text += '\n\t\tParameters:\n\n'
          text += str_args
      if len(str_kwargs)>0:
          text += '\n\t\tOptional keyword parameters:\n\n'
          text += str_kwargs
      do_args = ['"%s"' % command]
      do_args.extend(args2)
      result = '\tdef {funcname}(self, {params}):\n\t\t"""\n{description_with_tabs}\n\n\t\t{link}\n\n' \
             '{paramshit}\n' \
             '\t\tReturns:\n\n\t\t:return: {returns}\n\t\t:rtype:  {return_type}\n\t\t"""{asserts_with_tabs}\n\t\treturn self.do({do_args})\n\t# end def {funcname}'.format(
          funcname=convert_to_underscore(command),
          params=", ".join(args), description_with_tabs=description_with_tabs, link=link,
          returns=returns, return_type=return_type, command=command, do_args=", ".join(do_args),
          asserts_with_tabs=asserts_string,
          paramshit = text
      )
      result = result.replace("\t", "    ")
      return result