A blog about productivity, workflow best practices, company building and how to get things done with less work.

 

Entries Tagged “API Quirks”

Magento is a bundle of e-commerce awesome, especially when paired with over 180 Zapier services. However, getting Magento to talk to Zapier services fluently can be tricky – at first.

In this post we’ll talk about how to authenticate with Magento.

Getting Started

Before creating a zap using Magento, log on to your Magento Admin site (i.e., www.magentosite.com/admin) and create a new SOAP/ XML-RPC role and user (see screen shot below).

Magento Admin

References:

Learn how to create a role here.

Learn how to create a user here.

Setting up your zap

When complete, you’ll need three things to successfully authenticate with Magento from Zapier: a user name, API key, and (most important) the correct URL to your Magento web site.

Make sure to use the username and API Key created in the Magento's admin console on the SOAP/XML-RPC user page. As far as URL, typically you'd use, for example, one of the following options:

  1. http://magentosite.com
  2. https://magnetosite.com
  3. http://magentosite.com/index.php
  4. https://magnetosite.com/index.php

If you learn that using option 3 or 4 works and is required to authenticate with Magento, this is because of Magento htaccess configuration settings. To get rid of the "index.php" as part of your URL, you can get insight here. Otherwise, it's safe to keep it as-is.

Although brief, you now have ammunition to resolve most issues when authenticating Magento with Zapier. If you still have problems, let us know at contact@zapier.com and will also make sure to update this post.

Note: We test zaps using Magento Community Edition version 1.7.02. If you have an older version of Magento, we advise upgrading to 1.7.0.2 or newer.

About the Author

Royce Haynes is a web engineer originally from Kansas City.

I won't rag on Unleashed too much as their API is in beta, but there are a few problems that exhausted a lot of my time that I thought I'd cover in a quick post. If you'd like the quick version of my advice:

Don't use their JSON API yet (11/25/2012), suck it up and do XML.

First of all, you'll need to generate your own UUID's. This isn't particularly hard (we use Python's import uuid library), but did throw me for a loop at first. Also, the guid's you generate need to be put in both the URL and the XML you POST.

Next, the JSON formatting of dates is very bizarre (at least at the time of writing). They opt for \/Date(1331550000000)\/ which I assume is milliseconds from epoch? Further, their JSON API doesn't serialize errors very well (read: at all). You'll see a lot of 403: Bad Request with no further details provided. However, their XML API does just fine! So, don't use JSON.

Next, some keys they say are required, aren't (and some they say aren't required, are). The best way around that is to do a few sample POSTs with more or less empty XML. Then you can start adding elements as they return missing key errors. (Be sure to use XML, not JSON!)

Finally, they also let you define related sub elements by various identifiers. For example, you don't need to include the guid of a product: you can alternatively include the code or name instead.


About the "API Quirks" Blog Series

Everyone at Zapier has to deal with API Quirks. We deal with so many APIs each day, we have become almost immune to the often bizarre, undocumented, frustrating behavior exhibited by web APIs. You can see all the posts in this series here. No API or documentation is static. Take any quirks published before "today" with a grain of salt.

Don't want to worry about this? Connect to Unleashed with Zapier

About the Author

Bryan Helmig is a co-founder and developer at Zapier, self-taught hacker, jazz/blues musician and fine beer and whiskey lover.

We use SQLAlchemy at Zapier to handle external database connections to things like MySQL, MSSQL, PostgreSQL, and others. For example, you could set up a Zap to add a new row into your database table every time someone tweets a specific word. Or archive tickets from JIRA into your in-house database.

We ran into a problem with our MSSQL connector recently. If you were using a username or password with a plus sign (+) in it, you could not connect. A quick search leads us to this solution. This works well to properly URL encode the plus sign when you are using standard built in SQLAlchemy connection strings (to MySQL, for example).

In our case, we are running SQLAlchemy on Ubuntu and need to rig up FreeTDS and PyODBC. You must use a special SQLAlchemy connection string to pass along extra variables, shown here:

