How to generate a file after a created command? - api

I have an e-commerce customer who uses Shopify APIs to create an order (a customer who purchased an item).
From a created command (which can contain different items), I must generate a file with some attributes like weight or the destination address.
I was drowning in their public documentation and honestly can't get over it (I don't have much programming experience).
I would like to know which APIs (or services...) I have to request in your opinion please?
Given what I'm being asked, I don't know if I can find all this info with a single API or I have to call several methods to build my file little by little...
For example, I have no idea, really no idea to know if a given command is fragile or not. I don't even know if they communicate such information by their API.
Thanks in advance

If you want realtime (as soon as the order is created, the file is created) : You need to register a webhook.
A Shopify webhook is simply a script that, on a certain event, send the event's data to a link.
Example : An order placed webhook (predefined Shopify webhook) will send the order's data to an URL in JSON format as soon as the order is placed.
So you will need a server running 24/7 (get a VPS for less than 5 bucks a month). The server will listen at an ip at a certain port.
You will setup Shopify's webhook to send data to that ip / port.
Step 1: Create your server
You will need any backend framework for this. I choose NodeJs + Express framework, because it is so easy to do with it.
Here is a sample code :
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = 3000;
app.use(bodyParser.json());
app.post('/', function (req, res) {
let body = req.body;
console.log(body);
});
let server = app.listen(port, function () {
let host = server.address().address;
console.log('Example app listening at http://%s:%s', host, port); //Copy this to your clipboard, you will need it in step 2
});
Step 2: Register Shopify Webhook
Go to your client's store, add /admin/settings/notifications to the url.
Scroll to the bottom of the page, click Create Webhook, chose Order creation as an event, JSON format, Lastest as API version. Paste the IP / Port you copied earlier into URL.
Step 3: Check the data sent by Shopify
From here, you can check the data Shopify sent you. It will be printed by your NodeJs server.
It is in JSON format, so you can do all kinds of stuff with it. Filter important info, and output to file for example.
If you want to check everytime your script starts and not realtime : you need to create a custom app in your client's store, and use GraphQL
Shopify won't let you check for certain orders by order number, and the limit of their API is 250. Using GraphQL, you can do this, but you need to know GraphQL (a little more advanced).
You can check their docs at shopify.dev

Related

How to securely validate payment and send product

