I would like to integrate my cloud service in Heroku as an add-on. I read the available tutorials on how to do this, but it is still not clear. https://devcenter.heroku.com/articles/building-a-heroku-add-on#provisioning
I couldn't understand the role of the application that we create from a template (Sinatra for example) using kensa.
Is it an intermediate between Heroku and the cloud service?
thanks in advance.
Actually, Heroku needs 2 things:
addon-manifest.json file where described all information needed for Heroku. And this json file contains 2 important urls:
'base_url'
'sso_url'
Application which will server heroku-specific API and responds wit corresponding JSON on provisioning/deprovisioning/planchange requests. These request point to 'base_url'.
So, if you own your Cloud service code, and can add new API endpoints, then you don't need any application based on kensa-template: add necessary API controllers directly in the service.
But if you can't upgrade the cloud service, then you're right, kensa-template is a ready to use with heroku intermediate.
In case of sinatra template, you just need to put necessary API calls to your cloud service in "# provision" method of app.rb file, deploy app somewhere and do 'kensa push' for your addon-manifest.json (don;t forget to update base_url to yours)
Good luck!
Bare minimum API routes for heroku add-on based on your Cloud service:
POST request to '/heroku/resources' - for provisioning
DELETE request to '/heroku/resources' - for deprovisioning
If you really want to sell it to heroku users, then you should do more stuff:
add support for heroku single sign-on
this is one more API route: POST to '/heroku/sso', but you can change it in addon-manifest.json file.
PUT '/heroku/resources/:id' for Plan change request. Note that ':id' is an id which you provided heroku in your response during provisioning.
If you implement SSO, then user can click on your add-on on heroku instance's resources page and redirect directly to your service bypass any login forms.
You can show just short info about user's resource in the page after SSO.
Related
I'm in the process of building my first RoR webapp and I'm currently trying to set up an integration with Shopify. I want to create an order in my web application whenever one is created in Shopify. For this I want to use a Shopify webhook. Step two will be to set it up so that after processing the order I'll use the Shopify API to update some records. For now my main concern is receiving the webhooks. I've been looking at the documentation for the Shopify gem but with my limited RoR skills I can't seem to figure it out. I've been searching the web for a few hours but can't find any clear examples / explanation.
I'm confused about this gem; shopify-api (https://docs.shopify.com/api/authentication/using-api-gem-with-private-app-credentials). I've created a private app in shopify, but after that I'm lost. Where am I supposed to place this code and how is this invoked after receiving a webhook?
It seems to me that this gem is mainly used to access the Shopify API instead of consuming webhooks. Am I going at this all wrong?
For receiving the changes (especially Order Creation event) from Shopify, you don't need to use any gem or third party to integrate!
Here are the steps that I did before in my app:
1. Provide an api in your app to receive a webhook event
Here is an example:
Your route:
post '/shopify/create_order', to: 'shopify#create_order'
Your controller:
class ShopifyController < ApplicationController
def create_order
# process shopify order here: all info in `params`
end
end
2. Config to call webhook from your Shopify Settings. The configured url will be:
http://your_production_url/shopify/create_order
If you want to test from localhost, go to step 3
3. (Optional) Test from your localhost
Download this free tool: ngrok and extract it to your machine.
Run ngrok in your terminal to generate a forwarding url to your localhost by this command:
ngrok http 3000
So you will get the output from console like this:
Copy the generated url (http://fbc5cf88.ngrok.io for example) above and add to your Shopify settings in step 2
4. (Optional but critical) Set privacy in your app, to make sure only Shopify can call your api. Follow this documentation
Shopify also provides api to integrate with Shopify resources: create/update product, collection, collect, metafield,... You can directly use it. All was described at Shopify API documentation. But the easiest way to work with Shopify is shopify_api gem which provides an interface to work with Shopify (via ActiceResource)
Probably reading up on the documentation on Webhooks would help you figure out a lot of what you need to do
In essence, here are the overview of what you need to start consuming web hooks:
1. Create your web hooks
You can do it using the Shopify API (POST /admin/webhooks.json)
Or you can do it through store admin
The params that you need to take note of:
topic: the type of hook you want (for e.g orders/create)
address: the URL of the endpoint that you would be consuming the hook at (for e.g: https://myapp.domain.com/hooks/order_create)
2. Create your endpoint that will respond to hooks
You then need to setup your ROR app to expose an endpoint that will respond to a POST request.
This endpoint is the same URL that you previously specified when creating the hook
More info at https://docs.shopify.com/api/webhooks/using-webhooks#respond-to-webhook
Notes: You also need to implement a way to verify that requests that you receive through the endpoints came from Shopify, detailed here.
I have a Rails app running on Heroku that uses Mailgun to process incoming emails. I haven't been able to figure how I can debug my email processing locally (on localhost) instead of having to push everything up to heroku every time I make a change. (this is just a test app - I'm the only one using it)
Is it possible to work with Mailgun locally? If so, how do I go about it?
Thank you in advance
Mailgun gives you the option to store a message for later retrieval. If you configure it that way, you'll be able to fetch messages from development for processing without having to set up a publicly-accessible webhook for Mailgun to hit.
But I'm assuming you have production configured with an HTTP endpoint, and it's no fun to do things differently between environments. There are a few tools that will let you set up a public endpoint that routes to localhost:
ngrok, which I've used to good effect to test Twilio. You can set up a permanent subdomain so you don't have to constantly change your Mailgun configuration.
UltraHook, which I haven't personally used, but looks the same.
Localtunnel which looks easiest to start up, but like you get a different host at every boot.
If you have a permanent publicly-accessible server, you can also maintain your own tunnel.
mailgun provides a sandbox that you can use for localhost the only downside to this is that you have to add the test email to valid recipient.
using this gem might be another possible solution:
https://github.com/ryanb/letter_opener/ or https://github.com/fgrehm/letter_opener_web for more advanced features
follow installation from repo
mail will open in new tab
I'm trying to setup my heroku app to have an static IP using QuotaGuard (I know proximo is the other option, but it's pretty expensive).
I added the heroku QuotaGuard Static addon and got the two IPs it generates as well as the proxy url.
What is my next step? (aka how do I tell my Rails app to use the proxy provided by QuotaGuard)
I see they have ruby code samples using REST-client and HTTParty, but do I put that somewhere like in the application.rb??
Most likely a bit too late to answer this question, but still.
Like you said, the first step to configuring QuotaGuard Static is provisioning the addon on Heroku (either via the Web Interface or the Heroku CLI). From there, you are able to get your two outbound IPs, and your proxy URL. The two IPs you were given should be whitelisted on whichever remote service you are trying to access.
As you mentioned, the documentation gives you a couple of samples using Rest Client for Ruby on Rails. This snippet should pretty much go anywhere you want to access whichever resource you need to access via the static IP Addresses. Assuming you want to access a Web Service hosted on an Amazon EC2 instance with elastic IP 1.2.3.4, your would write:
RestClient.proxy = ENV["QUOTAGUARDSTATIC_URL"]
res = RestClient.get("http://1.2.3.4/yourWebService")
And from there process the response stored in res appropriately. This code would go in say whichever controller's method you'll be using to access the remote web service. In this case, you also need to add the Rest Client to your controller, so at the top of that file you shoud also add require "rest-client" . Don't forget to add the rest-client gem to your Gemfile.
Summing up, basically the snippets from the documentation go wherever it is you want to use the proxy to access a remote service requiring a fixed, whitelisted set of IP addresses.
Source: https://devcenter.heroku.com/articles/quotaguardstatic
I am new to Rails and am trying to figure out where I put my API Token for the external API I am using (one of Google's). I have worked with APIs in the past with Sinatra, but the directory structure of Rails has thrown me off with where I need to place it so I can access it in the controller. After I place my token somewhere, I plan on creating a create method in the controller and parsing the json data there so I can access it in my corresponding view. If someone could help guide me in the right direction as to where I put the token so I can access it (best practices), and if I'm on the right track to use the token in a method in the controller so I can access it in a view.
I know this question might be generic but from what I have Googled, many people new to Rails might benefit from this as to where to put things.
You can add your API Tokens under config/initializers. Although, you'll probably have a gem or directions from corresponding API docs telling you what the best way is to implement them. But if you were implement them via an initializer, it would be something like this -
GoogleApi.config do |config|
config.client_id = "<Your Google API Client Id>"
config.client_secret = "<Your Application Secret>"
config.application_name = "<Your Application Name>"
end
And then you'll be able to use GoogleApi in your controllers.
A good example is this guide from heroku to access AWS
I would suggest loading your API keys via a rails initializer. The rails initializers exist in config/initializers and are plain ruby scripts that run after the servers starts up. Here you can do things like load configuration files etc. For example, config/initializers/google_oauth.rb could contain some plain ruby code to load up a config/.yml file holding your API credentials for non-production environments.
In non-production environments, you could load the API tokens from a yml file and in production you could utilize something like Figaro for Heroku or Dotenv for other environments (AWS, DigitalOcean, etc).
The important thing to ensure is that the local configuration file and your API token stay out of version control so as to avoid compromising your token and the security of your application.
I'm building a Rails application that deals with file uploads through CarrierWave. Currently, larger file uploads block the server for a significant amount of time. I have seen solutions like the s3-swf-upload-plugin gem that skip the local server and send files straight from the browser to S3, but this would require some modifications for pre-generating unique filenames and synchronizing them with the database. I'm sure it wouldn't be too much trouble, but Heroku's new Cedar stack gave me the idea of offloading these long running requests to a node.js instance running in the same app. I'm not very experienced with these kinds of things, so excuse my wording if it's a bit off.
Would something like this be possible? How would you configure things such that certain requests (ones involving file uploads, in this case) would be handled by a node app bundled in the same heroku repository as the main rails app?
I don't think it's possible to mix Rails and Node in the same app. However, you could get roughly the same functionality by using two separate apps that communicate with each other.
You can use ENV['DATABASE_URL'] to determine your database connection string. Use the heroku console to set it as an ENV variable for your Node app (e.g. heroku config:add OTHER_DB=your_connection_string) should then be able to use the same connection string to connect to the same database from your other heroku app. You could even access it outside of heroku if you have a dedicated database, see: http://devcenter.heroku.com/articles/external-database-access
For seamless integration between the two apps, you could have a form rendered by the Rails app post to a URL of the Node app. In addition to the file upload, include in that form via hidden input fields any other variables you need to communicate to the Node app. When the upload to the Node app is done, it could redirect the client back to the Rails app, passing any status or variables as get parameters.
Run the two apps under two subdomains of the same domain and you could even share cookies between them.
You need two apps. I am doing exactly what's described in this question. I wanted large streaming uploads, and since Rack writes downloads to a temp file before passing them through to the handler, it is not possible to do this with Rails.
Node.js, on the other hand, does this beautifully. So there are two Heroku apps, the Rails web app and the Node.js (Express) web app. The Rails web app uses SWFUpload as the client-side solution. The Rails app and the Node.js app both have a secret key as a Heroku config variable. When it's time for the user to upload, client-side Javascript requests an upload URL from the Rails server. The Rails server forms an upload URL with an Expires parameter and computes a signature using the secret key. The client-side Javascript handler passes this URL along to SWFUpload (upload_url property). The user selects the files to upload, and SWFUpload starts posting them to the upload_url. The Node.js app verifies that the URL is not expired and that the signature is valid. It processes the form data with the formidable library.
One other detail. Flash requires the Node.js app to serve a crossdomain.xml that permits the cross-site request.
My Node.js app doesn't touch the database; but if it did I would share DATABASE_URL as previously suggested. Note that you can't share a DATABASE_URL outside of Heroku unless you have a dedicated DB. The DATABASE_URLs for shared databases are not reachable from outside Heroku (unlike some other services like RedisToGo).