rockneurotiko/ex_gram

Multiform requests not working

alan-andrade opened this issue · 4 comments

I'm trying to upload a photo from a bot.

Code looks like:

ExGram.send_photo 6666666, "photo.jpg"

I receive the following error:

{:error,                                                                                                                                                                                              [243/1927]
 %ExGram.Error{
   code: :response_status_not_match,
   message: "{\"ok\":false,\"error_code\":400,\"description\":\"Bad Request: unsupported URL protocol\"}",
   metadata: nil
 }}

After some debugging, I realized the request isn't being multiformed properly.
I also saw this might be a known issue since some type validations have a"#TODO" note.

For quickfix I was able to work around it by modifying macros.ex ~LOC 382.

# Extract the value and part name (it can be from parameter or ops)
...
              {vn, partname} =
                case Enum.at(unquote(multi_full), 0) do
                  {v, p} -> {v, p}
                  keyw -> {ops[keyw], Atom.to_string(keyw)}
                end
                
              # Hack for now
               vn2 = {:file, vn}

              case vn2 do
                {:file, path} ->
                  # It's a file, let's build the multipart data for maxwell post
                  disposition = {"form-data", [{"name", partname}, {"filename", path}]}
                  # IO.puts("disposition: #{disposition}")
                  # File part
                  fpath = {:file, path, disposition, []}
...

Notice the vn2.

I'm just beginning with Elixir and I haven't figured out the best approach for this fix. Any ideas?

With that, you will have the problem when sending files as IDs instead of the file from your system (which you can do in telegram)

You can send a file from your file system with {:file, path}

ExGram.send_photo 6666666, {:file, "photo.jpg"}

I get an error with this API. 🤔 Somthing isn't matching

** (FunctionClauseError) no function clause matching in :filename.do_flatten/2

    The following arguments were given to :filename.do_flatten/2:

        # 1
        {:file, "/tmp/temp.jpg"}

        # 2
        []

    (stdlib) filename.erl:992: :filename.do_flatten/2
    (stdlib) filename.erl:190: :filename.basename/1
    (maxwell) lib/maxwell/multipart.ex:291: Maxwell.Multipart.mp_file_header/2
    (maxwell) lib/maxwell/multipart.ex:176: anonymous fn/3 in Maxwell.Multipart.len_mp_stream/2
    (elixir) lib/enum.ex:1948: Enum."-reduce/3-lists^foldl/2-0-"/3
    (maxwell) lib/maxwell/multipart.ex:167: Maxwell.Multipart.len_mp_stream/2
    (maxwell) lib/maxwell/adapter/util.ex:98: Maxwell.Adapter.Util.multipart_encode/2
    (maxwell) lib/maxwell/adapter/adapter.ex:75: Maxwell.Adapter.Hackney.send_multipart/1

@alan-andrade
It is working fine in our case. May be you are passing the arguments in a wrong way.
Can you post a LOC How you are using exactly like in your code.

Is this how you are doing?

ExGram.send_photo(chat_id, {:file, "files/images/welcome.png"})

@alan-andrade remember to revert the changes that you made 😄

With your changes, all the files were wrapped inside a {:file, path} tuple, so with your changes now you have {:file, {:file, path}} which is causing that problem.

Basically, if you want to send a file from your system, you use {:file, path}, if you want to send a file ID you just use the ID.