I am building a website for a masseur with VueJS + Strapi, and clients can buy a gift voucher.
Right now I have the VueJS part set-up with a Paypal payment gateway.
I am wondering how to set-up the back-end part and how to trigger the creation of the voucher.
What I was planning to do is send the response from paypal (onApprove) to the back-end and create a new voucher in the database then send it through e-mail to the recipient.
onApprove: async (data, actions) => {
const order = await actions.order.capture();
axios.post('myapiroute', order)
},
Is this secure ? (if I use CORS to only allow my front-end's adress to make calls to the back-end API)
Is there a way to "bypass" cors or force the front-end to make API calls ?
Is there a more secure way to do this ?
Do not use actions.order.create / .capture to create and capture orders on the client side if you need to perform any server-side actions (such as writing to a database or sending to a product) as a result of that capture.
The order creation and capture should instead be done from server-side code, with whatever backend you have (apparently node.js in this case; there is a Checkout-NodeJS-SDK available).
Make two routes on your server, one for 'Create Order' and one for 'Capture Order', documented here. These routes should return only JSON data (no HTML or text). The latter one should (on success) store the payment details in your database before it does the return (particularly purchase_units[0].payments.captures[0].id, the PayPal transaction ID)
Pair those two routes with the following approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server
(Since you are using a vue frontend you can look at this vue-specific sample, but change its createOrder and onApprove to fetch from your backend)

Can't create a simple webhook fulfillment Good Actions Console

I am trying to do a simple google home integration with my home server. My only goal is to have it say "Hey google, turn on pool lights" and "Hey Google, turn off pool lights". Both should be mapped to https://mywebsite.com/fullfillment. Once it hits my express server which is running actions-on-google (code below) I have sample code that should properly respond.
Right now whenever I try to create a webhook fulfillment, I just get an error. What am I missing here to just have google home interact with my home server? I've watched countless tutorial and read articles but none really work with remote webhooks, most are fulfillment through firebase or through the inline editor. I have setup OAth as well in the activity linking but I still get the same error "We're sorry but something went wrong. Please try again".
I have also made sure my app and activity controls are enabled as well. I'm just trying to get the action to recognize the webhook and not through this error, if the error at least had some information I could move forward. The "Logs in Google Cloud" also show nothing at all. I have also changed the invocation to a long more custom name and still same error.
Below is a video showing me running through creation of a new Smart Home action on a fresh google account with a postman clip hitting my home server with the correct payload. I've tried this with multiple variations of the webhook url, ngrok was just the latest attempt.
https://youtu.be/Txv1HmP0yW4
Code for my express server below.
const express = require('express');
const bodyParser = require('body-parser');
const {
dialogflow,
actionssdk,
Image,
Table,
Carousel,
} = require('actions-on-google');
const app = dialogflow({
debug: true
});
app.intent('Default Welcome Intent', (conv) => {
conv.ask('How are you?');
});
app.intent('bye', (conv) => {
conv.close('See you later!');
});
app.catch((conv, error) => {
console.error(error);
conv.ask('I encountered a glitch. Can you say that again?');
});
app.fallback((conv) => {
conv.ask(`I couldn't understand. Can you say that again?`);
});
const expressApp = express().use(bodyParser.json());
expressApp.post('/fulfillment', app);
expressApp.listen(1349, () => {
console.log("Test on port 1349");
})
If you have created an Actions on Google Project using dialogflow or Assistant conversational action, it won’t work as a Smart Home integration anymore. Please create a new project in the Actions on Google Console, selecting Smart Home as the project type.
Once you create your action, if you intend to build your own server handling smart home requests, a good way to start could be with the Smart Home Washer codelab. You can replace the fulfillment url to your own server, keeping the firebase database and everything else the same. Once you verify you can handle fulfillment requests, you can carry over the rest of the pieces (OAuth) to your server as well. If you get stuck debugging the smart home fulfillments, you can take a look at the Troubleshooting guide.

How to fetch userID, tenantID and serviceURL from MSTeams?

I was looking into Microsoft Graph Postman Collections but could not locate the tenantID, serviceURL or userID?
Is there a way to fetch userID, tenantID and serviceURL from MSTeams?
As the other answer mentions, you can get this via the "context" object, which in turn means you need to create a Teams application, and it must include a Tab. There is another similar option, which is to create a Bot for Teams, and when the user installs the bot, either 1-1, or into a channel or group chat, you get the chance to retrieve that information. You can see more about that here, including some options based on the type of bot and when you want to retrieve the information.
If it's ok to have an app, then simply go ahead with this approach. If you really don't -want the user to interact with an app, then you could consider the following:
create the application (e.g. a bot) in order to get the context you need
Auto-install the bot, as per this Graph call
Retrieve and save the information in the conversationUpdate, which is fired when you bot is installed by the user / team / chat
Auto uninstall the app using this Graph call
However, you haven't explained why you need those bits of information. That set is often used to send a proactive message from a bot, and if that's what you're trying to do, you'll need the bot anyway.
Please take a look at Get context using Microsoft Teams javascript library.
// Call the initialize API first
microsoftTeams.initialize();
// Check the initial theme user chose and respect it
microsoftTeams.getContext(function (context) {
if (context) {
console.log(context);
}
});

Shopify : How to test webhooks in php

I am new in shopify. I have created one app in php for shopify. I have registered webhooks using admin apis. But i don't know how to test webhooks. I have spent lots of time to figure out but not getting any proper response. How to get response and write stuff over there?
Is it like Apis? How to notify that webhooks are called or not.
Please help me.
Unlike APIs, Webhook is event driven(triggered on any event e.g. Order Creation) and send data in JSON/XML format to particular URL.
You can create a Webhook in your Shopify store by following steps.
Go to Settings -> Notification -> Webhooks -> Create Webhook
Select Event on which your webhook will be triggered data Format and URL(https) to which you want to send your data.
Now your data is available in JSON format to server location you have shared in URL field. You can use following code.
<?php
define('SHOPIFY_APP_SECRET', 'my_shared_secret');
function verify_webhook($data, $hmac_header){
$calculated_hmac = base64_encode(hash_hmac('sha256', $data, SHOPIFY_APP_SECRET, true));
return hash_equals($hmac_header, $calculated_hmac);
}
$hmac_header = $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'];
$data = file_get_contents('php://input');
$verified = verify_webhook($data, $hmac_header);
error_log('Webhook verified: '.var_export($verified, true)); //check error.log to see the result
?>

How can a webhook identify USER_IDs?

I'm developing a webhook, and I want it to be able to #mention specific users. The simple message format specifies using the format of <users/123456789012345> to #mention a specific users. Since this is not a bot, it is not processing an incoming message and cannot pull the from the sender field, as suggested in the note on the developer site linked above.
How can I get the USER_ID of a user on my domain?
I am in the same boat as you. Trying to use a Webhook to mention a user.
If you inspect the HTML on https://chat.google.com, using web/dev tools, you can actually see user ID under tag data-member-id="user/bot/123456789012345"
Using the above I tried to form a webhook that mentioned the user (in my case another bot).
Unfortunately it didn't work. Passing in the string <users/123456789012345> please test came through to chat as a string literal.
It's strange because the html links and markup DO get interpreted. As mentioned here. Edit: so does <users/all>.
I'm leaving this here since your question asks for how to elicit the ID. While it may not be pretty, or much automatable, it helped me get the user ID at least.
Edit 2: It works, just not to mention my other bot for some reason. But using this method I was able to mention a human user :)
I use this for find the USER_ID but if you have another way let me know
Right click on the user and select inspect
Search for data-member-id this is your USER_ID
A webhook will not be able to pull the USER_ID of a user. As a workaround for this, you can create a service account and a bot that has access to the room and use the REST API spaces.members.list() and spaces.members.get() method.
Note: The bot will need to be added to the room.
Okay, so in order to get the UserID without having to do all of the things that you're trying to do here you need to use the Admin SDK API in google app script. Basically what you'll want to do is use your google app script as an intermediary for what you're trying to do. So you'll post something to google app script via their web exec functions on a deployed app and then have that app communicate to the google chat API via something like this:
var googlewebhookurl = 'https://chat.googleapis.com/v1/spaces/ASDFLKAJHEPQIHEWFQOEWNQWEFOINQ';
var options = {
'method': 'post',
'contentType': 'application/json',
'payload' : JSON.stringify({ text: "<users/000000000001> I see you!" })
}
UrlFetchApp.fetch(googlewebhookurl, options);
To start, you'll need to add the Admin SDK API to the services in your google app script services area. So click the plus next to "Services" and then select the Admin SDK API and click add to add it to the services, it winds up showing up in the list as "AdminDirectory" once it has been added to the services.
This is an image showing what it looks like once you've added it to the services.
Here is a link to the documentation for the Admin SDK API getting user information: https://developers.google.com/apps-script/advanced/admin-sdk-directory#get_user
You should be able to copy and paste that example function to get the information you're looking for regarding the user. I'm pasting the example code below in case something happens to this link:
/**
* Get a user by their email address and logs all of their data as a JSON string.
*/
function getUser() {
var userEmail = 'liz#example.com';
var user = AdminDirectory.Users.get(userEmail);
Logger.log('User data:\n %s', JSON.stringify(user, null, 2));
}
In order to get the user id, take the user variable that comes back and access user.id and voila! You have the ID you're looking for. From there just plaster it into a text message in google chat and you should be in business. I haven't gotten it to work with cards at all yet. I'm not seeing any documentation saying that it's supported in cards at all. For more information regarding chat messages and cards take a look at these:
https://developers.google.com/chat/api/guides/message-formats/basic
https://developers.google.com/chat/api/guides/message-formats/cards