Skip to content

Commit 006689c

Browse files
jiblitsJesse MacFadyen
authored andcommitted
PhoneGap wrapper around Shopify4J to make authenticated API calls
to the Shopify API from Javascript
1 parent ca39b2c commit 006689c

File tree

3 files changed

+279
-0
lines changed

3 files changed

+279
-0
lines changed

Android/ShopGap/README.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# ShopGap plugin for Android/Phonegap
2+
3+
Chris Saunders // @csaunders
4+
5+
## About
6+
7+
ShopGap is a wrapper around [Shopify4J](http://github.com/shopify/Shopify4J) to allow you to make Authenticated API calls to the Shopify API.
8+
9+
## Dependencies
10+
11+
You will need to include Shopify4J and all of it's dependencies in your project in order for this tool to work. This should be as simple as adding Shopify4J as a Library in your Android configuration.
12+
13+
## Using the plugin
14+
15+
**This has been developed against PhoneGap 1.1.0**
16+
17+
* Add java code to your projects source
18+
19+
* Register the plugin in the plugins.xml file
20+
21+
```xml
22+
<plugin name="ShopGapPlugin" value="ca.christophersaunders.shopgap.ShopGapPlugin" />
23+
```
24+
25+
* Setup your authenticated session with the Shopify API
26+
27+
```javascript
28+
window.plugins.shopGap.setup(
29+
'YOUR_API_KEY',
30+
'GENERATED_API_PASSWORD',
31+
'SHOP_NAME',
32+
successFunctionOrNull,
33+
failureFunctionOrNull
34+
);
35+
```
36+
37+
* Make calls to the Shopify API
38+
39+
```javascript
40+
var success = function(resultJson){
41+
console.log(JSON.stringify(resultJson));
42+
}
43+
44+
window.plugins.shopGap.read(
45+
'products', // endpoint
46+
null, // query -- not supported yet
47+
null, // data -- not needed for GET requests
48+
function(r){success(r);}, // success callback
49+
function(e){console.log}); // failure callback
50+
```
51+
52+
### Endpoints
53+
54+
The plugin takes care of most of the work for the endpoints, all you need to
55+
do is fill in a few missing pieces.
56+
57+
```javascript
58+
// get all products,
59+
window.plugins.shopGap.read('products', null, null, s, f);
60+
61+
// get product 1
62+
window.plugins.shopGap.read('products/1', null, null, s, f);
63+
64+
// create product
65+
window.plugins.shopGap.create('products', null, JSON.stringify(newProduct), s, f);
66+
67+
// update product 1
68+
window.plugins.shopGap.update('products/1', null, JSON.stringify(updateProduct), s, f);
69+
70+
// delete product 1
71+
window.plugins.shopGap.destry('products/1', null, null, s, f);
72+
```
73+
74+
## Release Notes
75+
76+
0.1.0 Initial Release
77+
78+
## License
79+
80+
The MIT License
81+
82+
Copyright (c) 2011 Chris Saunders
83+
84+
Permission is hereby granted, free of charge, to any person obtaining a copy
85+
of this software and associated documentation files (the "Software"), to deal
86+
in the Software without restriction, including without limitation the rights
87+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
88+
copies of the Software, and to permit persons to whom the Software is
89+
furnished to do so, subject to the following conditions:
90+
91+
The above copyright notice and this permission notice shall be included in
92+
all copies or substantial portions of the Software.
93+
94+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
95+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
96+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
97+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
98+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
99+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
100+
THE SOFTWARE.

Android/ShopGap/ShopGapPlugin.java

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package ca.christophersaunders.shopgap;
2+
3+
import java.io.BufferedInputStream;
4+
import java.io.ByteArrayOutputStream;
5+
import java.io.IOException;
6+
import java.io.InputStream;
7+
import java.io.StringReader;
8+
9+
import org.json.JSONArray;
10+
import org.json.JSONException;
11+
import org.json.JSONObject;
12+
13+
import com.phonegap.api.Plugin;
14+
import com.phonegap.api.PluginResult;
15+
import com.phonegap.api.PluginResult.Status;
16+
import com.shopify.api.client.ShopifyClient;
17+
import com.shopify.api.credentials.Credential;
18+
import com.shopify.api.endpoints.JsonPipeService;
19+
20+
public class ShopGapPlugin extends Plugin {
21+
private static final String API_KEY = "apikey";
22+
private static final String PASSWORD = "password";
23+
private static final String SHOPNAME = "shopname";
24+
private static final String CALL = "call";
25+
private static final String ENDPOINT = "endpoint";
26+
private static final String QUERY = "query";
27+
private static final String DATA = "data";
28+
29+
private ShopifyClient client;
30+
private JsonPipeService service;
31+
32+
enum Methods { CALL_API, SETUP };
33+
enum Call { READ, CREATE, UPDATE, DESTROY };
34+
35+
@Override
36+
public PluginResult execute(String func, JSONArray arguments, String callbackId) {
37+
try {
38+
JSONObject argsMap = arguments.getJSONObject(0);
39+
switch(determineMethod(func)) {
40+
case CALL_API:
41+
JSONObject results = callAPI(determineCall(argsMap.getString(CALL)), argsMap);
42+
return new PluginResult(Status.OK, results);
43+
case SETUP:
44+
if(setupClient(argsMap)) {
45+
return new PluginResult(Status.OK);
46+
}
47+
break;
48+
default:
49+
return new PluginResult(PluginResult.Status.INVALID_ACTION);
50+
}
51+
} catch (JSONException e) {
52+
// Trololololololo
53+
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
54+
}
55+
return null;
56+
}
57+
58+
private Methods determineMethod(String name){
59+
if(name.equals("callapi"))
60+
return Methods.CALL_API;
61+
if(name.equals("setup"))
62+
return Methods.SETUP;
63+
return null;
64+
}
65+
66+
private Call determineCall(String callname) {
67+
if(callname.equals("read"))
68+
return Call.READ;
69+
if (callname.equals("update"))
70+
return Call.UPDATE;
71+
if (callname.equals("create"))
72+
return Call.CREATE;
73+
if (callname.equals("destroy"))
74+
return Call.DESTROY;
75+
return null;
76+
}
77+
78+
private boolean setupClient(JSONObject args) throws JSONException {
79+
if (args.has(API_KEY) && args.has(PASSWORD) && args.has(SHOPNAME)) {
80+
String apiKey = args.getString(API_KEY);
81+
String passwd = args.getString(PASSWORD);
82+
String shop = args.getString(SHOPNAME);
83+
84+
Credential cred = new Credential(apiKey, "", shop, passwd);
85+
client = new ShopifyClient(cred);
86+
service = client.constructService(JsonPipeService.class);
87+
return true;
88+
}
89+
return false;
90+
}
91+
92+
private JSONObject callAPI(Call call, JSONObject args) {
93+
try {
94+
String endpoint = null, data = null, query = null;
95+
if(args.has(ENDPOINT))
96+
endpoint = args.getString(ENDPOINT);
97+
if(args.has(QUERY))
98+
query = args.getString(QUERY);
99+
if(args.has(DATA))
100+
data = args.getString(DATA);
101+
102+
InputStream result = null;
103+
104+
switch(call) {
105+
case CREATE:
106+
result = service.create(endpoint, data);
107+
break;
108+
case READ:
109+
result = service.read(endpoint);
110+
break;
111+
case UPDATE:
112+
result = service.update(endpoint, data);
113+
break;
114+
case DESTROY:
115+
result = service.destroy(endpoint);
116+
break;
117+
}
118+
119+
if( result != null) {
120+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
121+
BufferedInputStream bis = new BufferedInputStream(result);
122+
byte[] resultData = new byte[0x4000];
123+
int dataRead = 0;
124+
while((dataRead = bis.read(resultData)) > 0) {
125+
baos.write(resultData, 0, dataRead);
126+
}
127+
return new JSONObject(new String(baos.toByteArray()));
128+
}
129+
130+
} catch (JSONException e) {
131+
e.printStackTrace();
132+
} catch (IOException e) {
133+
e.printStackTrace();
134+
}
135+
return new JSONObject();
136+
}
137+
138+
}

Android/ShopGap/shopgap.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
var ShopGap = function(){};
2+
3+
ShopGap.prototype.setup = function(apiKey, password, shopname, onSuccessFn, onFailureFn){
4+
var args = {'apikey': apiKey, 'password': password, 'shopname': shopname};
5+
return PhoneGap.exec(onSuccessFn, onFailureFn, 'ShopGapPlugin', 'setup', [args]);
6+
};
7+
8+
ShopGap.prototype.consArgs = function(call, endpoint, query, data){
9+
return {call: call, endpoint: endpoint, query: query, data: data};
10+
};
11+
12+
ShopGap.prototype.read = function(endpoint, query, data, success, failure){
13+
return this.callapi(this.consArgs('read', endpoint, query, data), success, failure);
14+
};
15+
16+
ShopGap.prototype.update = function(endpoint, query, data, success, failure){
17+
return this.callapi(this.consArgs('update', endpoint, query, data), success, failure);
18+
};
19+
20+
ShopGap.prototype.create = function(endpoint, query, data, success, failure){
21+
return this.callapi(this.consArgs('create', endpoint, query, data), success, failure);
22+
};
23+
24+
ShopGap.prototype.destroy = function(endpoint, query, data, success, failure){
25+
return this.callapi(this.consArgs('destroy', endpoint, query, data), success, failure);
26+
};
27+
28+
ShopGap.prototype.callapi = function(args, onSuccessFn, onFailureFn){
29+
return PhoneGap.exec(onSuccessFn, onFailureFn, 'ShopGapPlugin', 'callapi', [args]);
30+
};
31+
32+
/*
33+
ShopGap.prototype.callapi = function(call, endpoint, query, data, onSuccessFn, onFailureFn){
34+
var args = {'endpoint': endpoint, 'data': data, 'query': query};
35+
return PhoneGap.exec(onSuccessFn, onFailureFn, 'ShopGapPlugin', 'callapi', [args]);
36+
};
37+
*/
38+
39+
PhoneGap.addConstructor(function(){
40+
PhoneGap.addPlugin('shopGap', new ShopGap());
41+
});

0 commit comments

Comments
 (0)