diff --git a/Google_Scripts/AE_Reminders_Daily.gs b/Google_Scripts/AE_Reminders_Daily.gs index aecf2489..a8960613 100644 --- a/Google_Scripts/AE_Reminders_Daily.gs +++ b/Google_Scripts/AE_Reminders_Daily.gs @@ -1,129 +1,219 @@ -/* -Custom Fields: -Channel = customfield_10121 -Campaign = customfield_10120 -SDR = customfield_10122 -Start Date = customfield_10015 - -Users: -Travis Nardin = 5d9cb42c0265ca0db955b965 -Dan Peski = 603318815ddf020069969cad -Norm Rasmussen = 6092af20d353800068863d15 -Michael Valido = 61fbf60cd8d7cf006a90941c -Jon Newfield = 6092af212c2f6c0068ec92c4 -Isabel Katz = 620145241fec260068c107e5 -Charles McGovern = 5eaaf1c4021ae30ba8fcb184 -Nick Zuppe = 60eddda64257a90070aeebef -Doug Goldsmith = 61294a4845f753006951a590 -Nick Appleby = 6183eab7892c420072f9c437 -Quba Williams-Wilfong = 62101fe4e41f76006a6f6510 - -Without accounts: Adan, Drew - +/* + This script sends a daily reminder to the Sales and Marketing channel as to which + lines of data are unclean and not filled out. Currently, it is only pulling from the last 5 days. + This will be sent out between 3-4pm so that AEs can get their data in and clean before EOD. + Any questions or changes needed, see Norm. + Webhook URL in this sheet is for #sales-n-marketing channel. */ +// Setup of the sheet +const sheet = SpreadsheetApp.getActiveSheet(); -function myFunction() { - var URL = "https://northpass.atlassian.net/rest/api/3/issue/"; - // var accountID = "6092af20d353800068863d15"; - var token = "2NrKYv22TLWnxTo7EhU3633E"; - // var UserCredentials = Utilities.base64Encode(accountID + ":" + token); - var user = "nrasmussen@northpass.com"; - // var pass = "c9QK\>4^fxiHt!"; - var UserCredentials = Utilities.base64Encode(user + ":" + token); +// Setup of the date range to compare. Currently, it is using 5 days until Present. +var now = new Date(); +var formatNow = Utilities.formatDate(now, 'America/New_York', 'MM/dd/yyyy'); // Today +var daysToSubtract = 2; +var withinWeek = new Date(now.getTime()-daysToSubtract*(3600*24*1000)); +var formatWeek = Utilities.formatDate(withinWeek, 'America/New_York', 'MM/dd/yyyy'); // 5 Days ago - // Setting up data range and empty arrays - var list = []; - const sheet = SpreadsheetApp.getActiveSheet(); - var startRow = 244; // First col of data to process - var numRows = 450; // Number of rows to process - var dataRange = sheet.getRange(startRow, 1, numRows, sheet.getLastColumn()).getValues(); - // var data = dataRange.filter(function(r){ - // return r.join("").length>0; - // }); +// Counter for formatting the final list +var meetingCount = 0; - for (col in dataRange) { // For a data col within the entire data range - var col = dataRange[col]; - let sdr = col[0]; // Column - A - let name = col[1]; // Column - B - let rawDate = Utilities.formatDate(col[3], 'America/New_York', 'yyyy-MM-dd'); - let bookingDate = Utilities.formatDate(col[2], 'America/New_York', 'MM/dd/yyyy'); // Column - C - let meetingDate = Utilities.formatDate(col[3], 'America/New_York', 'MM/dd/yyyy'); // Column - D - let company = col[4]; // Column - E - let channel = col[5]; // Column - F - let result = col[7]; // Column - H - let campaign = col[8]; // Column - I - let info = col[9]; // Column - J - let list = [sdr, name, rawDate ,bookingDate, meetingDate, company, channel, result, campaign, info]; - list.toString(); - Logger.log(list); - let sdrDict = { - "Mike" : - "61fbf60cd8d7cf006a90941c", - "Nick" : - "60eddda64257a90070aeebef", - "Appleby" : - "6183eab7892c420072f9c437", - "Doug" : - "61294a4845f753006951a590", - "Quba" : - "62101fe4e41f76006a6f6510", +// Other empty Globals +var finalAEList; +var tagUsers; + +/* + This function will create two empty arrays, one for the list of missed entries and one for tagging users in Slack + First, the function gets the data ranges in spreadsheed and adds those columns to an array index. + Second, the for loop cycles through the super long array (4 results per line). Based on the if statement, + the loop removes all arrays that don't fit the statement. +*/ +function findMeetings() { // Setting up data range and empty arrays + var startRow = 2; // First row of data to process + var numRows = sheet.getLastRow()-1; // Number of rows to process + var dataRange = sheet.getRange(startRow, 1, numRows, sheet.getLastColumn()); + var data = dataRange.getValues(); + var slackingAEListOne = []; + var tagList = []; + + for (i in data) { // For a data row within the entire data range + var row = data[i]; + let attended = row[6]; // Column G + var name = row[1]; // Column - B + var date = Utilities.formatDate(row[3],'America/New_York','MM/dd/yyyy'); // Column - D + var company = row[4]; // Column - E + let missedEntries = [name, date, company, attended]; + /* + Adding a For Loop will pull a result for EACH element, aka 4 results per line. + This pulls one for each group of missedEntries + This then removes the last value (attended, since we already know it is a blank), converts to a string, + and adds to a new array. The counter will compare if there is more than one entry in the array. + */ + if ((missedEntries[3] == "") && (missedEntries[1] >= formatWeek) && (missedEntries[1] <= formatNow)) { + meetingCount += 1; + missedEntries.pop(); + missedEntries.toString(); + slackingAEListOne.push(missedEntries); + //Logger.log(slackingAEListOne); }; - if (list.includes("Norm")) { - var data = { - "fields": { - "project": { - "key": "NORMPIPE", - }, - "issuetype": { - "id": "10268", - }, - "summary": list[5], - "description": { - "type": "doc", - "version": 1, - "content": [ - { - "type": "paragraph", - "content": [ - { - "type": "text", - "text": "Booked Date - " + list[3] + '\n' + - "Meeting Date - " + list[4] + '\n' + - "Description from Tracker: " + list[9] + '\n' + - "Last Status - " + list[7] - } - ] - } - ], - }, - "customfield_10015": list[2], // Start (Meeting) Date - rawDate - "customfield_10120": [ // Campaign - list[8] - ], - "customfield_10122": [{"id" : sdrDict[list[0]]}], // SDR - "customfield_10121": [ // Channel - list[6] - ], + }; + /* Now outside of the if statement: + the array is built, and we want each group to be on a new line, remove the commas and add a hyphen. + The counter counts if there is 1 or more meetings, or not. If 0, it sends a certain message, not tagging anyone. + If it is one or more, it splices by the first array (index 0), adds a new line, and replaces commans with hyphens. + */ + if (meetingCount >= 1) { + var slackingAEListTwo = slackingAEListOne.splice(0).join('\n'); + var finalAEList = slackingAEListTwo.replace(/,/g, ' - '); + // This if statement is going to only tag those who appear in the previous list. + // No need to tag people who have done their work and contribute to clean data. + if (finalAEList.includes('Norm')) { + tagList.push('<@U020KRBDSDQ>'); + } + if (finalAEList.includes('Dan')) { + tagList.push('<@U01P7DTFSQZ>'); + } + if (finalAEList.includes('Charles')) { + tagList.push('<@U01286MQUS2>'); + } + if (finalAEList.includes('Travis')) { + tagList.push('<@UFE3T14UX>'); + } + if (finalAEList.includes('Nick')) { + tagList.push('<@U0276LMA70F>'); + } + if (finalAEList.includes('Mike')) { + tagList.push('<@U027MAQUPM0>'); + } + if (finalAEList.includes('Doug')) { + tagList.push('<@U02CK55FHFX>'); + } + if (finalAEList.includes('Isabel')) { + tagList.push('<@U03019S7R6F>'); + } + if (finalAEList.includes('Ryan')) { + tagList.push('<@U0325CWA3N3>'); + } + var tagUsers = tagList.toString(); + /* + Now, we're building the payload for the Slack Message. + This is very specific and prone to errors, so check that it works using Slack's tool: + https://app.slack.com/block-kit-builder/ + + Copy from Rich: + ":rotating_light::rotating_light::rotating_light: New Meeting Tracker Alert! :rotating_light::rotating_light::rotating_light: + It's your daily reminder to update the new meeting tracker. + If you've been tagged, please address this by EOD." + */ + let payloadText = +{ + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": ":rotating_light::rotating_light::rotating_light: New Meeting Tracker Alert! :rotating_light::rotating_light::rotating_light:" } }, - payload = JSON.stringify(data); - Logger.log(payload); - var headers = { - "Accept": "application/json", - "Content-Type": "application/json", - "Authorization": "Basic " + UserCredentials, - "muteHttpExceptions": true, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "It's your daily reminder to update the new meeting tracker." + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "If you've been tagged, please address this by EOD." + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": finalAEList // Sends list with AE, meeting date, and company + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "In case you need it, here's a link to the sheet. :point_right:" + }, + "accessory": { + "type": "button", + "text": { + "type": "plain_text", + "text": "Sales New Meeting Tracker", + "emoji": true + }, + "value": "sales_tracker_link_123", + "url": "https://docs.google.com/spreadsheets/d/150nSuHQLJHpJaYdQ6KHeN7nQ6iexwtnQEpicM77PK8A/edit#gid=0 | First Meeting Tracker", + "action_id": "button-action" + } + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": tagUsers // Tags with slack user numbers if they appear in finalSend + } } - var options = { - "method": "POST", - "headers": headers, - "payload": payload - } - //Logger.log(options); - var response = UrlFetchApp.fetch(URL, options); - //Logger.log(response); - var respCode = response.getResponseCode(); - //Logger.log(respCode); - } - } - }; + ] +}; + // This is standard operating procedure to creating the payload and destination + const webhook = "https://hooks.slack.com/services/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"; + const options = { + method: "post", + contentType: "application/json", + muteHttpExceptions: true, + payload: JSON.stringify(payloadText), + }; + const sendMsg = UrlFetchApp.fetch(webhook, options); + var respCode = sendMsg.getResponseCode(); + //Logger.log(sendMsg); // Debug to confirm send + //Logger.log(respCode); // Debug to show errors, if any + /* + This is the else statement that sends a certain message not tagging anyone and saying that data is clean. + */ + } else { + let noMeetingMsg = + { + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": ":star::star::star: New Meeting Tracker Alert! :star::star::star:" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "Good job, everyone! All meetings from the last 5 days are up to date. Keep doing what you're doing!" + } + } + ] +}; +// This is standard operating procedure to creating the payload and destination + + const webhook = "https://hooks.slack.com/services/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"; + const options = { + method: "post", + contentType: "application/json", + muteHttpExceptions: true, + payload: JSON.stringify(noMeetingMsg), + }; + const sendMsg = UrlFetchApp.fetch(webhook, options); + var respCode = sendMsg.getResponseCode(); + + //Logger.log(sendMsg); // Debug to confirm send + //Logger.log(respCode); // Debug to show errors, if any +} +};