Rails: How to disable app after certain amount of usage - ruby-on-rails

I have a Rails/Shopify app that processes orders from the User's Shopify store. I want to have tiered plans (e.g. Bronze < 20 orders, Silver < 100 orders, Gold 100+).
What's the best way to implement this?
1) How do I track which subscription plan they are on, when it changes etc?
2) How do I disable the app once a user hits their limit?
Any links to articles/tutorials/gems to help would be great.

I would do it the following way. Once you have the token you can access the application charges for the shop you're in. You could either use
GET /admin/recurring_application_charges/455696195.json
or like I use it
ShopifyAPI::RecurringApplicationCharges.current
which gets you the current plan the user is on. You can access the name of the plan etc. To track how many orders were processed I would write a controller and implement a simple counter. Each time a request is being sent the counter is incremented. Once the limit is reached you can redirect him to an error page or somewhere else.
To answer the second part of your question you could access the current charge as mentioned above and get all the information you need (e.g. "billing_on": "2015-03-27T00:00:00+00:00")
Here is a sample response with all the available fields:
HTTP/1.1 200 OK
{
"recurring_application_charge": {
"activated_on": null,
"api_client_id": 755357713,
"billing_on": "2015-03-27T00:00:00+00:00",
"cancelled_on": null,
"created_at": "2015-03-28T13:31:19-04:00",
"id": 455696195,
"name": "Super Mega Plan",
"price": "15.00",
"return_url": "http:\/\/yourapp.com",
"status": "pending",
"test": null,
"trial_days": 0,
"trial_ends_on": null,
"updated_at": "2015-03-28T13:31:19-04:00",
"decorated_return_url": "http:\/\/yourapp.com?charge_id=455696195",
"confirmation_url": "https:\/\/apple.myshopify.com\/admin\/charges\/455696195\/confirm_recurring_application_charge?signature=BAhpBENfKRs%3D--a911ece9470850c96f6c7735c684b8a3f6869594"
}
}
You can find more under https://docs.shopify.com/api/recurringapplicationcharge or https://docs.shopify.com/api/applicationcharge
Hope I could help

Related

ErrorItemNotFound when trying to retrieve room calendar via MS Graph API

Next to retrieving calendar views of a user's calendar (on behalf of the user), we are trying hard to also get the calendar view of rooms via the Graph API using
https://graph.microsoft.com/beta/users/room1#ourdomain.com/calendarView. It's a painful process since we've been running into many problems and are currently stuck with the following 404 response:
https://graph.microsoft.com:443/v1.0/users/room1#ourdomain.com/calendarView?startDateTime=2018-12-04T23:00:00.000Z&endDateTime=2019-02-10T22:59:59.999Z
{
"error": {
"code": "ErrorItemNotFound",
"message": "The specified object was not found in the store.",
"innerError": {
"request-id": "358a003a-57a4-4f0e-91da-edc17c1fa2d8",
"date": "2018-12-12T07:38:33"
}
}
}
The email address of the room has been double checked and the resource exists, since we can create appointments with it and it is even being returned in the response when we retrieve the calendar of the user who has an appointment in that location.
App permissions and OAuth2 scopes are set to: openid email profile offline_access https://graph.microsoft.com/Calendars.Read https://graph.microsoft.com/Calendars.Read.Shared https://graph.microsoft.com/User.Read
https://graph.microsoft.com/User.ReadBasic.All https://graph.microsoft.com/User.Read.All, so that should not be an issue, judging by the documentation.
Does anyone know how to solve this?
I've tried all possible ways, but there is no way to get access.
This is what I've tried out the following in the Graph explorer:
https://graph.microsoft.com/v1.0/users/meetingroom1#domain.com/events -> DelegatedCalendarAccessDenied
https://graph.microsoft.com/v1.0/users/meetingroom1#domain.com/calendarView?startDateTime=2019-01-14&endDateTime=2019-01-18 -> ErrorItemNotFound
https://graph.microsoft.com/v1.0/users/meetingroom1#domain.com/calendar/calendarView?startDateTime=2019-01-14&endDateTime=2019-01-18 -> ErrorItemNotFound
All three on both the v1.0 and the beta.
It isn't an issue with rights, because for my testing I granted the Graph Explorer the Directory.ReadWrite.All scope. Resulting in the following scp claim.
The first requests seems the most promising (because of the different error), I also made myself a delegate with full control of the rooms-mailbox. That still didn't help.
A request to https://graph.microsoft.com/v1.0/users/meetingroom1#domain.com gives a result, as in a result describing the meetingroom.
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
"businessPhones": [],
"displayName": "Meeting room 1",
"givenName": null,
"jobTitle": null,
"mail": "meetingroom1#domain.com",
"mobilePhone": null,
"officeLocation": null,
"preferredLanguage": null,
"surname": null,
"userPrincipalName": "meetingroom1#domain.com",
"id": "3e0a7b7e-xxxx-xxxx-xxxx-xxxxcxxxx120"
}
After doing all these tests, I can only conclude that you cannot access the events in a rooms mailbox. This is either intended (as in only use the scheduling assistant) or a bug.
Maybe some of the Microsoft guys around here could clarify this?
FINALLY! After going through this with countless Microsoft support people, each of whom said this was not their territory and did not know where to forward the question, I got in touch with somebody from the Exchange team. He suggested the one thing that worked for us: the user on behalf of which you are retrieving the room resource calendar needs to be a delegate of that room resource!
In addition, to retrieve the list of room resources which the user can select from, we needed to use the findRooms endpoint but this only works on the beta API. The only drawback of this is that you cannot seem to filter for rooms of which the user is a delegate. So the user will get a list of rooms for which he might or might not be able to retrieve the calendar.
A final drawback of the room resource calendarView response is that the response does not contain the names of the meetings planned in the rooms. The description of each event only contains the name of the meeting organizer.

