npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

infusionsoft-api

v0.6.0

Published

Javscript wrapper for the Infusionsoft API

Downloads

200

Readme

Infusionsoft API

A promise-driven, fluent-style Node.js wrapper for the XML-RPC Infusionsoft API.

Write badass Infusionsoft apps on the server that are fully and natively asynchronous.

It's pretty dope.

Usage

Install via npm:

$ npm install infusionsoft-api

Do cool stuff:

var api = require('infusionsoft-api');

var infusionsoft = new api.DataContext('myapp', 'MY_API_KEY');

infusionsoft.Contacts
    .where(Contact.FirstName, 'Brandon')
    .like(Contact.LastName, 'V%')
    .select(Contact.Id, Contact.Email)
    .orderByDescending('LastName')
    .take(100)
    .toArray()
    .done(function(result) {
        console.log(result);
    });

You can also use the API Services directly:

infusionsoft.ContactService
    .findByEmail('[email protected]', ['Id', 'FirstName', 'LastName']);

Awesome.

Promises

All asynchronous methods return a Promise that represents the eventual value that will be returned.

Promises are glorious and make writing heavily asynchronous code much less awful than it would otherwise be.

See the More Examples section to see them in action.

API Scraper

This project creates interfaces and classes for the API services and tables via the grunt-infusionsoft grunt plugin. To recreate the generated files, run grunt infusionsoft.

Check out the infusionsoft directory to see the output.

More Examples

All examples use infusionsoft as an instantiated DataContext with your app name and API key. ie:

var infusionsoft = new api.DataContext('myAppName', 'MY_API_KEY');

Get monthly revenue from a particular month

infusionsoft.Payments
    .like(Payment.PayDate, '2013-06%')
    .sum(function(x) { return x.PayAmt; })
    .done(function(total) {
        console.log('total revenue: ' + total);
    });

Login a user and get their info

And an example of using the fail method to catch any problems.

infusionsoft.DataService
    .authenticateUser('[email protected]', 'md5-hash-of-password')
    .then(function(userId) {
        return infusionsoft.Users.where(User.Id, userId).first();
    })
    .then(function(user) {
        console.log('Hello ' + user.FirstName + ' ' + user.LastName);
    })
    .fail(function(err) {
        console.log('uh oh: ' + err);
    });

Get all invoices for a specific month, grouped by product

Uses underscore.

infusionsoft.Invoices
    .like(Invoice.DateCreated, '2013-08%')
    .groupBy(function(x) { return x.ProductSold; })
    .done(function(result) {
        _(result).each(function(invoices, productId) {
            console.log(productId, invoices.length);
        });
    });

Same as above, but use the spread function to wait on 2 promises to get the corresponding product names. The API hits for querying both the Product table and the Invoice table will actually fire off at the same time.

Hashtag asynchronous.

var products = infusionsoft.Products.toArray();
var invoices = infusionsoft.Invoices
    .like(Invoice.DateCreated, '2013-08%')
    .groupBy(function(x) { return x.ProductSold; });

Q.spread([products, invoices], function(products, invoices) {
   _(invoices).each(function(invoices, productId)  {
        var productName = _(products)
            .find(function(x) { return x.Id == productId; })
            .ProductName;

        console.log(productName, invoices.length);
   });
});

From an email address, get a contact's tags

sdk.Contacts
    .where(Contact.Email, '[email protected]')
    .first()
    .then(function(contact) {
        return sdk.ContactGroupAssigns
            .where(ContactGroupAssign.ContactId, contact.Id)
            .toArray();
    })
    .then(function(cgas) {
        cgas.forEach(function(group) {
            console.log(group.ContactGroup, group.DateCreated);
        });
    });

Get the full Product Category Name for all subscription plans

Okay, take a deep breath. We can do (inner) joins. We fake it though... the inner part of the join has to be loaded entirely and then we do a O(n^2) iteration to make it, but we can still do it. If the inner is cheap, this isn't too bad. Especially when the SDK will handle loading, paging, waiting, etc... all for you.

Syntax (stolen from C#'s LINQ):

join (innerQueryable, outerKey, innerKey, selectorFn)

Let's do this:

var pc    = infusionsoft.ProductCategories;
var pca   = infusionsoft.ProductCategoryAssigns;
var plans = infusionsoft.SubscriptionPlans;

// Join the categories onto itself for creating the full category name
// (category parent name + category name)
var categories = pc
    .join(pc, 'ParentId', 'Id', function(pc, parent) {
        return {
            Id: pc.Id,
            Name: parent.CategoryDisplayName + ' ' + pc.CategoryDisplayName
        }; });

var subPlans = plans

    // Join the sub plan (which only has product Id) onto the PCA table to get
    // the product category ID
    .join(pca, 'ProductId', 'ProductId', function(plan, pca) {
        plan.ProductCategoryId = pca.ProductCategoryId;
        return plan;
    })


    // Join our categories object we made above onto the projection from the
    // most recent join to get the full category name + subscription plan Id
    .join(categories, 'ProductCategoryId', 'Id', function(plan, category) {
        return { planId: plan.Id, category: category.Name }; });

subPlans.toArray().done(function(d) { console.log(d); });

What happens magically behind the scenes is pretty nice. When we call toArray() at the end, we first query the SubscriptionPlan table (aliased as plans). It then knows we need to join the ProductCategoryAssign table on there, so it fetches that (which may be more than one page). It finally gets the ProductCategory table (in its entirety), and joins them all up.

The syntax looks nasty, but that is somewhat unavoidable with a join function.

License

Copyright 2013 Brandon Valosek

Infusionsoft API is released under the MIT license.