{"info":{"_postman_id":"cff94895-6b05-4736-862e-40f4d8fb0217","name":"Slack-Weekly-Pageview-Report","description":"<html><head></head><body><p><a href=\"https://i.imgur.com/kIVcm08.png\"><img src=\"https://i.imgur.com/kIVcm08.png\"></a></p>\n<p>This collection calls Google Analytics Reporting API v4 to query the report and post to Slack.</p>\n<h2 id=\"workflow\">Workflow:</h2>\n<p><a href=\"https://i.imgur.com/wOt1TKv.png\"><img src=\"https://i.imgur.com/wOt1TKv.png\"></a></p>\n<h2 id=\"how-to-setup-oauth-20-to-access-google-apis\"> How to setup OAuth 2.0 to Access Google APIs:</h2>\n<br>\n\n<p><strong>1.</strong> You need to set up a project with <a href=\"https://console.developers.google.com/apis/credentials\">Google APIs console</a>. And under <code>Credentials</code>, follow this workflow:</p>\n<blockquote>\n<p>click <code>Create credentials</code> → choose <code>OAuth client ID</code> → select <code>Web application</code> → fill <code>your name</code> → fill <code>your redirect url</code> with <code>https://www.getpostman.com/oauth2/callback</code> → click <code>Create</code>.</p>\n</blockquote>\n<ul>\n<li>save the <code>Client ID</code> and <code>Client secret</code> in your environment.</li>\n</ul>\n<p><a href=\"https://i.imgur.com/fiPAJk7.png\"><img src=\"https://i.imgur.com/fiPAJk7.png\"></a></p>\n<br>\n\n<p><strong>2.</strong> Go to this collection in Postman, under the <code>Auth</code> tag, follow this workflow:</p>\n<blockquote>\n<p>choose <code>OAuth 2.0</code> from the Tpye dropdown list → click <code>Get New Access Token</code> → fill <code>Auth URL</code> with <code>https://accounts.google.com/o/oauth2/v2/auth?access_type=offline</code> → fill <code>Access Token URL</code> with <code>https://www.googleapis.com/oauth2/v4/token</code> → fill <code>Client ID</code> with the client ID you got above → fill <code>Client Secret</code> with the client secret you got above → fill <code>Scope(Optional)</code> with <code>https://www.googleapis.com/auth/analytics.readonly</code> → select <code>Authorization Code</code> from the dropdown list → check <code>Request access token locally</code> → click <code>Request Token</code>.</p>\n</blockquote>\n<ul>\n<li>Save the <code>refresh_token</code> in your environment (<strong>Important !</strong>)</li>\n<li>Save the <code>access_token</code> in your environment and it is valid in the next couple minutes.</li>\n</ul>\n<p><a href=\"https://i.imgur.com/6g45Zor.png\"><img src=\"https://i.imgur.com/6g45Zor.png\"></a></p>\n<br>\n\n<p><strong>3.</strong> If you forgot to save the <code>refresh_token</code> for the first time you send the request, you won't be able to get the <code>refresh_token</code> again. Here's what you need to do:</p>\n<blockquote>\n<p>go to <a href=\"https://www.google.com/settings/u/1/security\">Google Sign-in &amp; security</a> → scroll down to <code>Connected apps &amp; sites</code> and click <code>MANAGE APPS</code> → click on your project → click <code>REMOVE</code> → go to Postman App and click <code>Request Token</code> again.</p>\n</blockquote>\n<p><a href=\"https://i.imgur.com/wL86flT.png\"><img src=\"https://i.imgur.com/wL86flT.png\"></a></p>\n</body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[],"owner":"792488","collectionId":"cff94895-6b05-4736-862e-40f4d8fb0217","publishedId":"6thxLUw","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"EF5B25"},"publishDate":"2017-09-22T22:53:14.000Z"},"item":[{"name":"GA Fetch Avg","event":[{"listen":"test","script":{"type":"text/javascript","exec":["if (pm.response.code === 200) {","    //average Mon","    var mon_total_value = pm.response.json().reports[0].data.totals[0].values[0];","    var mon_total_day = pm.response.json().reports[0].data.rowCount;","    pm.environment.set('avg_mon_pageviews', mon_total_value/mon_total_day);","    ","    //average Tue, Wed, and Thu","    var TueThu_total_value = pm.response.json().reports[1].data.totals[0].values[0];","    var TheThu_total_day = pm.response.json().reports[1].data.rowCount;","    pm.environment.set('avg_tuethu_pageviews', TueThu_total_value/TheThu_total_day);","    ","    //average Fri","    var fri_total_value = pm.response.json().reports[2].data.totals[0].values[0];","    var fri_total_day = pm.response.json().reports[2].data.rowCount;","    pm.environment.set('avg_fri_pageviews', fri_total_value/fri_total_day);","    ","    //average Sat","    var sat_total_value = pm.response.json().reports[3].data.totals[0].values[0];","    var sat_total_day = pm.response.json().reports[3].data.rowCount;","    pm.environment.set('avg_sat_pageviews', sat_total_value/sat_total_day);","    ","    //average Sun","    var sun_total_value = pm.response.json().reports[4].data.totals[0].values[0];","    var sun_total_day = pm.response.json().reports[4].data.rowCount;","    pm.environment.set('avg_sun_pageviews', sun_total_value/sun_total_day);","} else if (pm.response.code === 401) {","    postman.setNextRequest(\"Refresh Token\");","}",""]}}],"id":"5841eed0-cf76-4e06-af38-6692cc98c45b","request":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{access_token}}"},{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n\t\"reportRequests\": [\n\t\t{\n\t\t\t\"viewId\": {{View-ID}},\n\t\t\t\"dateRanges\": [\n\t\t\t\t{\n\t\t\t\t\t\"startDate\": \"186daysAgo\",\n\t\t\t\t\t\"endDate\": \"7daysAgo\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"metrics\": [\n\t\t\t\t{\n\t\t\t\t\t\"expression\": \"ga:pageviews\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"dimensions\":[\n\t\t\t\t{\n\t\t\t\t\t\"name\":\"ga:date\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"dimensionFilterClauses\": [\n\t\t        {\n\t\t\t\t\t\"filters\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"dimensionName\": \"ga:dayOfWeek\",\n\t\t\t\t\t\t\t\"operator\": \"NUMERIC_EQUAL\",\n\t\t\t\t\t\t\t\"expressions\": [\"1\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"viewId\": {{View-ID}},\n\t\t\t\"dateRanges\": [\n\t\t\t\t{\n\t\t\t\t\t\"startDate\": \"186daysAgo\",\n\t\t\t\t\t\"endDate\": \"7daysAgo\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"metrics\": [\n\t\t\t\t{\n\t\t\t\t\t\"expression\": \"ga:pageviews\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"dimensions\":[\n\t\t\t\t{\n\t\t\t\t\t\"name\":\"ga:date\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"dimensionFilterClauses\": [\n\t\t        {\n\t\t        \t\"operator\": \"AND\",\n\t\t\t\t\t\"filters\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"dimensionName\": \"ga:dayOfWeek\",\n\t\t\t\t\t\t\t\"operator\": \"NUMERIC_GREATER_THAN\",\n\t\t\t\t\t\t\t\"expressions\": [\"1\"]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"dimensionName\": \"ga:dayOfWeek\",\n\t\t\t\t\t\t\t\"operator\": \"NUMERIC_LESS_THAN\",\n\t\t\t\t\t\t\t\"expressions\": [\"5\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"viewId\": {{View-ID}},\n\t\t\t\"dateRanges\": [\n\t\t\t\t{\n\t\t\t\t\t\"startDate\": \"186daysAgo\",\n\t\t\t\t\t\"endDate\": \"7daysAgo\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"metrics\": [\n\t\t\t\t{\n\t\t\t\t\t\"expression\": \"ga:pageviews\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"dimensions\":[\n\t\t\t\t{\n\t\t\t\t\t\"name\":\"ga:date\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"dimensionFilterClauses\": [\n\t\t        {\n\t\t\t\t\t\"filters\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"dimensionName\": \"ga:dayOfWeek\",\n\t\t\t\t\t\t\t\"operator\": \"NUMERIC_EQUAL\",\n\t\t\t\t\t\t\t\"expressions\": [\"5\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"viewId\": {{View-ID}},\n\t\t\t\"dateRanges\": [\n\t\t\t\t{\n\t\t\t\t\t\"startDate\": \"186daysAgo\",\n\t\t\t\t\t\"endDate\": \"7daysAgo\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"metrics\": [\n\t\t\t\t{\n\t\t\t\t\t\"expression\": \"ga:pageviews\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"dimensions\":[\n\t\t\t\t{\n\t\t\t\t\t\"name\":\"ga:date\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"dimensionFilterClauses\": [\n\t\t        {\n\t\t\t\t\t\"filters\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"dimensionName\": \"ga:dayOfWeek\",\n\t\t\t\t\t\t\t\"operator\": \"NUMERIC_EQUAL\",\n\t\t\t\t\t\t\t\"expressions\": [\"6\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"viewId\": {{View-ID}},\n\t\t\t\"dateRanges\": [\n\t\t\t\t{\n\t\t\t\t\t\"startDate\": \"186daysAgo\",\n\t\t\t\t\t\"endDate\": \"7daysAgo\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"metrics\": [\n\t\t\t\t{\n\t\t\t\t\t\"expression\": \"ga:pageviews\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"dimensions\":[\n\t\t\t\t{\n\t\t\t\t\t\"name\":\"ga:date\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"dimensionFilterClauses\": [\n\t\t        {\n\t\t\t\t\t\"filters\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"dimensionName\": \"ga:dayOfWeek\",\n\t\t\t\t\t\t\t\"operator\": \"NUMERIC_EQUAL\",\n\t\t\t\t\t\t\t\"expressions\": [\"0\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n}"},"url":"https://analyticsreporting.googleapis.com/v4/reports:batchGet","urlObject":{"protocol":"https","path":["v4","reports:batchGet"],"host":["analyticsreporting","googleapis","com"],"query":[],"variable":[]}},"response":[],"_postman_id":"5841eed0-cf76-4e06-af38-6692cc98c45b"},{"name":"GA Fetch","event":[{"listen":"test","script":{"type":"text/javascript","exec":["var moment = require('moment');","","if (pm.response.code === 200) {","    var report = { \"text\": \"No reliable data yet, please check Google Analytics at a later time.\" };","    var data = pm.response.json().reports[0].data;","    var start_date = moment(data.rows[0].dimensions, 'YYYY-MM-DD').format('L');","    var end_date = moment(data.rows[6].dimensions, 'YYYY-MM-DD').format('L');","    var upper_bund = 1.3; // + 30%","    var lower_bund = 0.7; // - 30%","    var max_mon_threshold = pm.environment.get('avg_mon_pageviews') * upper_bund;","    var min_mon_threshold = pm.environment.get('avg_mon_pageviews') * lower_bund;","    var max_tuethu_threshold = pm.environment.get('avg_tuethu_pageviews') * upper_bund;","    var min_tuethu_threshold = pm.environment.get('avg_tuethu_pageviews') * lower_bund;","    var max_fri_threshold = pm.environment.get('avg_fri_pageviews') * upper_bund;","    var min_fri_threshold = pm.environment.get('avg_fri_pageviews') * lower_bund;","    var max_sat_threshold = pm.environment.get('avg_sat_pageviews') * upper_bund;","    var min_sat_threshold = pm.environment.get('avg_sat_pageviews') * lower_bund;","    var max_sun_threshold = pm.environment.get('avg_sun_pageviews') * upper_bund;","    var min_sun_threshold = pm.environment.get('avg_sun_pageviews') * lower_bund;","    ","    if (true) {","        report = {","            \"attachments\": [{","                \"pretext\": \"<https://analytics.google.com/analytics/web/?authuser=2#report/content-pages/a43979731w76722927p79319544/%3F_u.dateOption%3Dlast7days%26_r.tabId%3Dexplorer/|Check Google Analytics for more detail>\",","                \"author_name\": \"www.getpostman.com\",","                \"color\": \"#E2763B\",","                \"title\": \"Weekly Pageview Report\",","                \"text\": \"from `\" + start_date + '` to `' + end_date + '`',","                \"footer\": \":fire: : more than 30% increase than past 3 months average \\n\\n :scream: : more than 30% decrease than past 3 months average.\",","                \"fallback\": \"Oops! Failed to render the data table.\",","                \"mrkdwn_in\": [\"fields\", \"text\"],","                \"fields\": [","        \t\t\t{","        \t\t\t    \"title\": \"Date\",","        \t\t\t\t\"value\": \"\",","        \t\t\t\t'short': true","        \t\t\t},","        \t\t\t{","        \t\t\t    \"title\": \"Pageviews\",","        \t\t\t\t\"value\": \"\",","        \t\t\t\t'short': true","        \t\t\t}","                ]","            }]","        };","        data.rows.forEach(val => {","            var week = moment(val.dimensions, 'YYYY-MM-DD').format('ddd');","            report.attachments[0].fields[0].value += week + \"\\n\\n\";","            ","            report.attachments[0].fields[1].value += +(val.metrics[0].values/1000).toFixed(1) + 'K';","            if (week === 'Mon') {","                if (val.metrics[0].values > max_mon_threshold) {","                    report.attachments[0].fields[1].value += ' :fire:';","                } else if (val.metrics[0].values < min_mon_threshold) {","                    report.attachments[0].fields[1].value += ' :scream:';","                }","            } else if (week === 'Tue' || week === 'Wed' || week === 'Thu') {","                if (val.metrics[0].values > max_tuethu_threshold) {","                    report.attachments[0].fields[1].value += ' :fire:';","                } else if (val.metrics[0].values < min_tuethu_threshold) {","                    report.attachments[0].fields[1].value += ' :scream:';","                }","            } else if (week === 'Fri') {","                if (val.metrics[0].values > max_fri_threshold) {","                    report.attachments[0].fields[1].value += ' :fire:';","                } else if (val.metrics[0].values < min_fri_threshold) {","                    report.attachments[0].fields[1].value += ' :scream:';","                }","            } else if (week === 'Sat') {","                if (val.metrics[0].values > max_sat_threshold) {","                    report.attachments[0].fields[1].value += ' :fire:';","                } else if (val.metrics[0].values < min_sat_threshold) {","                    report.attachments[0].fields[1].value += ' :scream:';","                }","            } else if (week === 'Sun') {","                if (val.metrics[0].values > max_sun_threshold) {","                    report.attachments[0].fields[1].value += ' :fire:';","                } else if (val.metrics[0].values < min_sun_threshold) {","                    report.attachments[0].fields[1].value += ' :scream:';","                }","            }","            report.attachments[0].fields[1].value += \"\\n\\n\";","        });","    }","    ","    pm.environment.set('GA_report', JSON.stringify(report));","    postman.setNextRequest(\"Post on Slack\");","} else if (pm.response.code === 401) {","    postman.setNextRequest(\"Refresh Token\");","}",""]}}],"id":"81797eb0-09ce-4d70-b6ed-895418575f5d","request":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{access_token}}"},{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n\t\"reportRequests\": [\n\t\t{\n\t\t\t\"viewId\": {{View-ID}},\n\t\t\t\"dateRanges\": [\n\t\t\t\t{\n\t\t\t\t\t\"startDate\": \"7daysAgo\",\n\t\t\t\t\t\"endDate\": \"yesterday\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"metrics\": [\n\t\t\t\t{\n\t\t\t\t\t\"expression\": \"ga:pageviews\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"dimensions\":[\n\t\t\t\t{\n\t\t\t\t  \"name\":\"ga:date\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n}"},"url":"https://analyticsreporting.googleapis.com/v4/reports:batchGet","urlObject":{"protocol":"https","path":["v4","reports:batchGet"],"host":["analyticsreporting","googleapis","com"],"query":[],"variable":[]}},"response":[],"_postman_id":"81797eb0-09ce-4d70-b6ed-895418575f5d"},{"name":"Refresh Token","event":[{"listen":"test","script":{"type":"text/javascript","exec":["tests[\"Status code is 200\"] = (pm.response.code === 200);","","if (pm.response.code === 200) {","    pm.environment.set('access_token', pm.response.json().access_token);","    postman.setNextRequest(\"GA Fetch Avg\");","} else if (pm.response.code === 401) {","    postman.setNextRequest(null); // terminate the collection run and warn the user in the test message.","    tests[\"refresh_token issue! Terminate the collection run.\"] = false;","}"]}}],"id":"4fb0ab49-d5bf-401f-89d6-09282615d03d","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/x-www-form-urlencoded"}],"body":{"mode":"urlencoded","urlencoded":[{"key":"client_id","value":"{{client_id}}","type":"text"},{"key":"client_secret","value":"{{client_secret}}","type":"text"},{"key":"grant_type","value":"refresh_token","type":"text"},{"key":"refresh_token","value":"{{refresh_token}}","type":"text"}]},"url":"https://www.googleapis.com/oauth2/v4/token","urlObject":{"protocol":"https","path":["oauth2","v4","token"],"host":["www","googleapis","com"],"query":[],"variable":[]}},"response":[],"_postman_id":"4fb0ab49-d5bf-401f-89d6-09282615d03d"},{"name":"Post on Slack","event":[{"listen":"test","script":{"type":"text/javascript","exec":["tests[\"Status code is 200\"] = (pm.response.code === 200);"]}}],"id":"d5ff7c6c-17c5-40d8-9db3-b7171ef1288e","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/x-www-form-urlencoded"}],"body":{"mode":"raw","raw":"{{GA_report}}"},"url":"{{webhook}}","urlObject":{"host":["{{webhook}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"d5ff7c6c-17c5-40d8-9db3-b7171ef1288e"}]}