├── README.md
├── THEMES.md
├── images
├── add2slack.png
├── bluebar.png
├── bluebar.svg
├── db-config1.png
├── db-config2.png
├── definecmd.png
├── draganddrop.png
├── fetch.png
├── gaugechart.png
├── guide.png
├── springbar.png
├── springbox.svg
└── svglink.png
├── themes
└── example-style.css
└── trainers
├── example-multiple.yaml
└── example.yaml
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Overview: Chatlytics Data Visualization For Slack
4 | Chatlytics is a data query and visualization platform. Part of the platform is a bot called "Fetch". Think of Fetch not just as a chatbot, but as an analytics assistant too.
5 |
6 | Fetch has one key job to perform: help teams use their data to create beautiful visualizations without ever needing to leave Slack (or Hipchat). Fetch takes care of the query, visualization and reporting grunt work so your team can focus on more important things. Fetch packages everything in flexible and customizable PNG & interactive SVGs.
7 |
8 | - [Prerequisites](#prerequisites)
9 | - [How To Interact With Fetch, Your Analytics Bot](#how-to-interact-with-fetch-your-analytics-bot)
10 | - [Step 1: Add To Slack](#step-1-add-to-slack)
11 | - [Step 2: Setup Your Database connection](#step-2-setup-your-database-connection)
12 | - [Step 3: Ask Fetch To Run Queries For You](#step-3-ask-fetch-to-run-queries-for-you)
13 | - [Teaching Fetch Custom Commands](#teaching-fetch-custom-commands)
14 | - [Step 1: Defining Custom Commands Via YAML File](#step-1-defining-custom-commands-via-yaml-file)
15 | - [Step 2: Train Fetch To Understand Your Command](#step-2-train-fetch-to-understand-your-command)
16 | - [Drag-and-Drop](#drag-and-drop)
17 | - [Attachments](#attachments)
18 | - [Remote Import from URL](#remote-import-from-url)
19 | - [Step 3: Tell Fetch To Run Your New Commands](#step-3-tell-fetch-to-run-your-new-commands)
20 | - [Creating Your Own Themes](#themes)
21 | - [Notes](#notes)
22 | - [MySQL](#mysql)
23 | - [Issues](#issues)
24 | - [Contributing](#contributing)
25 |
26 | ## Prerequisites
27 | You will need:
28 |
29 | * Database connection parameters. Currently only `PostgreSQL`, `MySQL`, `Amazon Redshift`, `Amazon Aurora (Postgres/MYSQL)` and `AmazON RDS (Postgres/MYSQL)` are supported)
30 | * Slack account for the bot to use. If you do not have one you need to get yourself a Slack account. Go to the Slack website: https://slack.com/
31 |
32 |
33 |
34 | ## How To Interact With Fetch, Your Analytics Bot
35 |
36 | ### Step 1: Add To Slack
37 |
38 | The first step required to set the bot up involves clicking the "Add to Slack" button at [https://www.chatlytics.co](https://www.chatlytics.co).
39 |
40 | 
41 |
42 | Chatlytics is only available for use with Slack at the moment. Other chat clients (Hipchat, Facebook, Skype, etc.) will be added soon!
43 |
44 | ### Step 2: Setup Your Database Connection
45 | You'll want to start by setting up your database connection. Run the command `!dbconfig` and follow the prompts to get started.
46 |
47 |
48 |
49 | In addition to your database type, Fetch will need your host address (which can be an IP address or domain), your username & password, port and database name. After you provide this info, you'll be able to review the configuration and start giving Fetch commands!
50 |
51 |
52 |
53 |
54 |
55 | ### Step 3: Ask Fetch To Run Queries For You
56 |
57 | Once you have connected Chatlytics to your database, you can interact with Fetch by sending commands to the linked Slack account.
58 |
59 | You'll find a guide to these commands at [https://www.chatlytics.co/guide.html](https://www.chatlytics.co/guide.html). Just select a command in the dropdown to see what Fetch will do with it and get additional tips.
60 |
61 | 
62 |
63 | Fetch has a built-in set of commands it understands. To see a list of available commands Fetch can recognize, type `!help`.
64 |
65 | The following is a list of available predefined commands:
66 | * `!list_tables`: Returns a list of all tables in the database.
67 | * `!table_count `: Returns the number of rows in the table.
68 | * Example: `!table_count MyTable`
69 | * `!count_compare Puppy Activities last Week0044881212161620202424282832323636SundayMondayTuesdayWednesdayThursdayFridaySaturday749.5824175824399.708502024Sunday10127.054945055382.704453441Monday9204.527472527388.372469636Tuesday7282.0399.708502024Wednesday8359.472527473394.04048583Thursday6436.945054945405.376518219Friday5514.417582418411.044534413Saturday649.5824175824326.024291498Sunday10127.054945055269.344129555Monday9204.527472527286.348178138Tuesday7282.0320.356275304Wednesday3359.472527473331.692307692Thursday1436.945054945365.700404858Friday3514.417582418365.700404858Saturday349.5824175824275.012145749Sunday3127.054945055195.659919028Monday5204.527472527206.995951417Tuesday3282.0263.67611336Wednesday9359.472527473263.67611336Thursday13436.945054945286.348178138Friday11514.417582418286.348178138Saturday549.5824175824229.668016194Sunday2127.054945055167.319838057Monday3204.527472527161.651821862Tuesday2282.0235.336032389Wednesday5359.472527473184.32388664Thursday7436.945054945172.987854251Friday10514.417582418167.319838057Saturday149.5824175824195.659919028Sunday3127.054945055138.979757085Monday5204.527472527116.307692308Tuesday16282.0133.311740891Wednesday13359.47252747382.2995951417Thursday3436.945054945116.307692308Friday7514.41758241870.963562753SaturdayPuppy Activities last WeekDayActivityPlayed fetchTook a napWent for a walkDid tricksChased cats
--------------------------------------------------------------------------------
/images/db-config1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openbridge/chatlytics/ffeba906d9e43d5ca4ca980bd6ca7d9437bd37b5/images/db-config1.png
--------------------------------------------------------------------------------
/images/db-config2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openbridge/chatlytics/ffeba906d9e43d5ca4ca980bd6ca7d9437bd37b5/images/db-config2.png
--------------------------------------------------------------------------------
/images/definecmd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openbridge/chatlytics/ffeba906d9e43d5ca4ca980bd6ca7d9437bd37b5/images/definecmd.png
--------------------------------------------------------------------------------
/images/draganddrop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openbridge/chatlytics/ffeba906d9e43d5ca4ca980bd6ca7d9437bd37b5/images/draganddrop.png
--------------------------------------------------------------------------------
/images/fetch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openbridge/chatlytics/ffeba906d9e43d5ca4ca980bd6ca7d9437bd37b5/images/fetch.png
--------------------------------------------------------------------------------
/images/gaugechart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openbridge/chatlytics/ffeba906d9e43d5ca4ca980bd6ca7d9437bd37b5/images/gaugechart.png
--------------------------------------------------------------------------------
/images/guide.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openbridge/chatlytics/ffeba906d9e43d5ca4ca980bd6ca7d9437bd37b5/images/guide.png
--------------------------------------------------------------------------------
/images/springbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openbridge/chatlytics/ffeba906d9e43d5ca4ca980bd6ca7d9437bd37b5/images/springbar.png
--------------------------------------------------------------------------------
/images/springbox.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/images/svglink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openbridge/chatlytics/ffeba906d9e43d5ca4ca980bd6ca7d9437bd37b5/images/svglink.png
--------------------------------------------------------------------------------
/themes/example-style.css:
--------------------------------------------------------------------------------
1 |
2 | .color-0 {
3 | stroke: #261e7f;
4 | fill: #261e7f;
5 | }
6 |
7 | .color-1 {
8 | stroke: #264aa5;
9 | fill: #264aa5;
10 | }
11 | .color-2 {
12 | stroke: #277ace;
13 | fill: #277ace;
14 | }
15 |
16 | .color-3 {
17 | stroke: #2bb3e5;
18 | fill: #2bb3e5;
19 | }
20 | .color-4 {
21 | stroke: #37d5fc;
22 | fill: #37d5fc;
23 | }
24 |
25 | @font-face {
26 | font-family: 'Open Sans';
27 | font-weight: 300;
28 | font-style: normal;
29 | src: url('/fonts/Open-Sans-300/Open-Sans-300.eot');
30 | src: url('/fonts/Open-Sans-300/Open-Sans-300.eot?#iefix') format('embedded-opentype'),
31 | local('Open Sans Light'),
32 | local('Open-Sans-300'),
33 | url('/fonts/Open-Sans-300/Open-Sans-300.woff2') format('woff2'),
34 | url('/fonts/Open-Sans-300/Open-Sans-300.woff') format('woff'),
35 | url('/fonts/Open-Sans-300/Open-Sans-300.ttf') format('truetype'),
36 | url('/fonts/Open-Sans-300/Open-Sans-300.svg#OpenSans') format('svg');
37 | }
38 |
39 | @font-face {
40 | font-family: 'Open Sans';
41 | font-weight: 400;
42 | font-style: normal;
43 | src: url('/fonts/Open-Sans-regular/Open-Sans-regular.eot');
44 | src: url('/fonts/Open-Sans-regular/Open-Sans-regular.eot?#iefix') format('embedded-opentype'),
45 | local('Open Sans'),
46 | local('Open-Sans-regular'),
47 | url('/fonts/Open-Sans-regular/Open-Sans-regular.woff2') format('woff2'),
48 | url('/fonts/Open-Sans-regular/Open-Sans-regular.woff') format('woff'),
49 | url('/fonts/Open-Sans-regular/Open-Sans-regular.ttf') format('truetype'),
50 | url('/fonts/Open-Sans-regular/Open-Sans-regular.svg#OpenSans') format('svg');
51 | }
52 |
53 | @font-face {
54 | font-family: 'Open Sans';
55 | font-weight: 600;
56 | font-style: normal;
57 | src: url('/fonts/Open-Sans-600/Open-Sans-600.eot');
58 | src: url('/fonts/Open-Sans-600/Open-Sans-600.eot?#iefix') format('embedded-opentype'),
59 | local('Open Sans Semibold'),
60 | local('Open-Sans-600'),
61 | url('/fonts/Open-Sans-600/Open-Sans-600.woff2') format('woff2'),
62 | url('/fonts/Open-Sans-600/Open-Sans-600.woff') format('woff'),
63 | url('/fonts/Open-Sans-600/Open-Sans-600.ttf') format('truetype'),
64 | url('/fonts/Open-Sans-600/Open-Sans-600.svg#OpenSans') format('svg');
65 | }
66 |
67 | @font-face {
68 | font-family: 'Open Sans';
69 | font-weight: 700;
70 | font-style: normal;
71 | src: url('/fonts/Open-Sans-700/Open-Sans-700.eot');
72 | src: url('/fonts/Open-Sans-700/Open-Sans-700.eot?#iefix') format('embedded-opentype'),
73 | local('Open Sans Bold'),
74 | local('Open-Sans-700'),
75 | url('/fonts/Open-Sans-700/Open-Sans-700.woff2') format('woff2'),
76 | url('/fonts/Open-Sans-700/Open-Sans-700.woff') format('woff'),
77 | url('/fonts/Open-Sans-700/Open-Sans-700.ttf') format('truetype'),
78 | url('/fonts/Open-Sans-700/Open-Sans-700.svg#OpenSans') format('svg');
79 | }
80 |
81 | .xy-graph .dot {
82 | stroke-width:6px;
83 | }
84 |
85 | text {
86 | font-family: 'Open Sans', Helvetica, Arial, sans-serif !important;
87 | font-size: 12px;
88 | }
89 |
90 | .legends .legend text {
91 | font-family: 'Open Sans', Helvetica, Arial, sans-serif !important;
92 | font-size: 9px !important;
93 | font-weight: 700 !important;
94 | text-transform: uppercase !important;
95 | cursor:pointer;
96 | fill: #4d5254;
97 | }
98 |
99 | .tooltip {
100 | font-size:10px !important;
101 | font-weight: 600 !important;
102 | }
103 |
104 | .axis text {
105 | fill: #4d5254 !important;
106 | cursor: default;
107 | }
108 |
109 | .axis text.major {
110 | font-weight: 700 !important;
111 | }
112 |
113 |
114 | /* under is direct from pygal styles */
115 | .graph > .background {
116 | fill: transparent;
117 | }
118 |
119 | .plot > .background {
120 | fill: transparent;
121 | }
122 |
123 | text.no_data {
124 | text-anchor: middle;
125 | }
126 |
127 | .centered {
128 | text-anchor: middle;
129 | }
130 |
131 | .title {
132 | text-anchor: middle !important;
133 | font-size: 11px !important;
134 | font-weight: 700 !important;
135 | fill: #656c6f;
136 | text-transform: uppercase !important;
137 | }
138 |
139 | .plot_title {
140 | text-transform: none !important;
141 | letter-spacing: none !important;
142 | text-anchor: start;
143 | font-weight: 300 !important;
144 | fill: #4d5254 !important;
145 | baseline-shift: sub;
146 | font-size: 20px !important;
147 | }
148 |
149 | .legends .legend text {
150 | fill-opacity: .9 !important;
151 | }
152 |
153 | .axis.x text {
154 | text-anchor: middle;
155 | }
156 |
157 | .axis.x:not(.web) text[transform] {
158 | text-anchor: start;
159 | }
160 |
161 | .axis.x:not(.web) text[transform].backwards {
162 | text-anchor: end;
163 | }
164 |
165 | .axis.y text {
166 | text-anchor: end;
167 | }
168 | .axis.y text[transform].backwards {
169 | text-anchor: start;
170 | }
171 |
172 | .axis.y2 text {
173 | text-anchor: start;
174 | }
175 |
176 | .axis.y2 text[transform].backwards {
177 | text-anchor: end;
178 | }
179 |
180 | .axis .line,
181 | .axis .major.line {
182 | stroke: #bbb;
183 | }
184 |
185 | .axis .guide.line {
186 | stroke-dasharray: 5px;
187 | stroke-linecap: round;
188 | stroke: transparent;
189 | }
190 |
191 | .axis .major.guide.line {
192 | stroke-linecap: round;
193 | stroke: transparent;
194 | stroke-dasharray: none;
195 | }
196 |
197 | .horizontal .axis.y .guide.line,
198 | .horizontal .axis.y2 .guide.line,
199 | .vertical .axis.x .guide.line {
200 | opacity: 0;
201 | }
202 |
203 | .horizontal .axis.always_show .guide.line,
204 | .vertical .axis.always_show .guide.line {
205 | opacity: 1 !important;
206 | }
207 |
208 | .axis.y .guides:hover .guide.line,
209 | .axis.y2 .guides:hover .guide.line,
210 | .axis.x .guides:hover .guide.line {
211 | opacity: 1;
212 | stroke: #727272 !important;
213 | stroke-width:1;
214 | }
215 |
216 | .axis .guides:hover text {
217 | opacity: 1;
218 | }
219 |
220 | /* normal state */
221 | .reactive {
222 | fill-opacity: .85;
223 | stroke-opacity: .9;
224 | }
225 |
226 |
227 | .reactive.active,
228 | .active .reactive {
229 | fill-opacity: .9;
230 | stroke-opacity: .95;
231 | stroke-width: 1.5;
232 | }
233 |
234 | .dot {
235 | stroke-width: 1px;
236 | fill-opacity: 1;
237 | }
238 |
239 | .dot.active {
240 | stroke-width: 5px;
241 | }
242 |
243 | .x_label {
244 | font-size:9px !important;
245 | }
246 |
247 | .dot.negative {
248 | fill: transparent;
249 | }
250 |
251 | text, tspan {
252 | stroke: none !important;
253 | }
254 | .series text.active {
255 | opacity: 1;
256 | }
257 |
258 | .tooltip rect {
259 | fill-opacity: .85;
260 | stroke-width: .5;
261 | stroke: #ccc;
262 | rx: 2;
263 | ry: 2;
264 | border-radius: 4px !important;
265 | }
266 |
267 | .tooltip text {
268 | fill-opacity: 1;
269 | fill: #4d5254 !important ;
270 | }
271 |
272 | .gauge-background {
273 | fill: {{ style.value_background }};
274 | stroke: none;
275 | }
276 |
--------------------------------------------------------------------------------
/trainers/example-multiple.yaml:
--------------------------------------------------------------------------------
1 | queries:
2 | - name: ga_unique_visits
3 | query: select date, count(distinct fullvisitorid || visitid) from ga_test_04 group by date
4 | chart_type: bar_chart
5 | chart_description: Unique visits by day for table ga_test_04
6 | chart_style: blue
7 |
8 | - name: ga360_unique_visits
9 | query: select date, count(distinct full_visitor_id || visit_id) from ga360_master group by date
10 | chart_type: line_chart
11 | chart_description: Unique visits by day for table ga360_master
12 | chart_style: sunset
13 |
--------------------------------------------------------------------------------
/trainers/example.yaml:
--------------------------------------------------------------------------------
1 | queries:
2 | - name: test_query
3 | query: select testColumn, count(*) from testTable group by testColumn
4 | chart_type: bar_chart
5 | chart_description: test
6 | style: blue
7 |
--------------------------------------------------------------------------------