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

Explanation about linking custom setting implemented from app to shopify website #21

Open
rubycis opened this issue Jul 13, 2016 · 114 comments

Comments

@rubycis
Copy link

rubycis commented Jul 13, 2016

Hi,
I have created partner account and created app as well. I have integrated the library also. Done with app installation and authorization.
Now I am stuck for next step. I don't understand how can I linked the custom setting implemented on my app to shopify frontend. How can I linked the app database to shopify website.
How can I implement a page on shopify website for customer to customize any product and where I save all the customized data and how can I linked that data with shopify website.

I am able to make standalone app with php but don't understand how it's data can be linked to shopify website. How my local app database can be used in shopify website.

I am new here. Any help is very much appreciated.

Thanks

@rubycis rubycis changed the title explanation about linking custom setting implemented from app to shopify website Explanation about linking custom setting implemented from app to shopify website Jul 13, 2016
@myjanky
Copy link

myjanky commented Jul 13, 2016

Hi @rubycis

I hope I understand you correctly. You want your app connected to the "Front End" or Shop so that you can add functionality for your customers and visitors to use.

If so, you need to enable the app proxy part of your app in the partners dashboard for that app.
For example: In your store, you can call your app's server url with the proxy url you created to get the data from your app into your store. The drop down Sub path prefix allows you to change the first part of the url and the text box allows URL to be the rest of the app proxy url. So in my case xxxx.myshopify.com/app/customize will call the proxy url https://xxxxx.com/shopify/shirt/client/ where my app code resides for the front end of the shop. Keep in mind that this has to be ssl cert protected with a valid non-selfsigned cert or Shopify will not allow the proxy to be called (throw up warnings of cross site validation). Also, shopify gets your app into the Shop via an iFrame which could cause other issues and why the SSL is so important.
screenshot 2016-07-13 at 10 37 45 am

@rubycis
Copy link
Author

rubycis commented Jul 14, 2016

Thank you so much myjanky 👍
You understand me with some extent. But the Proxy URL is the app's server url i.e the complete new page in shopify front end. But if we want to add some custom things in the existing product page or collection page itself in shopify front through our php app, then what we need to do in that case.

@myjanky
Copy link

myjanky commented Jul 14, 2016

No problem, you are welcome.
Yes you would use a proxy url to add functionality to the product or collection page.
I have an Embroidery Application that allows our customers to add monograms to the clothing we sale. It launches on the product page and allows the customer to see a virtual render of the product with the monogram. This is all done using the app proxy url. Maybe you only want to feed/get data to your store and not html/css, an app proxy is used for this as well.

So no, the proxy URL is not a complete new page in shopify frontend. You can add it to any template (or layout, snippet, asset), to get the result you are looking for.

Let me know what kind of front end functionality you are looking to implement and I may be able to steer you in the right direction.

The Proxy URL allows you to keep your store secure and prevent CSRF or XSRF attacks. By creating a /apps/customize type of URL for your store (you do not have access to add your app server domain to the CORS origin on Shopify) it will call your app server to retrieve the content without the need to setup CORS.

@rubycis
Copy link
Author

rubycis commented Jul 15, 2016

As you told me "you can add proxy URL to any template (or layout, snippet, asset), to get the result you are looking for." Can you explain me how this can be implement? Because in app section of partner dashboard we need to add a single url. So I don't understand how this can be implemented in the shopify collection, product etc template file or snippet.
Thanks

@myjanky
Copy link

myjanky commented Jul 15, 2016

This can be implemented in several ways.
I will show you a simple Javascript implementation.

Create an asset JS file and save something similar to the following.

jQuery(function($){ /*app load container */ var base_urlc = window.location.hostname; //get store url var window_width = $(window).width(); //get window width if ($('#custom_app').length > 0 ){ //check if element #custom_app exist $('#custom_app').css({'width':'100%'}); // set container width var width_canvas = $('#custom_app').width(); //save it var product_id = $('#custom_app').data('product'); //set ID of current product $.get( '/products/' + product_id + '.json', /* call the store and get a json list of the products parameters */ function(xhr,status){ data_params = JSON.stringify(xhr); //store parameters data_param=JSON.parse(data_params); //parse parameters var product_id = data_param.product.id; var img_lrg = Shopify.resizeImage(data_param.product.images[0].src, 'large'); //fix image size /* this is where the magic occurs. Notice I am calling /apps/customize into an iframe with url query parameters. you could also just call custom html with a .get function */ var target_html = '<iframe id="custome-app-iframe" src="//' + base_urlc + '/apps/customize?shop=' + Shopify.shop + '&product_id=' + product_id + '&image=' + img_lrg + '" frameborder="0" scrolling="no" style="display:block;" width="100%" />'; //create iframe elements with src of app server from proxy url $('#custome-app-iframe').html(target_html); //write iframe html to element }); }

Sorry for the formatting above.

Now that you have this piece you can add more functions to it based on the URL params being sent to the app server via the proxy URL.
Notice I have Shopify.shop which identifies the store we are working with (in case we have multiple stores using the app). then there is the product.id because the app above was made to work with the product page. But nothing is stopping you from getting the current page (collection, blog, product, page etc...) and sending that to the app server via a query param to do something with and return data/content back to your shop.

@myjanky
Copy link

myjanky commented Jul 15, 2016

here is a gist I made for this.

https://gist.github.com/myjanky/fea449e74830c86aed6a83d2e02ead3b

@rubycis
Copy link
Author

rubycis commented Jul 16, 2016

Hi myjanky
I have used your code but I don't get product_id. It's coming undefined. I have included app_proxy.js file and added custom_app div also in the product template.

@myjanky
Copy link

myjanky commented Jul 16, 2016

Sorry about that. I did not add the element with the "data-product" attribute.

add this to product.liquid to get the product.id
<div id='customized' data-product='{{ product.handle }}' ></div>

as long as you are using this with product.liquid you should be ok, but other file files like collection.liquid will need some heavy edits depending on what you are looking to do.

@alexandprivate
Copy link

alexandprivate commented Sep 22, 2016

Larry how you doing pal, I have kind of the doubt here with this part of the proxy and the frontend store modification like in the example you provide with the URL .../customize/ how can you modify for example a product name by adding some word in the product.liquid template? and I see you are using a js to do so, are you using a php file to inject the js to the desire view ? by the way can I get the checkout,liquid even if the shop that in runnig my app don't have a plus account plan ?

@myjanky
Copy link

myjanky commented Sep 22, 2016

Doing good, thanks! you?
that is possibly a js only solution.

Without knowing the full scope of what you are going after, this could be done with Liquid and a bit of js magic.

var title = {{ product.title | json }}; if (title == "My Product" ){ $.get("/proxy_url", function(data, status){ $('product_title h1').html('My Super Awesome' + data) }); }

also you could pass query params to /proxy_url whatever that is (like /customize).
Really you should not even need the ajax .get if you save your logic in a liquid template and then call that file instead of the get.

It just depends on how you plan on using the app proxy url.

@alexandprivate
Copy link

great ! and the checkout.liquid just to add a couple of plane text lines ?

@myjanky
Copy link

myjanky commented Sep 22, 2016

pretty much the same but you would need a Plus account. Unless it is static text than you could add it through a css content var, although I could be mistaken on that.

@alexandprivate
Copy link

well that a reasonable doubt since the API doc didn't mention the need for a plus plan to modify the checkout.liquid (just adding text) by an app, I fact it says about the plus plan if the store owner wanna change the checkout manipulating the liquid. Have you ever try to PUT some text at the checkout.liquid of a developer store ?

@myjanky
Copy link

myjanky commented Sep 22, 2016

try this in the theme editor.
screenshot 2016-09-22 at 3 44 53 pm

@myjanky
Copy link

myjanky commented Sep 22, 2016

depends on what plan you have.
screenshot 2016-09-22 at 3 46 15 pm

@alexandprivate
Copy link

Great but remember I wanna do the text injection to the checkout.liquid using the app proxy without touch the liquid itself

@alexandprivate
Copy link

In the first pic you try to create a new layout base in checkout.liquid ... thats because you have a plus account right ?

@myjanky
Copy link

myjanky commented Sep 22, 2016

well there is this additional scripts in the admin where you can add some js for things like google tracking and such. I would try it there but I have never had a use case where I needed to get data from the app server on the checkout page. It should work but remember the checkout for shops that are not Plus are hosted at checkout.shopify.com and not somestore.myshopify.com. This is why I am unsure the app proxy will work this way.

@alexandprivate
Copy link

hummmmmmmm I see it is just to put some

text at the left side in the checkout

@myjanky
Copy link

myjanky commented Sep 22, 2016

what about adding the text to a custom image and uploading it as the background image in the customize theme option?

@alexandprivate
Copy link

alexandprivate commented Sep 23, 2016

Humm no, that wont work for me, look what I really need is to change some content in the template automatically without touching the liquid file itself, I saw I can do so through the Asset API I just don't know how to do it. Any idea ? ohh Larry by the way this is a public App not a private one, the product name will change with content set using the app and modifying the product name automatically, since the app will be installed en several shops we cant touch the liquid, that's the reason we need to accomplish this using the Asset and like so far we cant not determine the tag containing the element we need to modify there is another concern. because one shop may use a "h1" with class name to place the product name and another shop may use a "p" tag or whatever to place the product name and so on.

@myjanky
Copy link

myjanky commented Sep 23, 2016

The issue with that understanding is that the Asset API gets or puts theme files and can modify those.
So adding content to the checkout.liquid will not work for most accounts. (plus required.)

the docs need to be updated to reflect these restrictions.

So your app users will log in and load your app, make content changes they want to appear as the product title then save it. When customers Checkout, you want the app users content to be displayed instead of the default product.title?

If so, this could be done using the new Shopify Scripts. (Plus account required.)

@alexandprivate
Copy link

@alexandprivate
Copy link

ok checkout appart, this is perfectly accomplish for the rest of view, like product detail view and product list, collections etc ?

@alexandprivate
Copy link

so how can I modify the name of a product out of the checkout page ? in all places but in the checkout using data placed through my app ?

@alexandprivate
Copy link

Larry how much cost the plus plan ?

@myjanky
Copy link

myjanky commented Sep 23, 2016

Yes, you can use for the rest of the page views that use product.title.
I see many app developers use a "kludge" so to speak. Where they create a new hidden product that they replace in the cart for the originally added product? In your case it would be a hidden product that has the title you want but is a representation of the original added to the cart.

The base cost of a plus plan is $1200 per month.

@myjanky
Copy link

myjanky commented Sep 23, 2016

Also, try to install a few apps and poke around in the code that was added to your site. It may clear any misunderstandings and also give you ideas on how to implement what you want.

@realramesh05
Copy link

How to add webhook for particular store on app deletion

@myjanky
Copy link

myjanky commented Dec 20, 2016

Not sure I understand for a particular store. I usually add the webhook on app install. When app is deleted the webhook is called and the app server runs the api command to remove the assets your app installed. Most apps just leave the assets behind in case of reinstall.

@realramesh05
Copy link

Thank you myjanky. Will get back to you for help if any. I am new to this app development

@realramesh05
Copy link

Hi myjanky. I have did what I want to do with the help of your knowledge Thank you so much. I have a issue. When the Shop owner clicks on my APP from their admin/apps. My app is loading in the iframe. where shopify passing the following

https://www.mydomain.com/shopify/app.php?hmac=e8ffe2f8601c49bba7e683d6107a1d49da7b39fe041ffd1a53b507e615b7f43a&amp;protocol=https%3A%2F%2F&amp;shop=shopifyname.myshopify.com&amp;timestamp=1482377633

Using this how can I generate acccess token? I am using OhShopify unofficial library. where the following function which need the parameter code. How can I get access_token with the above url parameters which does't have the code parameter.

public function getAccessToken($code) {
    // POST to  POST https://SHOP_NAME.myshopify.com/admin/oauth/access_token
    $url = "https://{$this->shop_domain}/admin/oauth/access_token";
    $payload = "client_id={$this->api_key}&client_secret={$this->secret}&code=$code";
    $response = $this->curlHttpApiRequest('POST', $url, '', $payload, array());
    $response = json_decode($response, true);
    if (isset($response['access_token']))
        return $response['access_token'];
    return '';
}

@myjanky
Copy link

myjanky commented Dec 22, 2016

Yea that is the same as this library just written differently.
check this doc out. https://help.shopify.com/api/guides/authentication/oauth
Webhooks have a different code (see note at bottom of above url).
Is that url the $permission_url?

function access_token($shop, $api_key, $shared_secret, $code) { try { $response = http\request("POST https://$shop/admin/oauth/access_token", array(), array('client_id'=>$api_key, 'client_secret'=>$shared_secret, 'code'=>$code)); } catch (http\CurlException $e) { throw new CurlException($e->getMessage(), $e->getCode(), $e->getRequest()); } catch (http\ResponseException $e) { throw new ApiException($e->getMessage(), $e->getCode(), $e->getRequest(), $e->getResponse()); } return $response['access_token']; }

@bikramsao
Copy link

How to show order data in every page?
I am developing an application in Ruby on Rails
I have developed an application proxy and I want to show orders data in every page .
How to make it possible?
Thanks in advance.

@myjanky
Copy link

myjanky commented Jul 28, 2017

Such as when a customer is logged in, their order data from previous orders is displayed on all the pages they navigate to?

If so, I would do it without an app and use something like this on the frontend. https://help.shopify.com/themes/development/templates/customers-order

@bikramsao
Copy link

Thanks for the response .
But I want to display all recent orders regardless of customer login.
That's why I used proxy and JavaScript for the purpose.
I am looking for way to get all order data and display on store front .
how to make it possible?
Regards

@myjanky
Copy link

myjanky commented Jul 28, 2017

You can do an ajax GET to the proxy URL and that will call the URL you have pointed at your app.
For example if you have YOUR-SHOP.myshopify.com/apps/orderdata
for the Proxy and it points to myapp.com/orderdata

then do something like $.ajax({url: " YOUR-SHOP.myshopify.com/apps/orderdata",data: {id: did, id1: did1},cache: false}).done(function( html ) { $('.classname').append(html);});

place in theme.liquid or where ever you need it on the shop.

@bikramsao
Copy link

Its showing 404 (Not Found) error

This code is in my proxy controller
def index
render layout: false, content_type: 'application/liquid'
ShopifyAPI::Base.site = Shop.find(name: params[:shop])
@orders = ShopifyAPI::Order.find(:all, :params => {:limit => 10})
end

@myjanky
Copy link

myjanky commented Jul 28, 2017

screenshot what you have set for the app proxy in the partners dashboard

@bikramsao
Copy link

image

@myjanky
Copy link

myjanky commented Jul 28, 2017

can you post the JS code that calls /app_proxy page?

@bikramsao
Copy link

These codes are in theme.liquid

<script> $.ajax({url: " marmeto.myshopify.com/apps/latest-bkm",cache: false}).done(function( html ) { $('#custom_app').append(html);}); </script>

@myjanky
Copy link

myjanky commented Jul 28, 2017

Not sure but I think it is '{url: "/apps/latest-bkm",.....'

can you console.log the error?

@bikramsao
Copy link

There is no error in the console .
But the div is empty.
Its not showing orders.

@myjanky
Copy link

myjanky commented Jul 28, 2017

How did you obtain the 404 page not found error? from before? are you still seeing that?
Here is some code I use to load in an iframe.
var base_urlc = window.location.hostname; $.get( '/products/' + product_id + '.json',function(xhr,status){ data_params = JSON.stringify(xhr); data_param=JSON.parse(data_params); var product_id = data_param.product.id; var img_lrg = Shopify.resizeImage(data_param.product.images[0].src, 'large'); var target_html = '<iframe id="customized-iframe" src="//' + base_urlc + '/apps/customize?shop=' + Shopify.shop + '&product_id=' + product_id + '&image=' + img_lrg + '" frameborder="0" scrolling="no" style="display:block;" width="100%" />'; $('#customized').html(target_html); });

@myjanky
Copy link

myjanky commented Jul 28, 2017

are you using private app credentials? i see a 500 internal server error.

@myjanky
Copy link

myjanky commented Jul 28, 2017

Just so you know anyone can get at your store data doing it that way.
screenshot 2017-07-28 at 10 13 44 am

@myjanky
Copy link

myjanky commented Jul 28, 2017

Also this is not a valid endpoint
screenshot 2017-07-28 at 10 16 21 am

@bikramsao
Copy link

404 error is not there.
I think its problem with back-end .
Is there any problem with controller of the proxy app?
Code as follows
class AppProxyController < ApplicationController
include ShopifyApp::AppProxyVerification
include ShopifyAPI

def index
render layout: false, content_type: 'application/liquid'
ShopifyAPI::Base.site = Shop.find(name: params[:shop])
@orders = ShopifyAPI::Order.find(:all, :params => {:limit => 10})
end
end

@bikramsao
Copy link

I checked heroku logs
500 internal server error is coming in due the following reason
NoMethodError (undefined method `path' for nil:NilClass):

@myjanky
Copy link

myjanky commented Jul 28, 2017

what library is the ruby code coming from?

@bikramsao
Copy link

I have used the shopify_app gem v 7.2.8
Then I run the generator
rails generate shopify_app:app_proxy_controller
After that I followed https://shopifyengineering.myshopify.com/blogs/engineering/17488588-application-proxies-the-new-hotness

@myjanky
Copy link

myjanky commented Jul 28, 2017

Yea that is way out of date. I suggest using the app proxy already available in the 7.2.8 (7.3 is latest)
https://github.com/Shopify/shopify_app#appproxyverification

@bikramsao
Copy link

I have used AppProxyVerification.
But how to pass the order data?

@myjanky
Copy link

myjanky commented Jul 28, 2017

what do you have for your template for index (def index)?

Path is nil may be due to def index not being defined.

It's too hard to determine where the issue is coming from.
What do you have your application scopes set to. read_orders is required.

@bikramsao
Copy link

index.html.erb
`


Your Shop Details:


Shop Name : {{ shop.name }} myshopify name : {{ shop.permanent_domain }} Primary Domain of Shop : {{ shop.domain }} Shop URL : {{ shop.url }} Shop Currency : {{ shop.currency }} No. of products in this shop : {{ shop.products_count }}

` It is the default one and was working on the proxy url After I tried getting order data it stopped working saying `There was an error in the third-party application.` And read_order scope is there in shopify_app.rb file .

@myjanky
Copy link

myjanky commented Jul 28, 2017

It might be that the App proxy does not allow access to these resources.
But again I am shooting in the dark because I can not debug from here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants