-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #74 from suryavaddiraju/devv
- v3.0.5
- Loading branch information
Showing
5 changed files
with
239 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,6 +72,30 @@ console.log(response); | |
- viu | ||
- the path to viu folder, if it doesnot work it will fall back to auto download | ||
- if it not works it throws an error | ||
- gcloud | ||
- This params can be `JSON String || Javascript Object || JSON File Buffer` | ||
- Google Cloud Service Account Credentials having permission of `serviceusage.services.use` | ||
- if this parameter is present we won't use viu for that process | ||
- `Note: This service is chargeable by Google and follow their terms and conditions` | ||
- To try this use below steps | ||
1. Create a Google Cloud account (Skip this step if you already have a Google Cloud account). | ||
2. Create a new, separate project. | ||
3. In the newly created project: | ||
- Search for `IAM & Admin` in the Google Cloud Console. | ||
- Go to `Roles` under IAM. | ||
4. Create a new role: | ||
- Set the title, description, and ID of your choice. | ||
- Set the Role Launch Stage to `General Availability`. | ||
5. Add the `serviceusage.services.use` permission to the role and click **Create**. | ||
6. Create a A New Service Account within IAM & Admin Page In `Service account details` - Give a Name, id, description of your choice and then in | ||
- `Service account details` - Give a Name, id, description of your choice | ||
- `Grant this service account access to project` - Attach the role that you created in previous step by searching your given name | ||
- `Grant users access to this service account (optional)` - Leave Empty | ||
- Then Click **Done** | ||
7. Go To service Accounts List of your project and Click on the email that you created in previous step download and Go to `Keys`and then `Create New Key - JSON`. You will get a json file in your browser downloads - `Keep this JSON` | ||
8. Search for `Cloud Vision API` in the Google Cloud Console and `Enable` it (Ignore, if its not already enabled) | ||
|
||
|
||
|
||
The example input is as follows | ||
|
||
|
@@ -81,6 +105,19 @@ const irctc = new IRCTC( | |
"userID":"XXXXXX", | ||
"password":"XXXXXXXXX", | ||
"viu":"./some/loaction/to/file.exe | ./some/loaction/to/file" // Optional | ||
"gcloud":{ | ||
"type": "service_account", | ||
"project_id": "vision-api", | ||
"private_key_id": "b0357d061ce2c96737d96c2", | ||
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqdyztLFNG\n-----END PRIVATE KEY-----\n", | ||
"client_email": "[email protected]", | ||
"client_id": "12345678901234567", | ||
"auth_uri": "https://accounts.google.com/o/oauth2/auth", | ||
"token_uri": "https://oauth2.googleapis.com/token", | ||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", | ||
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/default%40vision-api.iam.gserviceaccount.com", | ||
"universe_domain": "googleapis.com" | ||
} | ||
}); | ||
``` | ||
|
||
|
@@ -89,6 +126,12 @@ const irctc = new IRCTC( | |
|
||
`book` function in IRCTC class takes input as a javascript object, where they are explained below | ||
|
||
``` | ||
Note: | ||
for book_input function, there are a set of mandatory keys and a set of optional keys. Optional Keys means they're not compulsory to be passed. | ||
``` | ||
|
||
- `Mandatory Keys` | ||
- payment | ||
- for UPI payment | ||
|
@@ -174,8 +217,10 @@ const irctc = new IRCTC( | |
- Must be a string and should match the with the list of existing station code names | ||
- Must be short code of the station from where you are boarding | ||
- The Train must pass by and have a stop at this station | ||
-gst | ||
- board is the station where the passenger will be actually catching the train. this should not be confused with the mandatory from parameter which is a param for defining the starting point for the ticket. for eg. the passenger may book a train ticket from DEL to MUM, but he may prefer to join the journey at any intermediate station like AGC. | ||
- gst | ||
- Must be a string and it must be the 17 digit GSTIN number | ||
- This param is not necessary unless you are a business owner and want to claim the gst later. | ||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
import { createSign } from "node:crypto"; | ||
import { readFileSync } from "node:fs"; | ||
import { request } from "node:https"; | ||
import { URLSearchParams } from "node:url"; | ||
|
||
async function checker(service_account,params){ | ||
function isPlainObject(value) { | ||
return ( | ||
typeof value === 'object' && | ||
value !== null && | ||
!Buffer.isBuffer(value) && | ||
!Array.isArray(value) && | ||
value.constructor === Object | ||
); | ||
} | ||
|
||
function isgcloudservice(value){ | ||
return ( | ||
isPlainObject(value) && | ||
Object.prototype.hasOwnProperty.call(value,"type") && | ||
typeof value.type === "string" && | ||
value.type === "service_account" && | ||
Object.prototype.hasOwnProperty.call(value,"private_key_id") && | ||
Object.prototype.hasOwnProperty.call(value,"private_key") && | ||
typeof value.private_key === "string" && | ||
value.private_key.startsWith("-----BEGIN PRIVATE KEY-----") && | ||
( | ||
value.private_key.endsWith("-----END PRIVATE KEY-----") || | ||
value.private_key.endsWith("-----END PRIVATE KEY-----\n") | ||
) && | ||
Object.prototype.hasOwnProperty.call(value,"client_email") && | ||
typeof value.client_email === "string" && | ||
value.client_email.endsWith(".iam.gserviceaccount.com") && | ||
!Object.prototype.hasOwnProperty.call(value,"token") | ||
); | ||
} | ||
|
||
if (typeof service_account === "string"){ | ||
service_account = service_account.trim(); | ||
if (service_account.startsWith('{') && service_account.endsWith('}')){ | ||
service_account = JSON.parse(service_account); | ||
return await checker(service_account,params); | ||
}else{ | ||
throw new Error(`Invalid Parameter: value for gcloud key must be an object or valid JSON file content provided by google`); | ||
} | ||
} else if (typeof service_account === "object" && Buffer.isBuffer(service_account)){ | ||
return await checker(service_account.toString(),params); | ||
} else if (isgcloudservice(service_account)){ | ||
params.gcloud_project = service_account.project_id; | ||
return await generate_token(service_account); | ||
} else if (isPlainObject(service_account) && Object.prototype.hasOwnProperty.call(service_account,"token") && Object.prototype.hasOwnProperty.call(service_account,"project_id")){ | ||
params.gcloud_project = service_account.project_id; | ||
return service_account.token; | ||
}else{ | ||
throw new Error(`Invalid Parameter: value for gcloud key must be an object or valid JSON file content provided by google`); | ||
} | ||
} | ||
|
||
async function generate_token(service_account) { | ||
try { | ||
const header = Buffer.from( | ||
JSON.stringify({ | ||
alg: "RS256", | ||
typ: "JWT", | ||
kid: service_account.private_key_id, | ||
}) | ||
).toString("base64url"); | ||
const iat = Math.floor(Date.now() / 1000); | ||
const payload = Buffer.from( | ||
JSON.stringify({ | ||
iss: service_account.client_email, | ||
scope: "https://www.googleapis.com/auth/cloud-vision", | ||
aud: "https://oauth2.googleapis.com/token", | ||
exp: iat + 3600, | ||
iat: iat, | ||
}) | ||
).toString("base64url"); | ||
const signature = createSign("RSA-SHA256").update(`${header}.${payload}`).sign(service_account.private_key, "base64url"); | ||
const post_body = new URLSearchParams({ | ||
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer", | ||
assertion: `${header}.${payload}.${signature}` | ||
}); | ||
return new Promise((resolve, reject) => { | ||
const req = request( | ||
"https://oauth2.googleapis.com/token", | ||
{ | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/x-www-form-urlencoded", | ||
}, | ||
}, | ||
(res) => { | ||
const chunks = []; | ||
res.on("data", (chunk) => { | ||
chunks.push(chunk); | ||
}); | ||
|
||
res.on("end", () => { | ||
const data = JSON.parse(Buffer.concat(chunks).toString()); | ||
if (Object.prototype.hasOwnProperty.call(data,"access_token") && typeof data.access_token === "string" && data.access_token.length > 10){ | ||
resolve(data.access_token); | ||
} | ||
else{ | ||
reject(data); | ||
} | ||
}); | ||
} | ||
); | ||
req.on("error", (e) => { | ||
reject(e); | ||
}); | ||
req.write(post_body.toString()); | ||
req.end(); | ||
}); | ||
} catch (e) { | ||
throw new Error(`Error generating token: ${e.message}`); | ||
} | ||
} | ||
|
||
async function vision_api(params={},captcha){ | ||
try{ | ||
if (!Object.prototype.hasOwnProperty.call(params,"gcloud_token")){ | ||
params.gcloud_token = await checker(params.gcloud,params); | ||
return await vision_api(params,captcha); | ||
}else{ | ||
return new Promise((resolve, reject) => { | ||
const req = request("https://vision.googleapis.com/v1/images:annotate",{ | ||
"method":"POST", | ||
"headers": | ||
{ | ||
"Authorization":`Bearer ${params.gcloud_token}`, | ||
"x-goog-user-project":params.gcloud_project, | ||
"Content-Type":"application/json; charset=utf-8" | ||
} | ||
},(res) =>{ | ||
const chunks = []; | ||
res.on("data", (chunk) => { | ||
chunks.push(chunk); | ||
}); | ||
res.on("end", () => { | ||
const data = Buffer.concat(chunks).toString(); | ||
if (res.statusCode !== 200){ | ||
reject(data); | ||
}else{ | ||
resolve((JSON.parse(data)).responses[0].fullTextAnnotation.text.replace(/[\s\n\r]/g,'')); | ||
} | ||
}); | ||
}); | ||
req.on("error", (e) => { | ||
console.error("Request error:", e); | ||
reject(e); | ||
}); | ||
req.write(JSON.stringify({ | ||
"requests": [ | ||
{ | ||
"image": { | ||
"content": captcha | ||
}, | ||
"features": [ | ||
{ | ||
"type": "TEXT_DETECTION" | ||
} | ||
] | ||
} | ||
] | ||
} | ||
)); | ||
req.end(); | ||
}); | ||
} | ||
} catch(e){ | ||
throw new Error(`Error at Google Cloud Vision API:\n${e}`); | ||
} | ||
} | ||
|
||
export default vision_api; | ||
export {vision_api}; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters