Asana integration with Slack - api

I am looking to implement a solution where when I create a project in Asana it will create a room in Slack with all the same members.I was planning on writing a script to run every couple of minutes to look for either new projects or changes in membership of current projects and then call out to slack to make the changes. This, however, would be a lot of chatter so I was hoping someone might know of and be able to recommend another way that will make these changes on an as needed basis.

It sounds like you have the best solution outlined for this use case.
In order to get a list of new projects in a workspaces you should query the projects endpoint and check for newly created projects based on the created_at field, using opt_fields field selector to have that returned in your query. I strongly suggest that you scope this query to a single workspace and use pagination.
GET 'https://api.asana.com/api/1.0/workspaces/5233820891524/projects?opt_fields=name,created_at&limit=2' | j
{
"data": [
{
"id": 23154287843671,
"created_at": "2014-12-31T18:35:49.695Z",
"name": "Ninja Things"
},
{
"id": 23154287843675,
"created_at": "2014-12-31T18:35:59.174Z",
"name": "Unicorns"
}
],
"next_page": {
"offset": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJib3JkZXJfcmFuayI6ImRTbm5ZaGNOOWFFIiwiaWF0IjoxNDM4ODE0MzY0LCJleHAiOjE0Mzg4MTUyNjR9.82zecHAT51-GSrL6FdcrRdMs45U7PZ3g-d4Zuo_B8UA",
"uri": "https://api.asana.com/api/1.0/workspaces/5233820891524/projects?limit=2&opt_output=json&opt_fields=name%2Ccreated_at&offset=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJib3JkZXJfcmFuayI6ImRTbm5ZaGNOOWFFIiwiaWF0IjoxNDM4ODE0MzY0LCJleHAiOjE0Mzg4MTUyNjR9.82zecHAT51-GSrL6FdcrRdMs45U7PZ3g-d4Zuo_B8UA",
"path": "/workspaces/5233820891524/projects?limit=2&opt_output=json&opt_fields=name%2Ccreated_at&offset=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJib3JkZXJfcmFuayI6ImRTbm5ZaGNOOWFFIiwiaWF0IjoxNDM4ODE0MzY0LCJleHAiOjE0Mzg4MTUyNjR9.82zecHAT51-GSrL6FdcrRdMs45U7PZ3g-d4Zuo_B8UA"
}
}
For new members of current projects you would need to query individual projects and check the memberships property.
I would have suggested using the Events api to check for new members but tested and determined that new members are not considered an event on the project, something that we will consider changing.

Related

How to specify 'includes' for nested properties in a document in RavenDB

I am trying to use RavenDB's REST API to make some calls to my database and I'm wondering if there's a way to use the 'includes' feature to return documents that are nested in a document.
For example, I have an object, Order, that looks similar to this:
"Order": {
"Lines": [
{
"Product": "products/11-A"
},
{
"Product": "products/42-A"
},
{
"Product": "products/72-A"
}
],
"OrderedAt": "1996-07-04T00:00:00.0000000",
"Company": "companies/85-A"
}
Company maps to another document and is simple enough to include in the query.
{ "Query": "from Orders include Company" }
My problem is Product that is nested in Lines, which is an array of order lines. Since I didn't find anything in the documentation about it I tried things like include Product or include Lines.Product, but those didn't work.
Is this kind of thing possible with the REST API? If so, how would I go about doing it?
The syntax to Query for Related Documents from the client can be found in this demo:
https://demo.ravendb.net/demos/csharp/related-documents/query-related-documents
The matching RQL to be used in the Query when using REST API is:
from 'Orders' include 'Lines[].Product'

Without JOINs, what is the right way to handle data in document databases?

I understand that JOINs are either not possible or frowned upon in document databases. I'm coming from a relational database background and trying to understand how to handle such scenarios.
Let's say I have an Employees collection where I store all employee related information. The following is a typical employee document:
{
"id": 1234,
"firstName": "John",
"lastName": "Smith",
"gender": "Male",
"dateOfBirth": "3/21/1967",
"emailAddresses":[
{ "email": "johnsmith#mydomain.com", "isPrimary": "true" },
{ "email": "jsmith#someotherdomain.com", "isPrimary": "false" }
]
}
Let's also say, I have a separate Projects collection where I store project data that looks something like that:
{
"id": 444,
"projectName": "My Construction Project",
"projectType": "Construction",
"projectTeam":[
{ "_id": 2345, "position": "Engineer" },
{ "_id": 1234, "position": "Project Manager" }
]
}
If I want to return a list of all my projects along with project teams, how do I handle making sure that I return all the pertinent information about individuals in the team i.e. full names, email addresses, etc?
Is it two separate queries? One for projects and the other for people whose ID's appear in the projects collection?
If so, how do I then insert the data about people i.e. full names, email addresses? Do I then do a foreach loop in my app to update the data?
If I'm relying on my application to handle populating all the pertinent data, is this not a performance hit that would offset the performance benefits of document databases such as MongoDB?
Thanks for your help.
"...how do I handle making sure that I return all the pertinent information about individuals in the team i.e. full names, email addresses, etc? Is it two separate queries?"
It is either 2 separate queries OR you denormalize into the Project document. In our applications we do the 2nd query and keep the data as normalized as possible in the documents.
It is actually NOT common to see the "_id" key anywhere but on the top-level document. Further, for collections that you are going to have millions of documents in, you save storage by keeping the keys "terse". Consider "name" rather than "projectName", "type" rather than "projectType", "pos" rather than "position". It seems trivial but it adds up. You'll also want to put an index on "team.empId" so the query "how many projects has Joe Average worked on" runs well.
{
"_id": 444,
"name": "My Construction Project",
"type": "Construction",
"team":[
{ "empId": 2345, "pos": "Engineer" },
{ "empId": 1234, "pos": "Project Manager" }
]
}
Another thing to get used to is that you don't have to write the whole document every time you want to update an individual field or, say, add a new member to the team. You can do targeted updates that uniquely identify the document but only update an individual field or array element.
db.projects.update(
{ _id : 444 },
{ $addToSet : "team" : { "empId": 666, "position": "Minion" } }
);
The 2 queries to get one thing done hurts at first, but you'll get past it.
Mongo DB is a document storage database.
It supports High Availability, and Scalability.
For returning a list of all your projects along with project team(details),
according to my understanding, you will have to run 2 queries.
Since mongoDb do not have FK constraints, we need to maintain it at the program level.
Instead of FK constraints,
1) if the data is less, then we can embed the data as a sub document.
2) rather than normalized way of designing the db, in MongoDb we need to design according to the access pattern. i.e. the way we need to query the data more likely. (However time for update is more(slow), but at the user end the performance mainly depends on read activity, which will be better than RDBMS)
The following link provides a certificate course on mongo Db, free of cost.
Mongo DB University
They also have a forum, which is pretty good.

How to add content and moreDetailsUrl for Google Search suggest?

I'm using GSA (version 6.14) and we would like to get an auto suggest function on our website. Works fine for basic requests, but it seems the GSA offers more functionality when you would be using user-added results. However, I can find nowhere a reference on how to add user-added results.
This is what the information tells me today :
/suggest?q=<query>&max=<num>&site=<collection>&client=<frontend>&access=p&format=rich
should return a response as below :
{
"query": "<query>",
"results": [
{ "name": "<term 1>", "type": "suggest"},
{ "name": "<term 2>", "type": "suggest"},
{ "name": "<term 3>", "type": "uar", "content": "Title of UAR",
"moreDetailsUrl": "URL of UAR"}
]
}
I am able to get results as the first 2 lines, but would like to get results as the last line also, so with content and a moreDetailsUrl. So maybe a very stupid question but I am not able to find the answer anywhere : How and where do I add this UAR ?
I actually want to understand if it's feasible to get metadata into the content part of the JSON, so if for instance an icon meta is available I'd like to have it included in the JSON so I can enrich my search results.
User Added Results are a OneBox that can be added to multiple frontends. See this: https://developers.google.com/search-appliance/documentation/614/admin_searchexp/ce_improving_search#uar
When done with Suggest, the data is fed from user entering 'keymatches' directly. What's different about them is that they are a direct link versus a suggested query. If you use the out of the box experience, you'll click a link to the url instead of running another query.

