(data: {
orgName: string;
domain: string;
owner: 'addie' | 'human';
priority?: 'high' | 'standard';
verdict: string;
companyType?: string;
source: string;
orgId?: string;
contactName?: string;
contactEmail?: string;
})
| 117 | } |
| 118 | |
| 119 | export async function notifyNewProspect(data: { |
| 120 | orgName: string; |
| 121 | domain: string; |
| 122 | owner: 'addie' | 'human'; |
| 123 | priority?: 'high' | 'standard'; |
| 124 | verdict: string; |
| 125 | companyType?: string; |
| 126 | source: string; |
| 127 | orgId?: string; |
| 128 | contactName?: string; |
| 129 | contactEmail?: string; |
| 130 | }): Promise<boolean> { |
| 131 | if (!isSlackConfigured()) { |
| 132 | logger.debug('Slack not configured, skipping prospect notification'); |
| 133 | return false; |
| 134 | } |
| 135 | |
| 136 | const channel = await getProspectChannel(); |
| 137 | if (!channel.channel_id) { |
| 138 | logger.debug('Prospect channel not configured, skipping notification'); |
| 139 | return false; |
| 140 | } |
| 141 | |
| 142 | const typeLabel = data.companyType ? getCompanyTypeLabel(data.companyType) : 'Unknown'; |
| 143 | const sourceLabel = data.source === 'slack' ? 'Slack join' : data.source === 'inbound' ? 'Website signup' : data.source; |
| 144 | const priorityLabel = data.priority === 'high' ? 'High priority' : 'Standard'; |
| 145 | |
| 146 | const isHumanNeeded = data.owner === 'human'; |
| 147 | const hasOrg = !!data.orgId; |
| 148 | const headerText = isHumanNeeded |
| 149 | ? 'Enterprise prospect needs an owner' |
| 150 | : 'New prospect auto-triaged'; |
| 151 | const ownerLabel = isHumanNeeded |
| 152 | ? 'Needs a human owner' |
| 153 | : hasOrg |
| 154 | ? `Addie (auto-claimed${data.priority === 'high' ? ', high priority' : ''})` |
| 155 | : `Addie (recommended${data.priority === 'high' ? ', high priority' : ''})`; |
| 156 | |
| 157 | const text = isHumanNeeded |
| 158 | ? `Enterprise prospect needs an owner: ${data.orgName} (${data.domain})` |
| 159 | : `New prospect: ${data.orgName} (${data.domain})`; |
| 160 | |
| 161 | const blocks: SlackBlock[] = [ |
| 162 | { |
| 163 | type: 'header', |
| 164 | text: { type: 'plain_text', text: headerText, emoji: true } as SlackTextObject, |
| 165 | }, |
| 166 | { |
| 167 | type: 'section', |
| 168 | fields: [ |
| 169 | { type: 'mrkdwn', text: `*Company:*\n${data.orgName}` }, |
| 170 | { type: 'mrkdwn', text: `*Domain:*\n${data.domain}` }, |
| 171 | { type: 'mrkdwn', text: `*Type:*\n${typeLabel}` }, |
| 172 | { type: 'mrkdwn', text: `*Source:*\n${sourceLabel}` }, |
| 173 | ], |
| 174 | }, |
| 175 | ]; |
| 176 |
no test coverage detected