Mailchimp API v2.0 filter campaigns by list id doesn't filter if there is no match - api

http://apidocs.mailchimp.com/api/2.0/campaigns/list.php
I would expect that something like
{
"apikey": "12345",
"filters": {
"list_id": "abcde",
"exact": true
}
}
to return a list of total=1 if there is one campaign with list_id = "abcde", or total=0 if there isn't (using exact=true). However, instead I get the full list. Is this by design? Am I missing some other setting to filter out all mismatches? Is there a way to deal with this?

OK, so this is what I have come up with, barring some other resolution:
When the result set is returned, do a sanity check on the first result (data.data[0]).
If there is a true match, then data.data[0].list_id = list_id
If there was no match, and the full set has come back, then data.data[0].list_id cannot = list_id
This extra step is not ideal, imo, but it does do the trick.
if data.data[0].list_id === list_id
// the list is a match, return the results
else
// the list is not a match, do something else

Here's another solution:
The full-response will provide an error object if no match
"errors": [{
"filter": "list_id",
"value": "abcde",
"code": 200,
"error": "Invalid MailChimp List ID: abcde"
}]
and an empty object for a set of matches
"errors": []
So you can first process your result by looking for this error object and making the appropriate decision.
I received some clarification from MailChimp (and post it here with permission) that this is as-intended:
To provide some more information, the behavior with the campaigns/list call completing, even with an invalid filter, is expected behavior. As you mention, an error array is included in the return, and it would be possible to check that array for any errors received to determine whether or not the call completed as expected.
I can certainly see how that may be unexpected, to receive the full list of campaigns when attempting to filter. If you'd prefer that an error would be returned, without the campaign data returned, we'd recommend adding that suggestion to our feedback form here: http://mailchimp.com/contact/feedback/ That's certainly something our developers could consider for future versions of the API.
I'm still not sure why they do it this way, but I've added feedback suggesting that they return an empty result (so as not to bulk up the response with irrelevant data), or to improve the documentation.

Related

Faunadb gives error on Paginate Error like "Ref or set expected, string provided"

I am learning about FaunaDB and on running the following script in Fauna Shell I get the error:
Error: [
{
"position": [
"map",
"expr",
"get"
],
"code": "invalid argument",
"description": "Ref or Set expected, String provided."
}
]
Query I am trying to run:
Map(Paginate(Match(Index("todo_tasks"))), Lambda(x => Get(x)))
Thanks all. I've figured it out. The problem was that the index I created was not returning the refs which is required by Get. Therefore, I created a new Index which returned the refs and used it instead and it worked. Thanks again.
Match is supposed to have two arguments. I think what's happening is that it is defaulting to matching against an empty string. You have to tell Fauna what you're Matching your index with. Have you tested your index? You can go to the fauna client and click on indexes. You should be able to select "string", "number" or "FQL" and enter a value that would return the document you're searching for.
But in order to properly determine what the second argument should be, you need to provide more information as to how your index is constructed for your todos. If the index is on a data type Todo, you need to provide a Ref to that Todo as your second argument in Match.

Connectwise API missing property value gives no response

This question may very well be a general API question, but the API I am using is the Connectwise Tickets API.
I'm writing in VB and I'm getting my list of tickets(i) then I'm setting the following variable:
currentTicket = tickets(i)
So that I can reference value like currentTicket.Source.Name and save the info to a DB.
As long as the Connectwise user put something into the "Source" field, everything works fine. I can reference that property and log it to the database or whatever else I want to do. If they left it blank though, even trying to look at currentTicket.Source.Name stops my program in it's tracks. It doesn't crash or error out, it just doesn't go past the line of code referencing the empty field.
Since it won't even let me reference currentTicket.Source.Name for example, I am unable to check to see if currentTicket.Source.Name = "" or Is Nothing.
What am I missing? Is there a way to check and see if the property even exists for a given API response?
Any help would be appreciated.
EDIT:
OK so I decided to take the Ticket object and grab the raw json and send it to the command line output.
When a ticket has the source field filled in, this is what that section of the JSON looks like:
...
},
"servicelocation": {
"id":4,
"name":"remote",
"_info":{
"location_href":"https://API_url"
}
},
"source":{
"id":4,
"name":"Email Connector",
"_info": {
"source_href":"https://API_url"
}
},
"severity": "Medium",
"impact":"Medium",
...
When the source field in the application has been left blank, the JSON looks like this instead:
...
},
"servicelocation": {
"id":4,
"name":"remote",
"_info":{
"location_href":"https://API_url"
}
},
"severity": "Medium",
"impact":"Medium",
...
That behavior is probably normal, I'm obviously just missing the knowledge of how to deal with it. I feel like I should be able to test if the property of the object is non-existent the same way I test if it's null or "", using Tickets(i).Source.Name, but I get no exceptions, no errors, no crashes, the program just sits their waiting for a response to "What's Source Name's value?"
I mean I suppose I could parse out the entire JSON response, create my own private object, assign values as they exist and then set my own property values so I could then set mySourceName = "" When it doesn't exist in the JSON response, but that seems like a lot of work when I only care about like 10 fields and it's a pretty large json response.
Is that the normal way of doing things with APIs?

Zapier lazy load input fields choices

