├── Episode 0.gs ├── Episode 1.gs ├── Episode 2.gs ├── Episode 3.gs ├── Episode 4.gs └── README.md /Episode 0.gs: -------------------------------------------------------------------------------- 1 | const cc = DataStudioApp.createCommunityConnector(); 2 | 3 | function getAuthType() { 4 | 5 | } 6 | 7 | function getConfig() { 8 | 9 | } 10 | 11 | function getSchema() { 12 | 13 | } 14 | 15 | function getData() { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /Episode 1.gs: -------------------------------------------------------------------------------- 1 | const cc = DataStudioApp.createCommunityConnector(); 2 | 3 | function getAuthType() { 4 | return cc.newAuthTypeResponse() 5 | .setAuthType(cc.AuthType.KEY) 6 | .setHelpUrl('https://p.nomics.com/cryptocurrency-bitcoin-api') 7 | .build(); 8 | } 9 | 10 | function resetAuth() { 11 | var userProperties = PropertiesService.getUserProperties(); 12 | userProperties.deleteProperty('dscc.key'); 13 | } 14 | 15 | function isAuthValid() { 16 | var userProperties = PropertiesService.getUserProperties(); 17 | var key = userProperties.getProperty('dscc.key'); 18 | var res = UrlFetchApp.fetch(`https://api.nomics.com/v1/markets?key=${key}`, { 'muteHttpExceptions':true }); 19 | return res.getResponseCode() == 200; 20 | } 21 | 22 | function setCredentials(request) { 23 | var key = request.key; 24 | var res = UrlFetchApp.fetch(`https://api.nomics.com/v1/markets?key=${key}`, { 'muteHttpExceptions':true }); 25 | if (res.getResponseCode() != 200) { 26 | return cc.newSetCredentialsResponse() 27 | .setIsValid(false) 28 | .build(); 29 | } else { 30 | var userProperties = PropertiesService.getUserProperties(); 31 | userProperties.setProperty('dscc.key', key); 32 | return cc.newSetCredentialsResponse() 33 | .setIsValid(true) 34 | .build(); 35 | } 36 | } 37 | 38 | function getConfig() { 39 | 40 | } 41 | 42 | function getSchema() { 43 | 44 | } 45 | 46 | function getData() { 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Episode 2.gs: -------------------------------------------------------------------------------- 1 | const cc = DataStudioApp.createCommunityConnector(); 2 | 3 | function getAuthType() { 4 | return cc.newAuthTypeResponse() 5 | .setAuthType(cc.AuthType.KEY) 6 | .setHelpUrl('https://p.nomics.com/cryptocurrency-bitcoin-api') 7 | .build(); 8 | } 9 | 10 | function resetAuth() { 11 | var userProperties = PropertiesService.getUserProperties(); 12 | userProperties.deleteProperty('dscc.key'); 13 | } 14 | 15 | function isAuthValid() { 16 | var userProperties = PropertiesService.getUserProperties(); 17 | var key = userProperties.getProperty('dscc.key'); 18 | var res = UrlFetchApp.fetch(`https://api.nomics.com/v1/markets?key=${key}`, { 'muteHttpExceptions':true }); 19 | return res.getResponseCode() == 200; 20 | } 21 | 22 | function setCredentials(request) { 23 | var key = request.key; 24 | var res = UrlFetchApp.fetch(`https://api.nomics.com/v1/markets?key=${key}`, { 'muteHttpExceptions':true }); 25 | if (res.getResponseCode() != 200) { 26 | return cc.newSetCredentialsResponse() 27 | .setIsValid(false) 28 | .build(); 29 | } else { 30 | var userProperties = PropertiesService.getUserProperties(); 31 | userProperties.setProperty('dscc.key', key); 32 | return cc.newSetCredentialsResponse() 33 | .setIsValid(true) 34 | .build(); 35 | } 36 | } 37 | 38 | function getConfig() { 39 | const config = cc.getConfig(); 40 | 41 | const option1 = config.newOptionBuilder() 42 | .setLabel('U.S. Dollars (USD)') 43 | .setValue("USD"); 44 | const option2 = config.newOptionBuilder() 45 | .setLabel('Euros (EUR)') 46 | .setValue("EUR"); 47 | const option3 = config.newOptionBuilder() 48 | .setLabel('Japanese Yen (JPY)') 49 | .setValue("JPY"); 50 | const option4 = config.newOptionBuilder() 51 | .setLabel('Pound Sterling (GBP)') 52 | .setValue("GBP"); 53 | 54 | config.newSelectSingle() 55 | .setId('currency') 56 | .setName('Please Select a Currency to Quote the Ticker Prices') 57 | .addOption(option1) 58 | .addOption(option2) 59 | .addOption(option3) 60 | .addOption(option4); 61 | 62 | config.newInfo() 63 | .setText('To learn more about currencies please go here: https://en.wikipedia.org/wiki/Currency'); 64 | 65 | return config.build(); 66 | } 67 | 68 | function getSchema() { 69 | 70 | } 71 | 72 | function getData(request) { 73 | 74 | } 75 | -------------------------------------------------------------------------------- /Episode 3.gs: -------------------------------------------------------------------------------- 1 | const cc = DataStudioApp.createCommunityConnector(); 2 | 3 | function getAuthType() { 4 | return cc.newAuthTypeResponse() 5 | .setAuthType(cc.AuthType.KEY) 6 | .setHelpUrl('https://p.nomics.com/cryptocurrency-bitcoin-api') 7 | .build(); 8 | } 9 | 10 | function resetAuth() { 11 | var userProperties = PropertiesService.getUserProperties(); 12 | userProperties.deleteProperty('dscc.key'); 13 | } 14 | 15 | function isAuthValid() { 16 | var userProperties = PropertiesService.getUserProperties(); 17 | var key = userProperties.getProperty('dscc.key'); 18 | var res = UrlFetchApp.fetch(`https://api.nomics.com/v1/markets?key=${key}`, { 'muteHttpExceptions':true }); 19 | return res.getResponseCode() == 200; 20 | } 21 | 22 | function setCredentials(request) { 23 | var key = request.key; 24 | var res = UrlFetchApp.fetch(`https://api.nomics.com/v1/markets?key=${key}`, { 'muteHttpExceptions':true }); 25 | if (res.getResponseCode() != 200) { 26 | return cc.newSetCredentialsResponse() 27 | .setIsValid(false) 28 | .build(); 29 | } else { 30 | var userProperties = PropertiesService.getUserProperties(); 31 | userProperties.setProperty('dscc.key', key); 32 | return cc.newSetCredentialsResponse() 33 | .setIsValid(true) 34 | .build(); 35 | } 36 | } 37 | 38 | function getConfig() { 39 | const config = cc.getConfig(); 40 | 41 | const option1 = config.newOptionBuilder() 42 | .setLabel('U.S. Dollars (USD)') 43 | .setValue("USD"); 44 | const option2 = config.newOptionBuilder() 45 | .setLabel('Euros (EUR)') 46 | .setValue("EUR"); 47 | const option3 = config.newOptionBuilder() 48 | .setLabel('Japanese Yen (JPY)') 49 | .setValue("JPY"); 50 | const option4 = config.newOptionBuilder() 51 | .setLabel('Pound Sterling (GBP)') 52 | .setValue("GBP"); 53 | 54 | config.newSelectSingle() 55 | .setId('currency') 56 | .setName('Please Select a Currency to Quote the Ticker Prices') 57 | .addOption(option1) 58 | .addOption(option2) 59 | .addOption(option3) 60 | .addOption(option4); 61 | 62 | config.newInfo() 63 | .setText('To learn more about currencies please go here: https://en.wikipedia.org/wiki/Currency'); 64 | 65 | return config.build(); 66 | } 67 | 68 | function getFields() { 69 | const fields = cc.getFields(); 70 | 71 | fields.newDimension() 72 | .setId('date') 73 | .setName('Date') 74 | .setDescription('The Date at Midnight') 75 | .setType(cc.FieldType.YEAR_MONTH_DAY); 76 | 77 | fields.newDimension() 78 | .setId('ticker') 79 | .setName('Ticker Symbol') 80 | .setDescription('The Ticker Symbol') 81 | .setType(cc.FieldType.TEXT); 82 | 83 | fields.newMetric() 84 | .setId('prices') 85 | .setName('Prices') 86 | .setDescription('The Price of the Cryptocurrency') 87 | .setType(cc.FieldType.NUMBER); 88 | 89 | return fields; 90 | } 91 | 92 | function getSchema() { 93 | return cc.newGetSchemaResponse() 94 | .setFields(getFields()) 95 | .build(); 96 | } 97 | 98 | function getData(request) { 99 | 100 | } 101 | -------------------------------------------------------------------------------- /Episode 4.gs: -------------------------------------------------------------------------------- 1 | const cc = DataStudioApp.createCommunityConnector(); 2 | 3 | function getAuthType() { 4 | return cc.newAuthTypeResponse() 5 | .setAuthType(cc.AuthType.KEY) 6 | .setHelpUrl('https://p.nomics.com/cryptocurrency-bitcoin-api') 7 | .build(); 8 | } 9 | 10 | function resetAuth() { 11 | var userProperties = PropertiesService.getUserProperties(); 12 | userProperties.deleteProperty('dscc.key'); 13 | } 14 | 15 | function isAuthValid() { 16 | var userProperties = PropertiesService.getUserProperties(); 17 | var key = userProperties.getProperty('dscc.key'); 18 | var res = UrlFetchApp.fetch(`https://api.nomics.com/v1/markets?key=${key}`, { 'muteHttpExceptions': true }); 19 | return res.getResponseCode() == 200; 20 | } 21 | 22 | function setCredentials(request) { 23 | var key = request.key; 24 | var res = UrlFetchApp.fetch(`https://api.nomics.com/v1/markets?key=${key}`, { 'muteHttpExceptions': true }); 25 | if (res.getResponseCode() != 200) { 26 | return cc.newSetCredentialsResponse() 27 | .setIsValid(false) 28 | .build(); 29 | } else { 30 | var userProperties = PropertiesService.getUserProperties(); 31 | userProperties.setProperty('dscc.key', key); 32 | return cc.newSetCredentialsResponse() 33 | .setIsValid(true) 34 | .build(); 35 | } 36 | } 37 | 38 | function getConfig() { 39 | const config = cc.getConfig(); 40 | 41 | const option1 = config.newOptionBuilder() 42 | .setLabel('U.S. Dollars (USD)') 43 | .setValue("USD"); 44 | const option2 = config.newOptionBuilder() 45 | .setLabel('Euros (EUR)') 46 | .setValue("EUR"); 47 | const option3 = config.newOptionBuilder() 48 | .setLabel('Japanese Yen (JPY)') 49 | .setValue("JPY"); 50 | const option4 = config.newOptionBuilder() 51 | .setLabel('Pound Sterling (GBP)') 52 | .setValue("GBP"); 53 | 54 | config.newSelectSingle() 55 | .setId('currency') 56 | .setName('Please Select a Currency to Quote the Ticker Prices') 57 | .addOption(option1) 58 | .addOption(option2) 59 | .addOption(option3) 60 | .addOption(option4); 61 | 62 | config.newInfo() 63 | .setText('To learn more about currencies please go here: https://en.wikipedia.org/wiki/Currency'); 64 | 65 | config.setDateRangeRequired(true); 66 | 67 | return config.build(); 68 | } 69 | 70 | function getFields() { 71 | const fields = cc.getFields(); 72 | 73 | fields.newDimension() 74 | .setId('date') 75 | .setName('Date') 76 | .setDescription('The Date at Midnight') 77 | .setType(cc.FieldType.YEAR_MONTH_DAY); 78 | 79 | fields.newDimension() 80 | .setId('ticker') 81 | .setName('Ticker Symbol') 82 | .setDescription('The Ticker Symbol') 83 | .setType(cc.FieldType.TEXT); 84 | 85 | fields.newMetric() 86 | .setId('prices') 87 | .setName('Prices') 88 | .setDescription('The Price of the Cryptocurrency') 89 | .setType(cc.FieldType.NUMBER); 90 | 91 | return fields; 92 | } 93 | 94 | function getSchema() { 95 | return cc.newGetSchemaResponse() 96 | .setFields(getFields()) 97 | .build(); 98 | } 99 | 100 | function getData(request) { 101 | const key = PropertiesService.getUserProperties().getProperty('dscc.key'); 102 | const ids = request.dimensionsFilters != null ? request.dimensionsFilters[0][0].values.join() : 'BTC,ETH,DOGE'; 103 | const start = request.dateRange.startDate; 104 | const end = request.dateRange.endDate; 105 | const currency = request.configParams != null ? request.configParams['currency'] : 'USD'; 106 | 107 | let res = UrlFetchApp.fetch(`https://api.nomics.com/v1/currencies/sparkline?key=${key}&ids=${ids}&start=${start}T00%3A00%3A00Z&end=${end}T00%3A00%3A00Z&convert=${currency}`); 108 | 109 | res = JSON.parse(res); 110 | 111 | let requestedIds = request.fields.map(object => object['name']); 112 | let data = []; 113 | 114 | for (let coin of res) { 115 | for (let timestamp in coin['timestamps']) { 116 | let row = []; 117 | for (let requestedId of requestedIds) { 118 | switch (requestedId) { 119 | case 'ticker': 120 | row.push(coin['currency']); 121 | break; 122 | case 'date': 123 | row.push(coin['timestamps'][timestamp].split('T')[0].replace(/-/g, '')); 124 | break; 125 | case 'prices': 126 | row.push(coin['prices'][timestamp]); 127 | break; 128 | default: 129 | break; 130 | } 131 | } 132 | data.push(row) 133 | } 134 | } 135 | 136 | let fields = getFields().forIds(requestedIds); 137 | 138 | return cc.newGetDataResponse() 139 | .setFields(fields) 140 | .addAllRows(data) 141 | .build(); 142 | } 143 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Apps-Script-Season-15-Data-Studio-Service 2 | The source code used in season 15 of my Apps Script Youtube channel (https://www.youtube.com/playlist?list=PL42xwJRIG3xBM88UgT79HKxO_u0ze3BZL) 3 | --------------------------------------------------------------------------------