├── .idea
├── .name
├── copyright
│ └── profiles_settings.xml
├── jsLibraryMappings.xml
├── modules.xml
├── asana-webhooks-manager.iml
├── libraries
│ └── asana_webhooks_manager_node_modules.xml
└── misc.xml
├── config
├── index.js
├── mongodb.js
└── asana.js
├── tests
├── mocks
│ ├── mongodb.js
│ ├── io.js
│ ├── Request.js
│ └── Response.js
├── helpers
│ ├── asana.test.js
│ ├── config.test.js
│ └── mongodb.test.js
├── controllers
│ ├── RootController.test.js
│ ├── OauthController.test.js
│ ├── AWMController.test.js
│ ├── EventsController.test.js
│ └── AsanaController.test.js
└── routes
│ ├── root.test.js
│ ├── events.test.js
│ ├── oauth.test.js
│ └── asana.test.js
├── public
├── client
│ ├── app.module.js
│ ├── models
│ │ ├── AWM.js
│ │ ├── AWMProject.js
│ │ ├── AWMPhoto.js
│ │ ├── AWMWorkspace.js
│ │ ├── AWMWebhook.js
│ │ ├── AWMEvent.js
│ │ └── AWMUser.js
│ ├── views
│ │ ├── main.html
│ │ ├── footer.html
│ │ ├── events.html
│ │ ├── header.html
│ │ ├── index.html
│ │ ├── manage.html
│ │ ├── body.html
│ │ └── docs.html
│ ├── directives
│ │ └── highlight.js
│ ├── controllers
│ │ ├── headerController.js
│ │ ├── mainController.js
│ │ ├── docsController.js
│ │ ├── eventsController.js
│ │ └── manageController.js
│ ├── app.config.js
│ ├── services
│ │ ├── userService.js
│ │ ├── navigationService.js
│ │ ├── resolveService.js
│ │ ├── eventsService.js
│ │ └── asanaService.js
│ └── app.routes.js
├── fonts
│ ├── FontAwesome.otf
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.ttf
│ ├── fontawesome-webfont.woff
│ └── fontawesome-webfont.woff2
├── img
│ └── documentation
│ │ ├── create_app
│ │ ├── step1.jpg
│ │ ├── step2.jpg
│ │ ├── step3.jpg
│ │ ├── step4.jpg
│ │ ├── step5.jpg
│ │ └── step6.jpg
│ │ ├── events
│ │ └── live_view.jpg
│ │ └── manage_webhooks
│ │ ├── manage_step1.jpg
│ │ ├── manage_step2.jpg
│ │ └── manage_step3.jpg
├── libs
│ ├── bootstrap
│ │ ├── fonts
│ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ └── glyphicons-halflings-regular.woff2
│ │ ├── js
│ │ │ └── npm.js
│ │ └── css
│ │ │ ├── bootstrap-theme.min.css
│ │ │ └── bootstrap-theme.min.css.map
│ ├── angular
│ │ └── angular-cookies.1.5.6.min.js
│ └── highlight
│ │ └── highlight.pack.js
└── css
│ ├── sticky-footer.css
│ ├── highlight.github.css
│ └── style.css
├── .travis.yml
├── helpers
├── response.js
├── asanaClient.js
├── configHelper.js
└── mongodbHelper.js
├── middlewares
└── restrictedAccess.js
├── models
├── webhook.js
└── event.js
├── .gitignore
├── controllers
├── RootController.js
├── OauthController.js
├── AWMController.js
├── EventsController.js
└── AsanaController.js
├── routes
├── index.js
├── events.js
├── root.js
├── oauth.js
└── asana.js
├── server.js
├── package.json
└── README.md
/.idea/.name:
--------------------------------------------------------------------------------
1 | asana-webhooks-manager
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | asana: require('./asana')
3 | };
4 |
--------------------------------------------------------------------------------
/tests/mocks/mongodb.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | getConnection : function(){}
3 | };
--------------------------------------------------------------------------------
/public/client/app.module.js:
--------------------------------------------------------------------------------
1 | var awmApp = angular.module('awmApp', ['ui.router','ngCookies']);
2 |
3 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "iojs"
4 | - "6"
5 | after_success: 'npm run coveralls'
--------------------------------------------------------------------------------
/public/client/models/AWM.js:
--------------------------------------------------------------------------------
1 | /**
2 | * AWM - A general mamespace for all models
3 | * */
4 | var AWM = AWM || {};
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
| # | 16 |Resource | 17 |User | 18 |Type | 19 |Action | 20 |Created at | 21 |Parent | 22 |
|---|---|---|---|---|---|---|
| {{$index+1}} | 27 |{{event.getResource()}} | 28 |{{event.getUser()}} | 29 |{{event.getType()}} | 30 |{{event.getAction()}} | 31 |{{event.getCreatedAt()}} | 32 |{{event.getParent()}} | 33 |
| # | 16 |Workspace | 17 |18 | |
|---|---|---|
| {{$index+1}} | 23 |{{workspace.getName()}} | 24 |25 | |
6 | Asana webhooks manager (AWM) is a free and open source management and event handling server, written in JavaScript for Asana's webhooks API.
7 | Use AWM to manage webhooks subscriptions and accept event payloads from Asana in real-time.
8 |
10 | Consider AWM as your starting point for writing your own application logic, on top of Asana's webhook notifications mechanism. 11 |
12 |13 | Quickly get started by watching a 5 minutes setup video or read the quick start guide 14 |
15 | 16 |17 | 18 | Watch video 19 | Login with Asana 20 | 21 |
22 |36 | Read the documentation to learn how you can modify and extend AWM functionality to better suit your needs. 37 |
38 |41 | Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, 42 | when an unknown printer took a galley of type and scrambled it to make a type 43 | specimen book. It has survived not only five centuries, 44 | but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in 45 |
46 |50 | Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, 51 | when an unknown printer took a galley of type and scrambled it to make a type 52 | specimen book. It has survived not only five centuries, 53 | but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in 54 |
55 |59 | Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, 60 | when an unknown printer took a galley of type and scrambled it to make a type 61 | specimen book. It has survived not only five centuries, 62 | but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in 63 |
64 |
52 | No one likes reading the docs :) so why not watch a quick-start video instead and get up and running in no-time!
53 | If you're interested in going beyond the basics, like extending AWM functionality read on.
54 |
65 | 1. Login into to your Asana account and Select My Profile Settings... for the top right user menu
66 |
67 |
69 | 2. Select the Apps tab from the top menu
70 |
71 |
73 | 3. Select Manage Developer Apps
74 |
75 |
77 | 4. Click on +Add New Application
78 |
79 |
81 | 5. Fill in all three fields, and mark the "agreement" checkbox then click Create
82 | The redirect url value must be your own server root address, appended with "/oauth/asana"
83 |
84 |
86 | 6. Congrats! you've just created an Asana Application. Before clicking Save, copy all values underlined below, You'll need to paste them into AWM Configuration File before you can start using AWM
87 |
88 |
89 |
94 | AWM uses Asana's OAuth flow to allow you to "Login with Asana".
95 | Using your text editor of choice, please update the configuration file located at <"your awm directory">/config/asana.js
96 | Following the values from screenshots above, your modified configuration file should look very similar to this:
97 |
98 | module.exports = {
99 | clientId: "304364573959829",
100 | clientSecret: "392ab438bf979973d0cc12a0ed6da8b0",
101 | redirectUri: "https://a2bd603f.ngrok.io/oauth/asana",
102 | };
103 |
104 |
105 |
106 |
107 |
109 | AWM uses MongoDB to stores webhooks information, to later use for validating incoming event payloads against their "webhook secret".
110 | In order for AWM to function correctly, you'll need to edit another configuration file located at <"your awm directory">/config/mongodb.js with your MongoDB information.
111 |
112 | module.exports = {
113 | username: null, //MongoDB user (optional)
114 | password: null, //MongoDB password (optional)
115 | host: "127.0.0.1", //Mongo hosts
116 | port: "27017", //Port
117 | database: "awm" //Database name
118 | };
119 |
120 |
121 |
122 |
124 | The following example uses ngrok.
125 | Download it here, then open up your terminal and run "ngrok http 3000".
126 | If you're terminal is showing something similar to what's below, it means things are working OK, and that whatever is running at localhost:3000 is now available both via http and https to the world.
127 | Before you try accessing yout https endpoint, please read one more step below to start your AWM server
128 |
129 | Tunnel Status online
130 | Version 2.0/2.0
131 | Web Interface http://127.0.0.1:4040
132 | Forwarding http://a2bd603f.ngrok.io -> localhost:3000
133 | Forwarding https://a2bd603f.ngrok.io -> localhost:3000
134 |
135 | Connnections ttl opn rt1 rt5 p50 p90
136 | 0 0 0.00 0.00 0.00 0.00
137 |
138 |
139 | 140 | More documentation is available on the ngork website: https://ngrok.com/docs 141 |
142 | 143 |146 | AWM requires NodeJS (v6.9 or higher) to run. You can download it from Node's official website 147 | Once you have node install, using another terminal session (to keep ngrok running) cd to your AWM folder and run "node server.js". You should see an "AWM Server started!" message: 148 |
149 | > node server.js
150 | AWM Server started!
151 |
152 |
153 | You should now be able to access the web interface for AWM, available at your https url as shown on screen in your terminal running the ngrok tunnel.
154 |
155 |
156 |
157 |
159 | Easily login with Asana by using a built-in url in AWM, Simply point your browser
162 | Please note you must have your configuration file updated with your app's details first. 163 |
164 | 165 | 166 |
168 | 1. AWM supports managing webhooks subscriptions for all projects, in all workspaces.
169 | Once logged in, use the Manage tab to view a list of all available workspaces:
170 |
171 |
174 | 2. Click View projects to list all available projects in a workspace
175 | then click Subscribe register a webhook for the selected project
176 |
177 |
180 | 3. Click Unsubscribe to remove an existing webhook subscription
181 |
182 |
186 | Once your subscriptions are in place, you can watch incoming event in real-time, under the Live view tab
187 | If you'd like to extend the current basic implementation, please see read below on extending AWM
188 |
189 |
194 | While AWM handles most common technicalities for working with Asana webhooks, it tries to be as slim as possible.
195 | Therefore, there are a few remaining security recommendations to consider when deploying to a live production server:
196 |
214 | AWM creates and expects to receive event notifications to "https://hostname/events/incoming/resourceId".
215 | For increased security, AWM will support modifying this url in the next version.
216 |