Skip to main content

How We Automated Enterprise Browser Onboarding with a Slack Bot

  • July 30, 2026
  • 0 replies
  • 7 views

Forum|alt.badge.img+10

The problem we kept running into

Every day, multiple Netskope employees would post in our internal #customerzero Slack channel asking for Enterprise Browser (EB) access. The messages were nearly identical: someone had just heard about EB, wanted to try it out, and needed a license key or enrollment invite to get started.

The CZ team would then manually look up the user, send an enrollment invite through the Netskope admin console, and reply in the thread. This worked, but it was repetitive, manual work that pulled our team away from higher-value investigations and dogfooding activities.

We started asking ourselves: why are we the bottleneck here? The process was entirely mechanical — receive request, identify user, send invite, confirm. It was a perfect candidate for automation.

📊 By the numbers

After analyzing 200+ posts in #customerzero, Enterprise Browser invite/license key requests were the second most common issue category — 16+ posts, fully repeatable, zero judgment required to resolve.
​​​​​

What we built

We built a Slack bot — CZ Bot — that automatically detects Enterprise Browser invite requests in #customerzero, pulls the requesting user's email from their Slack profile, and calls the Netskope EB enrollment API to send the invite. The entire flow takes under 5 seconds from message to confirmation.

 

✅ Before vs After

Before: User posts → CZ team sees it → manually looks up email → opens admin console → sends invite → replies in Slack. Time: 15–60 minutes depending on team availability.After: User posts → CZ Bot detects it → pulls email from Slack → calls Netskope API → invite sent → bot confirms in thread. Time: under 5 seconds. Zero human involvement.
​​​​​​

 

How it works — user experience

From the user's perspective, the experience is simple. They post a message in #customerzero mentioning they need an Enterprise Browser invite or license key. Within seconds, CZ Bot replies in the thread confirming the invite has been sent to their Netskope email address.

They don't need to open a ticket, DM anyone, or wait for business hours. The bot handles it instantly, 24/7.

 

Example interaction:

👤 Madhura Sridhar  •  10:42 AM

Hi Team, I'm having issue with my EB — need a license key to get started.

🤖 CZ Bot  •  10:42 AM

Hi! ✅ Done — EB enrollment invite sent to msridhar@netskope.com. Check your inbox 📧

If you don't receive it within a few minutes, check your spam or reply here and we'll re-send.
​​​​​​

The tech behind it

We built this using a combination of Slack's Events API, Tines (our security automation platform), and the Netskope Enterprise Browser enrollment API. Here's the architecture at a high level:

 

Component

Role

Slack Events API

Delivers new messages from #customerzero to our automation in real time

Tines Cloud

Public-facing entry point — receives the Slack event, handles verification, and filters for EB invite requests

Tines On-Prem

Processes the event behind our Netskope Private Access layer — fetches the user's email and calls the EB API

Netskope EB Enrollment API

Sends the enrollment invite directly to the user's email via POST /api/v2/nsbrowser/invite

Slack API (chat.postMessage)

Posts the confirmation reply back to the thread

 

Edge cases we handled

Building this taught us a few things about real-world Slack automation:

 

  • Third-party requests: Sometimes users ask for an invite on behalf of a colleague (e.g. 'can you send an EB invite to @Francisco Mena'). We detect @mentions in the message and send the invite to the mentioned user's email instead of the sender's.
  • Bot loop prevention: Without filtering, the bot would respond to its own replies, creating an infinite loop. We added a bot_id null check to ignore all bot-generated messages.
  • Thread reply filtering: The bot only responds to top-level channel messages, not replies within existing threads.
  • API failure fallback: If the Netskope enrollment API call fails, the bot posts a fallback message tagging the CZ team to handle it manually.
  • Private channels: We extended the bot to work in private Slack channels by adding the groups:history and message.groups scopes.

 

What's next

