public with sharing class SlackOpportunityPublisher { // Production business channel // private static final String slackURL = 'https://hooks.slack.com/services/######'; // Private channel for testing // private static final String slackURL = 'https://hooks.slack.com/services/#####'; public class Oppty { @InvocableVariable(label='Opportunity Owner') public String opptyOwnerName; @InvocableVariable(label='Opportunity Items') public String opptyItems; @InvocableVariable(label='Account Name') public String acctName; @InvocableVariable(label='Account Industry') public String acctIndustry; @InvocableVariable(label='Amount') public Decimal amount; // Getting the monthly total AggregateResult[] monthlyInvoices = [SELECT SUM(SaaSOptics_Invoice_Amount__c)sum FROM SaaSOptics_Invoice__c WHERE SaaSOptics_Invoice_Date__c >= THIS_MONTH AND SaaSOptics_Invoice_Date__c <= TODAY ]; public Decimal monthlySumAmount = (Decimal)monthlyInvoices[0].get('sum'); // Getting the quaterly total AggregateResult[] quaterlyInvoices = [SELECT SUM(SaaSOptics_Invoice_Amount__c)sum FROM SaaSOptics_Invoice__c WHERE SaaSOptics_Invoice_Date__c >= THIS_QUARTER AND SaaSOptics_Invoice_Date__c < NEXT_QUARTER ]; public Decimal quaterlySumAmount = (Decimal)quaterlyInvoices[0].get('sum'); // Getting the annual total AggregateResult[] annualInvoices = [SELECT SUM(SaaSOptics_Invoice_Amount__c)sum FROM SaaSOptics_Invoice__c WHERE SaaSOptics_Invoice_Date__c >=2018-01-01 AND SaaSOptics_Invoice_Date__c <= TODAY ]; public Decimal annualSumAmount = (Decimal)annualInvoices[0].get('sum'); } @InvocableMethod(label='Post to SlackV3') public static void postToSlack(List oppties) { Oppty o = oppties[0]; // If bulk, only post first to avoid overloading Slack channel // Create a format that looks better in Slack when posted Map msg = new Map(); List args = new String[]{'0','number','###,###,##0.00'}; // Formatting the amounts to have commas and decimal values String ot = String.format(o.amount.format(), args); String mt = String.format(o.monthlySumAmount.format(), args); String at = String.format(o.annualSumAmount.format(), args); String qt = String.format(o.quaterlySumAmount.format(), args); // Setting the message contents msg.put('text','Month total before order: $*' + mt + '*\n' + 'Quarter total before order: $*' + qt + '*\n' + 'Annual total before order: $*' + at + '*\n\n' + o.opptyOwnerName + ' just closed a new opportunity with *' + o.acctName + '* in the *' + o.acctIndustry + '* industry, worth a total of $*' + ot + '* . Check out the details in the document links below. :champagne:\n\n' + o.opptyItems); msg.put('mrkdwn', true); String body = JSON.serialize(msg); System.enqueueJob(new QueueableSlackCall(slackURL, 'POST', body)); } public class QueueableSlackCall implements System.Queueable, Database.AllowsCallouts { private final String url; private final String method; private final String body; public QueueableSlackCall(String url, String method, String body) { this.url = url; this.method = method; this.body = body; } public void execute(System.QueueableContext ctx) { HttpRequest req = new HttpRequest(); req.setEndpoint(url); req.setMethod(method); req.setBody(body); Http http = new Http(); if (!Test.isRunningTest()) { // HTTP callout is not allowed in tests apparently... HttpResponse res = http.send(req); } } } }