mssql+pyodbc:///?odbc_connect=dsn%3Dmydsn%3BDatabase%3Ddb

Notice that the actual variables are encoded into the odbc_connect query parameter. Naturally, I encoded my username and password into the odbc_connect parameter. The problem is that the odbc_connect parameter gets decoded twice. Normally SQLAlchemy connection strings get decoded once. The "quick answer" article above alludes to this. The second decode happens because the odbc_connect parameter has its own data structure (dsn=mydsn;Database=db). Presumably the odbc_connect parameter was added at a later time without consider how odd it is to double URL encode things.

About that plus sign... A plus sign "+" is encoded as "%2B". Decoded gives you back "+". Decoding a second time gives you a space " " (by definition of the URL encoding scheme for plus signs which are treated specially). So the proper way to handle this it to URL encode the odbc_connect parameter twice! Plus signs "+" end up as "%252B". This results in an incorrect password being sent to the server.

Here is the proper, working code to generate a mssql+pyodbc SQLAlchemy connection:

fields = {
  'host': 'database.host.com'
  'username': 'myusername'
  'password': 'password+with+a+plus!'
  'port': '1433'
}
db_url = 'mssql+pyodbc:///?odbc_connect=' + urllib.quote_plus(urllib.quote_plus('DRIVER={{FreeTDS}};SERVER={host};DATABASE={database};UID={username};PWD={password};port={port};TDS_Version=8.0;'.format(fields)
connection = create_engine(db_url, connect_args={'convert_unicode': True})


About the "API Quirks" Blog Series

Everyone at Zapier has to deal with API Quirks. We deal with so many APIs each day, we have become almost immune to the often bizarre, undocumented, frustrating behavior exhibited by web APIs. You can see all the posts in this series here. No API or documentation is static. Take any quirks published before "today" with a grain of salt.

Don't want to worry about this? Connect to MSSQL with Zapier

About the Author

Mike Knoop is a Co-founder at Zapier. He helps run product and love the color orange.

Introducing "API Quirks"

Everyone at Zapier has to deal with API Quirks. We deal with so many APIs each day, we have become almost immune to the often bizarre, undocumented, frustrating behavior exhibited by web APIs. Our goal with this series is to document some of the most time-consuming things we run into. Considering the short-form nature of many solutions (and the amount of quirks we run into), you can expect this series to grow quickly! You will be able to access all the posts in this series here.

Naturally, most of the content will be time-sensitive. No API or documentation is static. Take any quirks published before "today" with a grain of salt!

Yammer External Networks

Yammer, a Facebook-like product for the enterprise, allows users to join several networks (maybe a work network, and professional network). There is always a primary network which the default OAuth access_token will allow you access to.

The Yammer API documentation is not clear about how you go about reading or writing to an External Network which the current authorized user has access to. It is actually easy:

  • You'll need to have already performed the standard Yammer OAuth song-and-dance to obtain the base accecss_token for the user. Next, request a list of access_tokens for all External Networks associated with the currently authorized user.

    GET https://www.yammer.com/api/v1/oauth/tokens.json?access_token=...

  • The returned results will be a list of dictionaries. There may be duplicate access_tokens per network. You will likely want to de-duplicate off of network_id or network_permalink to end up with only one valid access_token per External Network. Assuming the JSONified contents of the above URL exist in the variable json, you can do something like (Python):

    external_networks = []
    
    def ids(external_networks):
        ret = []
        for each in external_networks:
            ret.append(each.get('network_id', None))
        return ret
    
    for each in json:
        if each.get('network_id', None) not in ids(external_networks):
            network = {
                'network_permalink': each.get('network_permalink', None),
                'network_name': each.get('network_name', None),
                'network_id': each.get('network_id', None),
                'token': each.get('token', None),
            }
            external_networks.append(network)
    
    print external_networks # [{...}, {...}]
    

... to obtain a final array of External Networks and their associated access_tokens

Don't want to worry about this? Use Yammer Triggers and Actions on Zapier

About the Author

Mike Knoop is a Co-founder at Zapier. He helps run product and love the color orange.

Get help