Getting Rating for an App from Apple AppStore

I want to create a report regarding my App's rating in three dimensions - date, Country and App Version (I know that from Android I can get in a query only Date+Another Dim, not quite sure how it works with Apple...). I found the "Reporter" (https://help.apple.com/itc/appsreporterguide/#/itcbd9ed14ac) but it allows me only finance reports... I also saw the RSS option - only this option gives me the "last X reviews"' and I just want an aggregated data (lets say - for each day, how many 1 star rating, 2 star rating etc'...)
If someone can help me with how to do so (preferably in bash/python script), I'd really appriciate it. Thank you!
The easiest way to get them out of iTunes Connect is probably with Spaceship. (App > Activity > Ratings & Reviews
# Get reviews for a given store front
reviews = ratings.reviews("US") # => Array of hashes representing review data
https://github.com/fastlane/fastlane/blob/master/spaceship/docs/iTunesConnect.md#app-ratings--reviews
The Appfigures API can give you ratings and reviews for iOS and Android apps.
The following request will give you the last 50 reviews from any country, but you can easily get more reviews, limit by country/version/etc.
GET https://api.appfigures.com/v2/reviews?count=50
While will give you something like this:
{
"total": 140,
"pages": 28,
"this_page": 1,
"reviews": [{
"author": "DeveloperToDeveloper",
"title": "Just Spectacular",
"review": "Finally able to remove the ads! The description is hilarious!! Thanks!!!",
"original_title": null,
"original_review": null,
"stars": "5.00",
"iso": "US",
"version": "1.2",
"date": "2017-05-19T17:05:00",
"product": 6567539,
"weight": 0,
"id": "5561747L7xnbsMRu8UbPvy7A71Dv6A=="
}]
}
Here's how you'd do it with Python:
import requests
USERNAME = 'USERNAME'
PASSWORD = 'PASSWORD'
APP_KEY = 'APP_KEY'
BASE_URI = "https://api.appfigures.com/v2/"
# Helper function for auth and app_key
# first / in uri is optional
def make_request(uri, **querystring_params):
headers = {"X-Client-Key": APP_KEY}
auth =(USERNAME, PASSWORD)
return requests.get(BASE_URI + uri.lstrip("/"),
auth=auth,
params=querystring_params,
headers=headers)
# Get the last 50 reviews for all of our apps
reviews_response = make_request("/reviews",
count=50)
assert 200 == reviews_response.status_code
assert 0 < len(reviews_response.json())
# Use the response to sum up ratings, analyze review text, etc.
FYI - Reviews and ratings are separate for apps, and while the 5 star rating on a review contributes to the total rating, there could also be ratings that aren't associated with a written review.
Those can be retrieved using the Ratings route.

Error in getting topic title in D2L

So I am trying to get the quiz names from course in D2L using this API GET /d2l/api/le/(version)/(orgUnitId)/content/topics/(topicId) http://docs.valence.desire2learn.com/res/content.html#get--d2l-api-le-(version)-(orgUnitId)-content-topics-(topicId)
But I am response which has wrong topic 'Title' field.
GET /d2l/api/le/1.4/6671/content/topics/1134
Response:
{
"DueDate": null,
"TopicType": 3,
"Url": "/d2l/common/dialogs/quickLink/quickLink.d2l?ou=66xx&type=quiz&rCode=1A4DE57C-F-3xx",
"StartDate": null,
"EndDate": null,
"IsHidden": false,
"IsLocked": false,
"Id": 1134,
"Title": "/d2l/common/dialogs/quickLink/quickLink.d2l?ou={orgUnitId}&type=quiz&rCode=1A4DE57C-F-3xx",
"ShortTitle": "",
"Type": 1
}
I created this quiz directly from course module --> new --> new quiz. But If I create quiz from Quizzes (Top menu) --> Manage Quiz --> New quiz. Then I get correct Title. Do I need to add some settings in quiz to get correct Title? Is there better way to get names?
We are running v10.3 of LMS
Unfortunately, this is a known issue, and will be addressed with due priority but D2L currently does not have an expected timeline for fixing it. If you'd like to track the status of this issue, or lobby for an increased priority on this issue, D2L encourages you to do so via your account or partner manager, or approved support contact.

YouTube API - No channel branding settings returned for queries by username

When using the YouTube API v3 to query a channel's branding settings, why are they returned for queries by channel ID, but not for queries by username? The API doesn't return branding settings for channel list queries by username.
If you query for a channel's branding settings by channel ID (e.g., id=UC8-Th83bH_thdKZDJCrn88g), you are returned a complete set of branding settings:
Google API Explorer: https://developers.google.com/youtube/v3/docs/channels/list
Request
GET https://www.googleapis.com/youtube/v3/channels?part=brandingSettings&id=UC8-Th83bH_thdKZDJCrn88g&key={YOUR_API_KEY}
Response
{
// ... snip ...
"items": [
{
"kind": "youtube#channel",
"etag": "\"...\"",
"id": "UC8-Th83bH_thdKZDJCrn88g",
"brandingSettings": {
"channel": {
"title": "The Tonight Show Starring Jimmy Fallon",
"description": "Watch The Tonight Show Starring Jimmy Fallon Weeknights 11:35/10:35c\n\nThe Tonight Show Starring Jimmy Fallon features hilarious highlights from the show including: comedy sketches, music parodies, celebrity interviews, ridiculous games, and, of course, Jimmy's Thank You Notes and hashtags! You'll also find behind the scenes videos and other great web exclusives.",
// all the branding settings are here
}
}
}]
}
If, on the other hand, you send a channel list query for a username (e.g., forUsername=latenight), you get no branding settings at all. The branding settings aren't returned or populated.
Request
GET https://www.googleapis.com/youtube/v3/channels?part=brandingSettings&forUsername=latenight&key={YOUR_API_KEY}
Response
{
// ... snip ...
"items": [
{
"kind": "youtube#channel",
"etag": "\"...\"",
"id": "UC8-Th83bH_thdKZDJCrn88g"
}]
}
I may be wrong, but I believe that, in v3 of the APIs, Channel IDs are the only way to get a full response, as the concept of a "username" doesn't really exist in the same way anymore. That is, newly created YouTube channels are linked to a G+ profile and can have a display name, but there isn't really any YouTube username anymore associated with such a channel.
Because usernames used to exist, though, and many channels are still known by them, the "forUsername" parameter is there to provide you the associated channelID and then issue the request for the branding settings with that.
Now, having said that, it's clear that the language on the API explorer page doesn't reflect that, and perhaps therein lies the problem; I'm taking my inferences from this documentation:
https://developers.google.com/youtube/v3/guides/working_with_channel_ids#v3
and from this bug report:
https://code.google.com/p/gdata-issues/issues/detail?id=4821&q=forUsername&colspec=API%20ID%20Type%20Status%20Priority%20Stars%20Summary
But it's always possible, too, that I'm reading incorrectly and you're actually seeing a new bug. The only way to know for sure would be to file it (or perhaps someone on the team could comment here)?

Restkit: How to get and map data from multiple source

I'm currently working on iOS Application with RestKit 0.20 to access data from Tastypie API.
And I am trying to get feeds data from URL like this
/api/v2/feed/?format=json
Then I will get array of feeds as below.
{
"meta": {
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 2
},
"objects": [
{
"id": 1,
"info": "This is my first post",
"pub_date": "2013-02-03T15:59:33.311000",
"user": "/api/v2/user/1/",
"resource_uri": "/api/v2/feed/1/"
},
{
"id": 2,
"info": "second post, yeah",
"pub_date": "2013-02-03T16:00:09.350000",
"user": "/api/v2/user/1/",
"resource_uri": "/api/v2/feed/2/"
}
]
}
if I want to fetch more data about user which Tastypie send it as url like a foreign key "user": "/api/v2/user/1/", do I have to nested call objectRequestOperation.
I'm confusing because I'm using block to callback when data is successful loaded. So is there any better way than requesting user data again for each feed after requesting feed complete.
Thank you very much :)
You have to define in the Feed resource :
user = fields.ToOneField(UserResource, full=True)
More info in the tastypie doc http://django-tastypie.readthedocs.org/en/latest/resources.html
Why Resource URIs?
Resource URIs play a heavy role in how Tastypie delivers data. This can seem very different from other solutions which simply inline related data. Though Tastypie can inline data like that (using full=True on the field with the relation), the default is to provide URIs.
URIs are useful because it results in smaller payloads, letting you fetch only the data that is important to you. You can imagine an instance where an object has thousands of related items that you may not be interested in.
URIs are also very cache-able, because the data at each endpoint is less likely to frequently change.
And URIs encourage proper use of each endpoint to display the data that endpoint covers.
Ideology aside, you should use whatever suits you. If you prefer fewer requests & fewer endpoints, use of full=True is available, but be aware of the consequences of each approach.

Resources