Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getPrice() Function using node #73

Closed
wants to merge 1 commit into from
Closed

getPrice() Function using node #73

wants to merge 1 commit into from

Conversation

Sukriti-m
Copy link

@Sukriti-m Sukriti-m commented Oct 9, 2022

Fixes: appwrite/appwrite#4079

I have added the getPrice() function.
I am open to suggestions and changes.
@Meldiron Please merge my PR and add the 'hacktoberfest-accepted' label to the PR.

@Meldiron
Copy link
Contributor

Thank you so much for the PR 🤩. We're adding the hacktoberfest-accepted label to ensure this PR counts towards your Hacktoberfest contributions count. With that said, please stay active on this PR to address any comments once you receive a review. Happy Hacktoberfest! 🎃

@stnguyen90 stnguyen90 self-requested a review November 2, 2022 21:35
Copy link
Contributor

@stnguyen90 stnguyen90 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great PR! 🤯 We left some comments during the review, please check them out.

Comment on lines +42 to +48
docker run --rm --interactive --tty --volume $PWD:/usr/code openruntimes/node:17.0 sh /usr/local/src/build.sh
```
As a result, a `code.tar.gz` file will be generated.

3. Start the Open Runtime:
```
docker run -p 3000:3000 -e INTERNAL_RUNTIME_ENTRYPOINT=src/index.js -e INTERNAL_RUNTIME_KEY=secret-key --rm --interactive --tty --volume $PWD/code.tar.gz:/tmp/code.tar.gz:ro openruntimes/node:17.0 sh /usr/local/src/start.sh
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you please make sure to use a v2 image? Also, it looks like node:17.0 is no longer available. Maybe 18 is better?

Suggested change
docker run --rm --interactive --tty --volume $PWD:/usr/code openruntimes/node:17.0 sh /usr/local/src/build.sh
```
As a result, a `code.tar.gz` file will be generated.
3. Start the Open Runtime:
```
docker run -p 3000:3000 -e INTERNAL_RUNTIME_ENTRYPOINT=src/index.js -e INTERNAL_RUNTIME_KEY=secret-key --rm --interactive --tty --volume $PWD/code.tar.gz:/tmp/code.tar.gz:ro openruntimes/node:17.0 sh /usr/local/src/start.sh
docker run --rm --interactive --tty --volume $PWD:/usr/code openruntimes/node:v2-18.0 sh /usr/local/src/build.sh
```
As a result, a `code.tar.gz` file will be generated.
3. Start the Open Runtime:
```
docker run -p 3000:3000 -e INTERNAL_RUNTIME_ENTRYPOINT=src/index.js -e INTERNAL_RUNTIME_KEY=secret-key --rm --interactive --tty --volume $PWD/code.tar.gz:/tmp/code.tar.gz:ro openruntimes/node:v2-18.0 sh /usr/local/src/start.sh


## 📝 Notes
- This function is designed for use with Appwrite Cloud Functions. You can learn more about it in [Appwrite docs](https://appwrite.io/docs/functions).
- This example is compatible with NodeJS 17.0. Other versions may work but are not guarenteed to work as they haven't been tested.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's update this node version too.

res.send({ "success": false, "message": "Type is not supported." });
}
};
module.exports = getPrice;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some style inconsistencies in this code. I highly recommend using some auto formatter like Prettier to easily and quickly clean up and ensure consistent style.

Comment on lines +4 to +6
const AlphavantageAPIkey = req.env.ALPHAVANTAGE_API_KEY;
const GoldAPIkey = req.env.GOLD_API_KEY;
const CoinAPIkey = req.env.COIN_API_KEY;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best practice for variable names like this is either camelCase or SCREAMING_SNAKE_CASE. Please also make sure to use req.variables for v2 runtime image.

let price,code;

if (!type) {
throw new Error("type is required");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intead of throwing an error, make sure to call res.json() and return after. The response format for errors should be something like:

{"success":false,"message":"Type is not supported."}

as described in the issue.

const AlphavantageAPIkey = req.env.ALPHAVANTAGE_API_KEY;
const GoldAPIkey = req.env.GOLD_API_KEY;
const CoinAPIkey = req.env.COIN_API_KEY;
const { type } = req.payload.toLowerCase();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To ensure compatiblity with Appwrite Functions, please pass a JSON string in as payload and parse it in the function like:

Suggested change
const { type } = req.payload.toLowerCase();
let payload = {};
try {
payload = JSON.parse(req.payload)
} catch (e) {
res.json({
success: false,
message: `Error parsing payload: ${e}`
})
return;
}
const type = (payload['type'] ?? '').toLowerCase();

throw new Error("type is required");
}

if ((!AlphavantageAPIkey || AlphavantageAPIkey === "")&&(!GoldAPIkey || GoldAPIkey === "") && (!CoinAPIkey || CoinAPIkey === "")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need for both !AlphavantageAPIkey AND AlphavantageAPIkey === "". If AlphavantageAPIkey is an empty string, the first condition will be true aleady.

Comment on lines +36 to +41
fetch(`https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${code}&apikey=${AlphavantageAPIkey}`)
.then(data=>data.json())
.then(data=>{
price=data['Global Quote']['02. open'];
res.staus(200).send({ "success": true, "price": price });
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

staus is invalid. I also highly suggest avoiding using then in async functions because it can make the code flow a lot more difficult to follow. For example, when I tried to run this:

curl -H "X-Internal-Challenge: secret-key" \
    -H "Content-Type: application/json" \
    -X POST http:https://localhost:3000/ \
    -d '{
    "variables": {
        "ALPHAVANTAGE_API_KEY": "ALPHAVANTAGE_API_KEY",
        "GOLD_API_KEY": "GOLD_API_KEY",
        "COIN_API_KEY": "COIN_API_KEY"
    },
    "payload": "{\"type\": \"google\"}"
}' 

the command just hang because the function threw an error:

22:05:16 0|server | TypeError: res.staus is not a function
22:05:16 0|server |     at /usr/code-start/src/index.js:51:13
22:05:16 0|server |     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

and a response was never sent back.

Suggested change
fetch(`https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${code}&apikey=${AlphavantageAPIkey}`)
.then(data=>data.json())
.then(data=>{
price=data['Global Quote']['02. open'];
res.staus(200).send({ "success": true, "price": price });
})
const response = await fetch(`https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${code}&apikey=${AlphavantageAPIkey}`)
if (response.status !== 200) {
res.json({ success: false, message: await response.text() });
return;
}
const text = await response.text();
try {
const data = JSON.parse(text);
const note = data['Note'];
if (note) {
res.json({ success: false, message: note });
return;
}
const price = data['Global Quote']['02. open'];
res.json({ "success": true, "price": price });
} catch (e) {
res.json({ success: false, message: text });
}

Please apply my comments for the other APIs as well.

Comment on lines +23 to +25
## 📝 Environment Variables

List of environment variables used by this cloud function:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove references to "environment" as those were in the older version of functions.

@Meldiron
Copy link
Contributor

Hey there 👋
We are temporarily closing your PR as there has been no activity on it. Feel free to re-open it when you're ready to start working on it again 😇

@Meldiron Meldiron closed this Jan 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

⚡ Write a getPrice() Function using Node
3 participants