This application is a Webex Integration that is intended to be used by a developer that manages and owns a Webex Service App. It serves as a companion app to facilitate secure OAuth flows and token management for Webex Service Apps.
The above diagram outlines a high-level overview of the intended use case for this application. It is a companion app to a Webex Service App that is owned, hosted and used by the Webex Developer.
This Node.js server is designed to:
- Handle OAuth flows from a Webex Integration
- Create webhooks for Webex events
- Manage token exchanges and refreshes
- Process authorization and token management requests
The server listens for HTTP requests and processes them to handle authorization and token management, making it easier for developers to integrate with Webex Service Apps.
📹 Watch this Vidcast for a demo on getting started!
- Prerequisites
- Installation
- Configuration
- Usage
- Architecture
- API Endpoints
- Code Overview
- Docker Support
- Troubleshooting
- Contributing
- License
- Webex Integration with the following scopes:
spark:all
spark:applications_token
application:webhooks_write
application:webhooks_read
- Webex Service App properly configured for your organization
- Webex Developer Sandbox (recommended for testing)
- ngrok or Pinggy for local development with HTTPS tunneling
-
Clone the repository:
git clone https://github.com/Joezanini/service_app_token_getter.git cd service_app_token_getter
-
Install dependencies:
npm install
-
Set up environment variables:
cp .env.example .env
Then edit the
.env
file with your credentials (see Configuration section).
Create a .env
file in the root of your project with the following variables:
# Server Configuration
PORT=3000
# Integration Credentials
INT_CLIENTID=your_integration_client_id
INT_CLIENTSECRET=your_integration_client_secret
# Service App Credentials
SA_CLIENTID=your_service_app_client_id
SA_CLIENTSECRET=your_service_app_client_secret
# OAuth Tokens (initially empty, will be populated automatically)
INT_ACCESSTOKEN=
INT_REFRESHTOKEN=
# Webex API Configuration
TOKEN_ENDPOINT=https://webexapis.com/v1/access_token
# Webhook Configuration
TARGET_URL=https://your-ngrok-url.ngrok.io/webhook
Variable | Description | Example |
---|---|---|
PORT |
Server port number | 3000 |
INT_CLIENTID |
Integration Client ID from Webex Developer Portal | C1234567890abcdef... |
INT_CLIENTSECRET |
Integration Client Secret from Webex Developer Portal | secret123... |
SA_CLIENTID |
Service App Client ID from Webex Developer Portal | S1234567890abcdef... |
SA_CLIENTSECRET |
Service App Client Secret from Webex Developer Portal | secret456... |
TARGET_URL |
Webhook endpoint URL (must include /webhook path) |
https://abc123.ngrok.io/webhook |
TARGET_URL
has the /webhook
appended as the server is listening at that endpoint.
-
Start the server:
node server.js
-
Start with automatic restart (development):
npm run dev
-
Access the application:
- Open your web browser and navigate to the integration registration page
- Retrieve the authorization URL from the black box on the form
-
Authorize the integration:
- Open a new incognito tab
- Paste the authorization URL into the browser
- Authorize the integration using the developer credentials that registered the integration
- This will redirect to the redirect URL (e.g.,
http://localhost:3000/redirect
)
Since webhooks require HTTPS, you'll need to use a tunneling service for local development:
Using ngrok:
ngrok http 3000
Using Pinggy:
ssh -p 443 -R0:localhost:3000 a.pinggy.io
Update your .env
file with the generated HTTPS URL:
TARGET_URL=https://your-tunnel-url.ngrok.io/webhook
graph TB
A[Developer] --> B[Webex Integration]
B --> C[OAuth Authorization]
C --> D[Service App Token Getter]
D --> E[Webex Service App]
D --> F[Webhook Handler]
F --> G[Token Management]
G --> H[Webex APIs]
sequenceDiagram
participant Dev as Developer
participant App as Token Getter App
participant Webex as Webex APIs
participant SA as Service App
Dev->>App: Start OAuth Flow
App->>Webex: Authorization Request
Webex->>Dev: Authorization Code
Dev->>App: Redirect with Code
App->>Webex: Exchange Code for Tokens
Webex->>App: Access & Refresh Tokens
App->>SA: Authorize Service App
SA->>App: Webhook Events
Handles webhook events from Webex, primarily focusing on Service App authorization events.
Request Body:
{
"id": "webhook-event-id",
"name": "authorized",
"data": {
"applicationId": "service-app-id",
"orgId": "organization-id"
}
}
Response:
{
"status": "success",
"message": "Webhook processed successfully"
}
Handles OAuth redirection and token exchange during the authorization flow.
Query Parameters:
code
: Authorization code from Webexstate
: State parameter for security
Response:
- Redirects to success page or returns error message
Package | Purpose | Version |
---|---|---|
http |
Node.js core module for HTTP server | Built-in |
axios |
Promise-based HTTP client | ^1.6.0 |
base64url |
Base64 encoding/decoding without padding | ^3.0.1 |
url |
Node.js core module for URL parsing | Built-in |
dotenv |
Environment variable management | ^16.3.1 |
Exchanges authorization code for access and refresh tokens.
const tokens = await exchangeCodeForTokens(authorizationCode);
Refreshes the access token using the refresh token.
const newTokens = await refreshTokens(currentRefreshToken);
Generates application ID based on the client ID.
const appId = generateApplicationId(serviceAppClientId);
Decodes the organization ID from a base64-encoded value.
const orgId = getOrgId(encodedOrgId);
Creates a webhook for the service app authorized event.
await createServiceAppAuthorizedWebhook();
Creates a webhook for the service app deauthorized event.
await createServiceAppDeauthorizedWebhook();
The server listens on the port specified in environment variables or defaults to port 3000. It handles the following endpoints:
/webhook
(POST): Processes webhook events, primarily focusing on theauthorized
anddeauthorized
events/redirect
(GET): Handles OAuth redirection and token exchange
docker build -t service-app-token-getter .
docker run -p 3000:3000 --env-file .env service-app-token-getter
version: '3.8'
services:
token-getter:
build: .
ports:
- "3000:3000"
env_file:
- .env
restart: unless-stopped
Run with:
docker-compose up -d
Problem: Webhooks fail to create or receive events.
Solution:
- Ensure
TARGET_URL
includes the/webhook
path - Verify your tunnel (ngrok/Pinggy) is running and accessible
- Check that your Integration has the required scopes
Problem: Authorization code exchange fails.
Solution:
- Verify Integration credentials in
.env
file - Check that the authorization URL is properly formatted
- Ensure the redirect URI matches your Integration configuration
Problem: Need to remove webhooks from the integration.
Solution:
- Get the webhook ID from the console logs
- Use the Webex API to delete the webhook:
curl -X DELETE "https://webexapis.com/v1/webhooks/{webhookId}" \ -H "Authorization: Bearer {access_token}"
- Alternatively, use the List Webhooks endpoint to find webhook IDs
Problem: Server fails to start due to missing environment variables.
Solution:
- Ensure all required variables are set in
.env
- Check for typos in variable names
- Verify
.env
file is in the project root
Enable debug logging by setting:
DEBUG=true
The application logs important events to the console:
- Token exchanges
- Webhook creations
- Authorization events
- Error messages
- Environment Variables: Never commit
.env
files to version control - HTTPS: Always use HTTPS for production webhooks
- Token Storage: Store tokens securely and refresh them regularly
- Access Control: Limit access to your Integration and Service App credentials
- Webhook Validation: Validate webhook signatures when available
For production deployments:
- Use a proper reverse proxy (nginx, Apache)
- Implement proper logging and monitoring
- Set up automated token refresh
- Use environment-specific configurations
- Implement proper error handling and retry logic
We welcome contributions! Please follow these steps:
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature-name
- Make your changes and test thoroughly
- Commit your changes:
git commit -m "Add your feature description"
- Push to your branch:
git push origin feature/your-feature-name
- Create a Pull Request
- Follow existing code style and conventions
- Add comments for complex logic
- Update documentation for new features
- Test your changes thoroughly
- Ensure all dependencies are properly declared
This project is licensed under the MIT License. See the LICENSE file for more details.
- Webex Developer Documentation
- Webex Integration Guide
- Webex Service Apps Guide
- Webex Webhooks Documentation
- OAuth 2.0 Specification
For issues and questions:
- Check the Troubleshooting section
- Review the Webex Developer Support
- Open an issue in this repository
Happy Coding! 🚀