.config
index.js
Packager files
package-lock.json
package.json
Config files
.replit
replit.nix
const http = require('http');
const base64 = require('base-64');
const vodUrl = 'https://vod.api.video/vod/';
const wsUrl = 'https://ws.api.video/videos/';
const apiKey = process.env['apiKey'];
// 1 - First create a server that will accept GET requests, with id as query parameter
const server = http.createServer(async (req, res) => {
const videoList = await getVideoList();
const html = await videoList.generateFinalHTML()
res.write(html);
});
server.listen(3000);
console.log('Node.js web server at port 3000 is running..')
// 2 - Create a handler function for the requests to api.video endpoints with the basic auth
const apiVideoReq = async (url) => {
const headers = new Headers();
headers.append('Authorization', 'Basic' + base64.encode(apiKey + ":"));
const response = await fetch(url, { headers });
return {
httpRawResponse: response,
getJsonResponse: async () => {
if (response.status === 200) {
const data = await response.json();
return data;
} else {
throw new Error(`unbale to prase JSON, got response status: ${response.status}`)
}
}
}
}
// 3 - get the list of videos from the api
const getVideoList = async () => {
const apiResponse = await apiVideoReq(wsUrl);
const videoList = await apiResponse.getJsonResponse();
return {
data: videoList,
// 4 - get all private videos from the video list
async getPrivateVideos() {
let privateVideosList = []
for (const videoListItem of videoList.data) {
if (videoListItem.public === false) {
await privateVideosList.push({
videoId: videoListItem.videoId,
videoUrl: videoListItem.assets.player,
thumbnailUrl: videoListItem.assets.thumbnail,
});
}
}
return privateVideosList;
},
// 5 - extract the private token from private video assets and map it to the each video asset
async mapPrivateTokenToAssets() {
const privateVideosList = await this.getPrivateVideos()
const regexFindPrvtToken = /(?<=token=).*$/
let assetsListWithPrivateToken = []
for (const privateVideoItems of privateVideosList) {
const privateTokenMatchRes = privateVideoItems.videoUrl.match(regexFindPrvtToken);
if (privateTokenMatchRes.length > 0) {
await assetsListWithPrivateToken.push({
privateToken: privateTokenMatchRes[0],
...privateVideoItems,
})
} else {
throw new Error(`Unable to find the private token for asset url: ${privateVideoItems.videoUrl}`)
}
}
return assetsListWithPrivateToken;
},
// 6 - create session tokens and add it to the assets
async mapSessionTokensToAssets() {
let assetsWithSessionTokens = []
const assetsListWithPrivateToken = await this.mapPrivateTokenToAssets()
for (const privateAssetItem of assetsListWithPrivateToken) {
const sessionUrlWithVideoIdAndToken = `${vodUrl}${privateAssetItem.videoId}/token/${privateAssetItem.privateToken}/session`
const res = await apiVideoReq(sessionUrlWithVideoIdAndToken);
const data = await res.getJsonResponse(res);
await assetsWithSessionTokens.push({
sessionToken: data.session_token,
...privateAssetItem,
})
}
return assetsWithSessionTokens;
},
// 7 - generate img and a href tags with the video url as href and thumbnail as img
async generateImgHrefTags() {
let imgTags = "";
const assestWithSessionToken = await this.mapSessionTokensToAssets();
for (const assetWithSessionTokenItem of assestWithSessionToken) {
imgTags = await imgTags.concat(`<a href=${assetWithSessionTokenItem.videoUrl}&avh=${assetWithSessionTokenItem.sessionToken}><img src=${assetWithSessionTokenItem.thumbnailUrl}?avh=${assetWithSessionTokenItem.sessionToken} alt="HTML tutorial" style="width:150px;height:150px;"></a>`)
}
return imgTags
},
// 8 - generate the final url that will be passed to the response
async generateFinalHTML() {
const imgTags = await this.generateImgHrefTags();
return `<html><head></div><div>${imgTags}</div><html>`
}
};
}