[Freebase]: Finding relationship between nodes

I am new to Freebase and I have been trying to find relationships between 2 nodes without success.
For example, I want to find if there is link between Lewis Hamilton(/en/lewis_hamilton) and Formula One(/en/formula_one), which there is in real life, but I can't seem to find it.
I have tried the following MQL codes, alternating IDs as well :
1)
[{
"type" : "/type/link",
"source" : { "id" : "/en/lewis_hamilton" },
"master_property" : null,
"target" : { "id" : "/en/formula_one" },
"target_value" : null
}]
2)
{
"id":"/en/lewis_hamilton",
"/type/reflect/any_master":[{
"link":null,
"name":null
}],
"/type/reflect/any_reverse":[{
"link":null,
"name":null
}],
"/type/reflect/any_value":[{
"link":null,
"value":null
}]
}
I'm also not able to use a couple of their apps that could do this because it returns "user rate limit exceeded" every time. Apps are:
http://between.freebaseapps.com
http://shortestpath.freebaseapps.com
Do you guys have any suggestions?
The queries that you gave are correct except that they only look at relationships that are one link apart. Surprisingly there isn't a path from Lewis Hamilton to Formula One in Freebase right now. If there was it might look something like this:
/en/lewis_hamilton → /type/object/type → /base/formula1/formula_1_driver
/base/formula1/formula_1_driver → /type/type/domain → /base/formula1
/base/formula1 → /freebase/domain_profile/equivalent_topic → /en/formula_one
Freebase doesn't support recursive queries so there's no good way to find these multi-link paths between topics. The apps that you tried simulate recursion by generating queries with increasingly nested subqueries. Unfortunately they are out of date and missing the proper API keys to run properly right now. Here's what those nested queries look like:
{
"id": "/en/lewis_hamilton",
"name": null,
"/type/reflect/any_master": [{
"link": {
"master_property": null,
"target": {
"id": null,
"name": null,
"/type/reflect/any_master": [{
"link": {
"master_property": null,
"target": {
"id": "//base/formula1",
"name": null
}
},
"name": null
}]
}
},
"name": null
}]
}
These sorts of queries can take a long time to run and are probably better if run locally over the Freebase data dumps.
Freebase is returning nothing but 503s right now, so it's a little difficult to experiment, but
All apps on Freebaseapps are open source, so looking at the sources for the apps you found should give you some good hints. The app directory is at https://www.freebase.com/apps (but isn't rendering right now)
All apps on Freebaseapps can be cloned with a single click. Pretty much every app written on that infrastructure stopped working when Google switched to the new API and the developers are unlikely to fix them if they haven't been looked at in years, but you can probably get the ones of interest working by a) cloning them, b) registering for an API key and c) adding that API key to cloned app.

Asana: Adding a task to a project when you create it

I am trying to use the Asana API to create a task that is assigned to me and added to an existing project.
I have tried by not specifying the workspace as suggested by someone else but the task creation still fails.
The jSon I am using is the following;
{ "data":
{
"name":"Testing Project",
"followers":[10112, 141516],
"workspace":6789,
"assignee":12345,
"project": 1234
}
}
If I create the task and then send another call to the API with the following jSon it works, but this means I need to make 2 API calls every time I create a task.
{
"project": 1234
}
Rather old question but it might help someone. Yes, you can attach a task to a project during creation using the 'projects' (not 'project' as stated above) param, passing its id.
You can also attach the task to many projects stating an array at 'projects' => {22, 33, 44}.
It's all here at https://asana.com/developers/api-reference/tasks
(I work for Asana)
The specification for Tasks can be found here: https://asana.com/developers/api-reference/tasks
Notably, you cannot specify a project during creation - you must go through the addProject call for each project you wish to add.
If there is contradictory information on another SO question, I apologize as that may have been written without first double-checking the implementation.
The actual problem is that you are passing an int instead of an string for "projects". Some attributes work well as string or int (e.g. "assignee" or "workspace") but not "projects".
..so correct your json to the following:
{
"data":
{
"name":"Testing Project",
"followers":[10112, 141516],
"workspace":6789,
"assignee":12345,
"project": "1234"
}
}
I wasted half a day -.-'