Google Drive Upload
Finally I got the file upload to work as expected. I’ve used swagger as described in previous posts, but for some reason it won’t work like that. I will now list the changes I hade to make in order for it to work.
Drive Connection
First I had to change the default adapter for Tesla
, Elixir package for http requests. First error I got was with httpc
package.
defmodule Drive.Connection do
@moduledoc """
Handle Tesla connections for Drive.
"""
use Tesla
adapter :hackney
You need to change the the host url to www.googleapis.com/upload/
for it to be able to upload. After you start the server and start up the upload with multipart/form-data
, if host stays without upload you will get the wrongUrlUpload
error, and it will tell you to re-send the request to supplied url. Just listen to the console and you are closer to Drive upload.
swagger: '2.0'
schemes:
- https
host: www.googleapis.com/upload/
basePath: drive/v3
info:
contact:
name: Google
Open API Yaml
Yaml file used to generate the api client had File
model. That was the problem because it interfered with built-in model for File in Java. So I had to change the name to DriveFile. After generating the client stub you will see the Elixir struct create with the name DriveFile.
Facade
To call the drive API I had to create a facade (I will probably rename it to service don’t judge my naming!). Here is the snippet to call the Elixir Drive Client.
# drive_facade.ex
file = %Drive.Model.DriveFile{
description: "Hello",
originalFilename: filename,
mimeType: "application/octet-stream",
name: filename
}
keyword_list = [{:uploadType, "multipart"}]
case drive_files_create(driveClient, file, filename, keyword_list) do
{:ok, resp} ->
resp |> inspect |> Logger.debug
{:error, error} ->
error |> inspect |> Logger.error
end
{:error, file_error} ->
file_error |> inspect |> Logger.error
# drive_files_create function
%{}
|> method(:post)
|> url("/files")
# it is important to get the resource struct first
|> add_param(:body, :"resource", body)
# after that comes the file
|> add_param(:file, :"media", file)
|> add_optional_params(optional_params, opts)
|> Enum.into([])
|> (&Connection.request(connection, &1)).()
|> decode(Drive.Model.DriveFile)
Generation of file part is not dynamic, I added that line directly into the client. What you need to do also is to change %Drive.Model.DriveFile{}
to Drive.Model.DriveFile
.
That’s all for now! More updates coming soon!