This is just the first automation in what we're building out as a broader CZ support bot. The next phase will add a generic triage response for all other NS Client issues — prompting users to share their OS version, NS Client version, and screenshots to help the team investigate faster.

We're also exploring extending this pattern to other repetitive request types in the channel. If you're a Netskope customer interested in replicating this for your own internal support channels, reach out to your Netskope account team — we're happy to share the implementation details.

 

 

 

HIGH-LEVEL LOGIC

CZ Bot — EB Invite Automation

Architecture & flow reference for internal and customer documentation

System architecture

The bot uses a two-tier Tines architecture to bridge the public internet (Slack) with Netskope's internal on-prem systems:

Slack (#customerzero)

↓  Events API (message.channels / message.groups)

Tines Cloud (frosty-hill-7339.tines.com)

[ Webhook → Filter EB Invite Messages → Forward to On-Prem ]

↓  HTTPS tunnel via Netskope Private Access

Tines On-Prem (frosty-mountain.netskope.io)

[ Check for Mention → Get User Email → Send EB Invite → Post Reply ]

↓  Slack API (chat.postMessage)          ↓  Netskope EB API

 

Step-by-step flow

 

1

Message received

User posts a message in #customerzero (or any channel the bot is invited to). Slack delivers the event to Tines Cloud via the Events API.

 

 

2

Filter: real messages only

Tines Cloud checks that the message is a top-level post (not a thread reply), not from a bot, and of type 'message'. Thread replies and bot messages are discarded.

 

 

3

Filter: EB invite keywords

The message text is checked against a keyword list (e.g. 'license key', 'enterprise browser', 'EB invite', 'enroll'). If no keywords match, the message is forwarded to the generic response flow instead.

 

 

4

Forward to On-Prem

Tines Cloud forwards the Slack event payload to the on-prem Tines instance via an HTTPS tunnel through Netskope Private Access.

 

 

5

Check for @mention

On-prem checks whether the message contains an @mention of another user using regex. If yes, the invite goes to the mentioned user. If no, it goes to the message sender.

 

 

6

Fetch user email

Tines On-Prem calls the Slack API (users.info) to retrieve the target user's email address from their Slack profile.

 

 

7

Send EB enrollment invite

Tines On-Prem calls the Netskope EB enrollment API (POST /api/v2/nsbrowser/invite) with the user's email. The API sends the enrollment email directly to the user.

 

 

8

Post confirmation

Tines On-Prem calls the Slack API (chat.postMessage) to post a confirmation reply in the original message thread, confirming the invite was sent.

 

 

9

Fallback on error

If the Netskope API call fails, the bot posts a fallback message in the thread tagging the CZ team to handle it manually.

 

 

Key decision points

Decision point

If true

If false

Is message a top-level post?

Continue processing

Discard — no response

Is message from a bot?

Discard — no response

Continue processing

Does message match EB keywords?

Route to EB invite flow

Route to generic response flow

Does message contain @mention?

Send invite to mentioned user

Send invite to message sender

Did Netskope API succeed?

Post confirmation in thread

Post fallback, tag CZ team

 

Netskope EB Enrollment API

The bot uses the following API call to send enrollment invites:

POST https://<tenant>.goskope.com/api/v2/nsbrowser/invite



Headers:

  Authorization: Bearer <token>

  Content-Type: application/json



Body:

  {

    "invitation": {

      "userIds": ["user@netskope.com"]

    },

    "sendInvitationEmail": true,

    "emailTemplate": 0

  }

Scopes and permissions required

 

Scope

Type

Purpose

channels:history

Slack Bot

Read messages from public channels

groups:history

Slack Bot

Read messages from private channels

chat:write

Slack Bot

Post messages to channels

users:read

Slack Bot

Fetch user profile information

users:read.email

Slack Bot

Fetch user email from Slack profile

message.channels

Slack Event

Subscribe to public channel messages

message.groups

Slack Event

Subscribe to private channel messages