code: func (api *Client) UploadFileContext(ctx context.Context, params FileUploadParameters) (file *File, err error) {
  	// Test if user token is valid. This helps because client.Do doesn't like this for some reason. XXX: More
  	// investigation needed, but for now this will do.
  	_, err = api.AuthTest()
  	if err != nil {
  		return nil, err
  	}
  	if params.Filename == "" {
  		return nil, fmt.Errorf("files.upload: FileUploadParameters.Filename is mandatory")
  	}
  	response := &fileResponseFull{}
  	values := url.Values{
  		"token": {api.token},
  	}
  	if params.Filetype != "" {
  		values.Add("filetype", params.Filetype)
  	}
  	if params.Filename != "" {
  		values.Add("filename", params.Filename)
  	}
  	if params.Title != "" {
  		values.Add("title", params.Title)
  	}
  	if params.InitialComment != "" {
  		values.Add("initial_comment", params.InitialComment)
  	}
  	if params.ThreadTimestamp != "" {
  		values.Add("thread_ts", params.ThreadTimestamp)
  	}
  	if len(params.Channels) != 0 {
  		values.Add("channels", strings.Join(params.Channels, ","))
  	}
  	if params.Content != "" {
  		values.Add("content", params.Content)
  		err = api.postMethod(ctx, "files.upload", values, response)
  	} else if params.File != "" {
  		err = postLocalWithMultipartResponse(ctx, api.httpclient, api.endpoint+"files.upload", params.File, "file", values, response, api)
  	} else if params.Reader != nil {
  		err = postWithMultipartResponse(ctx, api.httpclient, api.endpoint+"files.upload", params.Filename, "file", values, params.Reader, response, api)
  	}
  	if err != nil {
  		return nil, err
  	}
  
  	return &response.File, response.Err()
  }
docs: // UploadFileContext uploads a file and setting a custom context