I'm building a Zapier app for a platform that have dynamic fields. I have an API that returns the list of fields for one of my resource (for example) :
[
{ name: "First Name", key: "first_name", type: "String" },
{ name: "Civility", key: "civility", type: "Multiple" }
]
I build my action's inputFields based on this API :
create: {
[...],
operation: {
inputFields: [
fetchFields()
],
[...]
},
}
The API returns type that are list of values (i.e : Civility), but to get these values I have to make another API call.
For now, what I have done is in my fetchFields function, each time I encounter a type: "Multiple", I do another API call to get the possible values and set it as choices in my input field. However this is expensive and the page on Zapier takes too much time to display the fields.
I tried to use the z.dehydrate feature provided by Zapier but it doesn't work for input choices.
I can't use a dynamic dropdown here as I can't pass the key of the field possible value I'm looking for. For example, to get back the possible values for Civility, I'll need to pass the civility key to my API.
What are the options in this case?
David here, from the Zapier Platform team.
Thanks for writing in! I think what you're doing is possible, but I'm also not 100% that I understand what you're asking.
You can have multiple API calls in the function (which it sounds like you are). In the end, the function should return an array of Field objects (as descried here).
The key thing you might not be aware of is that subsequent steps have access to a partially-filled bundle.inputData, so you can have a first function that gets field options and allows a user to select something, then a second function that runs and pulls in fields based on that choice.
Otherwise, I think a function that does 2 api calls (one to fetch the field types and one to turn them into Zapier field objects) is the best bet.
If this didn't answer your question, feel free to email partners#zapier.com or join the slack org (linked at the bottom of the readme) and we'll try to solve it there.

INVALID_ARGUMENT exception when requesting Google's knowledge graph API

I've read the documentation on Google's knowledge graph and from what I understand we can search for results both based on a query and based on IDs. For getting results by a query, no problem whatsoever, but when I try to retrieve them by IDs, it fails. Setting aside what query I used myself, this is the request URL I got from Google's API Explorer:
https://kgsearch.googleapis.com/v1/entities:search?ids=kg%3A%2Fm%2F01nrz4&key={YOUR_API_KEY}
and the result is:
{
"error": {
"code": 400,
"message": "Request contains an invalid argument.",
"status": "INVALID_ARGUMENT"
}
}
And I'm pretty sure that the problem is with the ids parameter. Am I missing something?
Thanks
OK, so here's the thing. Each found instance has an attribute like this: "#id": "kg:/m/0gkg6" . So in this instance the id is kg:/m/0gkg6, but when we want to run a query based on ID, we should omit the kg: part.

Instagram API error

I using Instagram API to get user info
api = InstagramAPI(access_token=access_token)
profile = api.user(user_id="kallaucyahoocojp") # I try to put output data to profile variable here
And I get the below error:
DownloadError: Unable to fetch URL: https://api.instagram.com/v1/users/kallaucyahoocojp.json?access_token=(u'1191812153.f78cd79.d2d99595c79d4c23a7994d85ea0d412c', {u'username': u'kallaucyahoocojp', u'bio': u'\u30c4\u30a4\u30c3\u30bf\u30d5\u30a9\u30ed\u30ef\u30fc\u5897\u52a0\u30b5\u30fc\u30d3\u30b9', u'website': u'http://twitter\u30d5\u30a9\u30ed\u30ef\u30fc.jp', u'profile_picture': u'http://images.ak.instagram.com/profiles/anonymousUser.jpg', u'full_name': u'Kallauc', u'id': u'1191812153'})
Can anybody help me to fix it?
You need to pass the numeric-based user id, rather than the username. For example, instead of passing kallaucyahoocojp, you might pass 1234 if t
Here's how to get the ID if you don't have it:
Search for the instagram user id using this endpoint. In the python api:
api.user_search(q="kallaucyahoocojp", count=100)
Check the results for an exact string match on each user name while iterating through the results (calling .lower() to be sure to ignore potential case issues).
If you don't find the user in the first page of results, call to the next page using the max id returned.
Get the user id object from the returned from the matching users search result, then call your original function again with the numeric id.
A couple of very important notes:
Notice that I called the search function for users with a count of 100. You can pick any number, but contrary to other SO posts, the first user is not always the user you want in a search. The search can and will match partials, and not always according to an exact match first. How do I know? I have production instagram apps. I will qualify and say that usually the results are in the first 2-3 matches. Decide what is cheaper; repeated API calls that bring you closer to the limit, or 1 large bulk call where you are certain to get all the results.
The python Instagram API last I checked does a terrible job returning paging information. You actually get the paging URL which defeats the purpose of the python API itself to get additional pages. Your options are extract the next id parameter from the URL using urlparse or something similar, or fix the API to return the paging data as an object per the json (I've done both). What happens is the API itself is discarding part of the json and only giving you the URL which normally you don't want/need.
In your example, here's the search response:
{
"meta": {
"code": 200
},
"data": [
{
"username": "kallaucyahoocojp",
"bio": "ツイッタフォロワー増加サービス",
"website": "http://twitterフォロワー.jp",
"profile_picture": "http://images.ak.instagram.com/profiles/anonymousUser.jpg",
"full_name": "Kallauc",
"id": "1191812153"
}
]
}
Revising your call:
api = InstagramAPI(access_token=access_token)
profile = api.user(user_id="1191812153")
I should note that you may not need to call the user call if you did a search because you may simply have all the info you need. It will depend on what you are doing of course, so I am giving you the general method to use the rest of the user api.
For extracting profile info using Instagram API, userid is required.
The endpoint for extracting userID:
https://api.instagram.com/v1/users/search?q=[username]&access_token=[HERE]
The endpoint for extracting profile info:
https://api.instagram.com/v1/users/[userid]/?access_token=[HERE]
Note that before extracting information, check the login permissions for your access token.