Skip to content

Instantly share code, notes, and snippets.

@shaneosullivan
Last active January 11, 2021 22:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shaneosullivan/12d41c10f6ebf2aa07359d38fa0899a2 to your computer and use it in GitHub Desktop.
Save shaneosullivan/12d41c10f6ebf2aa07359d38fa0899a2 to your computer and use it in GitHub Desktop.
Example of signing a Cloudinary video upload request and uploading it from a browser
// Run in the browser
// This function takes "someId" as a parameter, as an example that you
// may want to link the video upload to some object in your database.
// This is of course totally optional.
function uploadVideo(
someId: number,
file: File,
listeners: {
onProgress: (perc: number) => void;
onComplete: (url: string) => void;
onError: (str: string) => void;
}
): () => void {
let cancelableXhr = null;
fetch("/api/signCloudinaryUpload", {
method: "POST",
cache: "no-cache",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
someId
}),
})
.then((res) => {
if (!res.ok) {
listeners.onError("Permission to upload denied");
} else {
return res.json();
}
})
.then((signatureInfo) => {
cancelableXhr = runUpload(
signatureInfo.cloud_name,
signatureInfo.api_key,
signatureInfo.signature,
signatureInfo.public_id,
signatureInfo.timestamp
);
});
function runUpload(cloudName, apiKey, signature, publicId, timestamp) {
const url = `https://api.cloudinary.com/v1_1/${cloudName}/upload`;
const xhr = new XMLHttpRequest();
const fd = new FormData();
xhr.open("POST", url, true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
listeners.onProgress(0);
// Update progress (can be used to show progress indicator)
xhr.upload.addEventListener("progress", function(e) {
const progress = Math.round((e.loaded * 100.0) / e.total);
listeners.onProgress(progress);
console.log(
`fileuploadprogress data.loaded: ${e.loaded}, data.total: ${e.total}`
);
});
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4 && xhr.status == 200) {
// File uploaded successfully
const response = JSON.parse(xhr.responseText);
console.log("response", response);
// Create a thumbnail of the uploaded image, with 150px width
listeners.onComplete(response.secure_url);
}
};
fd.append("api_key", apiKey);
fd.append("public_id", publicId);
fd.append("timestamp", timestamp);
fd.append("signature", signature);
fd.append("file", file);
xhr.send(fd);
}
return () => {
cancelableXhr && cancelableXhr.abort();
};
}
// Run on the server
import { v2 as cloudinary } from "cloudinary";
cloudinary.config({
cloud_name: "", // Your cloud name
api_key: "", // your api key
api_secret: "", // your api secret
});
function signCloudinaryRequest(publicId: string) {
const timestamp = Math.round(new Date().getTime() / 1000);
const apiSecret = (cloudinary.config("api_secret") as any) as string;
const signature = cloudinary.utils.api_sign_request(
{
timestamp,
public_id: publicId,
},
apiSecret
);
return {
api_key: (cloudinary.config("api_key") as any) as string,
signature,
cloud_name: (cloudinary.config("cloud_name") as any) as string,
timestamp,
};
}
function apiHandler(request, response) {
// This assumes that you have a bodyParser set up
const someId = request.body.someId;
const publicId = `${someId}/video`; // use whatever path you like
const signatureInfo = signCloudinaryRequest(publicId);
response.status(200);
response.json({
api_key: signatureInfo.api_key,
cloud_name: signatureInfo.cloud_name,
public_id: publicId,
signature: signatureInfo.signature,
timestamp: signatureInfo.timestamp,
});
response.end();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment