W
Wasp7d ago
Kynetix

Call custom api externally

I created a custom API that sends data to a database, and I want to call it from another application. I used fetch() to post the data, and got a 401 (unauthorized) as expected. I know I need to send a token or something in the header. How do I do that?
17 Replies
kapa.ai
kapa.ai7d ago
Hi @Kynetix. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To call a custom API in Wasp from an external application, you need to handle authentication properly. The 401 error you're receiving indicates that your API endpoint is protected and requires authentication. Adding Authentication to External API Calls When you make a request to a Wasp API endpoint that has auth: true set, you need to include a valid JWT token in the Authorization header. Here's how to do it: 1. First, make sure your API is properly configured in your main.wasp file:
api yourApiName {
fn: import { yourApiFunction } from "@src/apis",
httpRoute: (POST, "/your/route"),
auth: true // This is what's causing the 401 error
}
api yourApiName {
fn: import { yourApiFunction } from "@src/apis",
httpRoute: (POST, "/your/route"),
auth: true // This is what's causing the 401 error
}
2. To call this API externally, you need to include the JWT token in your fetch request:
fetch('<https://your-app-url.com/your/route',> {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_JWT_TOKEN'
},
body: JSON.stringify(yourData)
})
fetch('<https://your-app-url.com/your/route',> {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_JWT_TOKEN'
},
body: JSON.stringify(yourData)
})
Getting a JWT Token You have a few options to get a valid JWT token: 1. Create a login endpoint: You can create a custom API endpoint that authenticates users and returns a JWT token. This is similar to what's shown in the Discord thread where someone implemented a generateJwt endpoint in this Discord thread. 2. Use an existing auth method: If you're using one of Wasp's built-in auth methods (username/password, email, Google, GitHub), you can have users authenticate through those flows first to get a token. Alternative: Make the API Public If you don't need authentication for this specific endpoint, you can set auth: false in your API declaration:
api yourApiName {
fn: import { yourApiFunction } from "@src/apis",
httpRoute: (POST, "/your/route"),
auth: false // This makes the endpoint publicly accessible
}
api yourApiName {
fn: import { yourApiFunction } from "@src/apis",
httpRoute: (POST, "/your/route"),
auth: false // This makes the endpoint publicly accessible
}
This would allow you to call the API without authentication, but be careful with this approach if your API performs sensitive operations or accesses protected data. For more information about custom HTTP API endpoints in Wasp, check out the Custom HTTP API Endpoints documentation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Kynetix, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
Kynetix
KynetixOP7d ago
@kapa.ai I'm using the built-in authentication. How can I retrieve the token after the user logs in?
MEE6
MEE67d ago
Wohooo @Kynetix, you just became a Waspeteer level 4!
Kynetix
KynetixOP7d ago
@kapa.ai I'm using the built-in authentication. How can I retrieve the token after the user logs in?
kapa.ai
kapa.ai7d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- If you're using Wasp's built-in authentication, you should know that Wasp has moved from using JWT tokens to using sessions for authentication. This is an important distinction that affects how you would access authentication information. Current Authentication System in Wasp Wasp now uses sessions rather than JWT tokens for authentication:
Wasp's auth uses sessions to keep track of the logged-in user. The session is stored in localStorage on the client and in the database on the server. Under the hood, Wasp uses the excellent Lucia Auth v3 library for session management.
Auth Overview - Sessions This means that you don't directly access a token as you might expect. Instead, Wasp handles the session management for you behind the scenes. Accessing the Authenticated User To access the authenticated user in your client code, you can use the useAuth hook:
import { useAuth, logout } from 'wasp/client/auth'

export function MyComponent() {
const { data: user } = useAuth()

if (!user) {
return <span>Not logged in</span>
} else {
return (
<>
<p>Hello, {user.username}</p>
<button onClick={logout}>Logout</button>
</>
)
}
}
import { useAuth, logout } from 'wasp/client/auth'

export function MyComponent() {
const { data: user } = useAuth()

if (!user) {
return <span>Not logged in</span>
} else {
return (
<>
<p>Hello, {user.username}</p>
<button onClick={logout}>Logout</button>
</>
)
}
}
For External Applications If you're trying to access the authentication from an external application (like your previous question suggested), this becomes more complex because Wasp doesn't currently expose a direct API for authenticating users from external applications. As noted in a Discord conversation:
Unfortunately, Wasp doesn't yet expose the API for authenticating users (the idea is to use its internal RPC, which doesn't make sense for your use case).
Discord support thread For external applications, you might need to create a custom API endpoint that generates a JWT token specifically for external use, similar to what was discussed in another Discord thread about Chrome extensions. If you absolutely need to implement this for an external application, you would need to create a custom API endpoint that generates a JWT token based on the authenticated user's session. Would you like more information about any specific aspect of authentication in Wasp? ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Kynetix, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
Kynetix
KynetixOP7d ago
@kapa.ai please show me the implementation steps and an example custom API endpointsnfor generating JWT tokens
kapa.ai
kapa.ai7d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I'll show you how to implement a custom API endpoint for generating JWT tokens in Wasp. This approach is useful when you need to provide authentication for external applications. Implementation Steps 1. Declare the API in your main.wasp file First, you need to declare your custom API endpoint in your main.wasp file:
api generateJwt {
fn: import { generateJwt } from "@src/apis",
httpRoute: (POST, "/api/generate-jwt"),
entities: [User], // If you need to access the User entity
auth: false // This endpoint needs to be accessible without auth
}
api generateJwt {
fn: import { generateJwt } from "@src/apis",
httpRoute: (POST, "/api/generate-jwt"),
entities: [User], // If you need to access the User entity
auth: false // This endpoint needs to be accessible without auth
}
2. Implement the API function Next, create the implementation file for your API endpoint: - JavaScript
// src/apis.js
import jwt from 'jsonwebtoken';

export const generateJwt = async (req, res, context) => {
const { username, password } = req.body;

try {
// Authenticate the user (implement your authentication logic here)
const authResult = await authenticateUser(username, password);

if (!authResult.isAuthenticated) {
return res.status(401).json({ error: 'Invalid credentials' });
}

// User payload for JWT
const userPayload = {
username,
userId: authResult.userId
};

// Retrieve the secret key from environment variables
const secretKey = process.env.JWT_SECRET_KEY;

if (!secretKey) {
throw new Error('JWT secret key is missing');
}

// Token options
const options = { expiresIn: '1h' }; // Token expires in 1 hour

// Generate the JWT
const token = jwt.sign(userPayload, secretKey, options);

// Send the JWT back to the client
res.json({ token });
} catch (error) {
console.error('Error generating JWT token:', error);
res.status(500).json({ error: 'Internal server error' });
}
};
// Mock authentication function - replace with your actual auth logic
async function authenticateUser(username, password) {
// TODO: Implement actual user authentication logic here
// This should fetch the user from the database based on the provided username and password
// For demonstration, assuming authentication is successful and returning a mock user ID
return { isAuthenticated: true, userId: 'user123' };
}
// src/apis.js
import jwt from 'jsonwebtoken';

export const generateJwt = async (req, res, context) => {
const { username, password } = req.body;

try {
// Authenticate the user (implement your authentication logic here)
const authResult = await authenticateUser(username, password);

if (!authResult.isAuthenticated) {
return res.status(401).json({ error: 'Invalid credentials' });
}

// User payload for JWT
const userPayload = {
username,
userId: authResult.userId
};

// Retrieve the secret key from environment variables
const secretKey = process.env.JWT_SECRET_KEY;

if (!secretKey) {
throw new Error('JWT secret key is missing');
}

// Token options
const options = { expiresIn: '1h' }; // Token expires in 1 hour

// Generate the JWT
const token = jwt.sign(userPayload, secretKey, options);

// Send the JWT back to the client
res.json({ token });
} catch (error) {
console.error('Error generating JWT token:', error);
res.status(500).json({ error: 'Internal server error' });
}
};
// Mock authentication function - replace with your actual auth logic
async function authenticateUser(username, password) {
// TODO: Implement actual user authentication logic here
// This should fetch the user from the database based on the provided username and password
// For demonstration, assuming authentication is successful and returning a mock user ID
return { isAuthenticated: true, userId: 'user123' };
}
- TypeScript
// src/apis.ts
import * as jwt from 'jsonwebtoken';
import { Request, Response } from 'express';
import { GenerateJwt } from 'wasp/server/api'; // This type is generated by Wasp

// Adjusted authenticateUser function to also return user ID upon successful authentication
async function authenticateUser(username: string, password: string): Promise<{ isAuthenticated: boolean; userId?: string }> {
// TODO: Implement actual user authentication logic here
// This should fetch the user from the database based on the provided username and password
// For demonstration, assuming authentication is successful and returning a mock user ID
return { isAuthenticated: true, userId: 'user123' };
}
export const generateJwt: GenerateJwt = async (req, res, context) => {
const { username, password } = req.body;

try {
const authResult = await authenticateUser(username, password);

if (!authResult.isAuthenticated) {
res.status(401).json({ error: 'Invalid credentials' });
return;
}

// User payload for JWT
const userPayload = { username, userId: authResult.userId };

// Retrieve the secret key from environment variables
const secretKey = process.env.JWT_SECRET_KEY;

if (!secretKey) {
throw new Error('JWT secret key is missing');
}

// Token options
const options = { expiresIn: '1h' }; // Token expires in 1 hour

// Generate the JWT
const token = jwt.sign(userPayload, secretKey, options);

// Send the JWT back to the client
res.json({ token });
} catch (error) {
console.error('Error generating JWT token:', error);
res.status(500).json({ error: 'Internal server error' });
}
};
// src/apis.ts
import * as jwt from 'jsonwebtoken';
import { Request, Response } from 'express';
import { GenerateJwt } from 'wasp/server/api'; // This type is generated by Wasp

// Adjusted authenticateUser function to also return user ID upon successful authentication
async function authenticateUser(username: string, password: string): Promise<{ isAuthenticated: boolean; userId?: string }> {
// TODO: Implement actual user authentication logic here
// This should fetch the user from the database based on the provided username and password
// For demonstration, assuming authentication is successful and returning a mock user ID
return { isAuthenticated: true, userId: 'user123' };
}
export const generateJwt: GenerateJwt = async (req, res, context) => {
const { username, password } = req.body;

try {
const authResult = await authenticateUser(username, password);

if (!authResult.isAuthenticated) {
res.status(401).json({ error: 'Invalid credentials' });
return;
}

// User payload for JWT
const userPayload = { username, userId: authResult.userId };

// Retrieve the secret key from environment variables
const secretKey = process.env.JWT_SECRET_KEY;

if (!secretKey) {
throw new Error('JWT secret key is missing');
}

// Token options
const options = { expiresIn: '1h' }; // Token expires in 1 hour

// Generate the JWT
const token = jwt.sign(userPayload, secretKey, options);

// Send the JWT back to the client
res.json({ token });
} catch (error) {
console.error('Error generating JWT token:', error);
res.status(500).json({ error: 'Internal server error' });
}
};
3. Set up your environment variables Make sure to set up your JWT secret key in your environment variables. You can add it to your .env.server file:
JWT_SECRET_KEY=your_very_secure_secret_key
JWT_SECRET_KEY=your_very_secure_secret_key
4. Using the JWT token in external applications Once you have your JWT token, you can use it in external applications by including it in the Authorization header:
fetch('<https://your-wasp-app.com/your-protected-endpoint',> {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + jwtToken
}
})
fetch('<https://your-wasp-app.com/your-protected-endpoint',> {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + jwtToken
}
})
Testing Your API You can test your API using curl or Postman:
curl -X POST <http://localhost:3001/api/generate-jwt> \
-H "Content-Type: application/json" \
-d '{"username":"testuser","password":"verysecurepassword"}'
curl -X POST <http://localhost:3001/api/generate-jwt> \
-H "Content-Type: application/json" \
-d '{"username":"testuser","password":"verysecurepassword"}'
This implementation provides a basic JWT generation endpoint. Remember to replace the mock authentication function with your actual authentication logic that verifies credentials against your database. Custom HTTP API Endpoints documentation provides more details on how to work with custom APIs in Wasp. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Kynetix, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
toticozeni
toticozeni7d ago
Hey @Kynetix, how are are you using wasp with external API? Public API rework is something that is going to be done in future, so feedback can help us with shaping new API. As for your specific question, @miho knows the most about our auth possibilities.
Kynetix
KynetixOP6d ago
hi @franjo , I embedded a Flowise chatbot that queries the user, and the answers are http-POSTed to the external API (which saves the data to a Supabase db). The alternative would've been to call Supabase Edge functions, but I'm not too familiar with them (especially in terms of security) @kapa.ai I've written the following for creating a token: // BEGIN function export const createToken: CreateToken<{}, { status: string; data: string }> = (req, res, context) => { if (!context.user) { throw new HttpError(401); } try { // Create a JWT token with user id and email, expires in 1 hour const payload = { id: context.user.id, email: context.user.email, username: context.user.username, }; const secret = process.env.JWT_SECRET || 'zigozi_default_secret'; const token = jwt.sign(payload, secret, { expiresIn: '6h' }); res.json({ status: 'success', data:token }); } catch (error: unknown) { let errorMessage = 'Error creating token'; if (error instanceof Error) { errorMessage = error.message; } res.status(500).json({ status: 'error', data: errorMessage }); } }; // END createToken and the generated token, I used it in the header of a fetch() call to the api like this // begin HEADER { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + $vars.jwtToken }, // end HEADER But it responds with { "message": "Invalid credentials", "data": {} } Why is it saying "invalid credentials"? How can I rectify this?
kapa.ai
kapa.ai6d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I can see you're having an issue with your JWT token authentication in your Wasp application. The "Invalid credentials" error suggests there's a problem with how the token is being validated on the server side. Possible Causes and Solutions 1. JWT Secret Mismatch: The most common cause of this issue is that the secret used to sign the token is different from the one used to verify it.
const secret = process.env.JWT_SECRET || 'zigozi_default_secret';

const secret = process.env.JWT_SECRET || 'zigozi_default_secret';

Make sure your JWT_SECRET environment variable is properly set and consistent across your application. Wasp reads this from the environment, and if it's not set or is different between token creation and verification, you'll get this error. 2. Token Verification Process: In Wasp, when you set auth: true on an API endpoint, it expects the token to be in a specific format that matches its internal authentication system. Since Wasp has moved from JWT tokens to sessions for its built-in authentication, your custom JWT might not be compatible with Wasp's auth middleware. From the Discord support thread, we can see that custom JWT implementations need to be handled carefully. 3. API Port Issue: Make sure you're calling the correct port for your API. As mentioned in the Discord support thread, Wasp runs the server on port 3001, not 3000:
curl -v -X POST <http://localhost:3001/api/generate-jwt>

curl -v -X POST <http://localhost:3001/api/generate-jwt>

Recommended Fixes 1. Check your JWT_SECRET environment variable: Make sure it's properly set in your .env.server file and that you're not relying on the default fallback value. 2. Implement a custom token verification middleware: Instead of relying on Wasp's built-in auth middleware, you might need to create your own API endpoint that doesn't use auth: true but instead manually verifies the JWT token:
// In your API implementation
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return res.status(401).json({ message: "No token provided", data: {} });
}

try {
const decoded = jwt.verify(token, process.env.JWT_SECRET || 'zigozi_default_secret');
// Continue with your API logic using the decoded user info
} catch (err) {
return res.status(401).json({ message: "Invalid credentials", data: {} });
}

// In your API implementation
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return res.status(401).json({ message: "No token provided", data: {} });
}

try {
const decoded = jwt.verify(token, process.env.JWT_SECRET || 'zigozi_default_secret');
// Continue with your API logic using the decoded user info
} catch (err) {
return res.status(401).json({ message: "Invalid credentials", data: {} });
}

3. Check token format: Make sure your token is being sent correctly in the Authorization header. The format should be exactly:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

(with no extra spaces or characters) 4. Debug the token verification: Add some logging to see what's happening during token verification:
console.log('Token received:', token);
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET || 'zigozi_default_secret');
console.log('Decoded token:', decoded);
} catch (err) {
console.error('Token verification error:', err);
return res.status(401).json({ message: "Invalid credentials", data: {} });
}

console.log('Token received:', token);
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET || 'zigozi_default_secret');
console.log('Decoded token:', decoded);
} catch (err) {
console.error('Token verification error:', err);
return res.status(401).json({ message: "Invalid credentials", data: {} });
}

These steps should help you identify and fix the issue with your JWT token authentication. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Kynetix, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
Kynetix
KynetixOP6d ago
@kapa.ai Since wasp has moved from JWT to sessions, how can I implement this session for external API calling? How can I convert this JWT approach I was implementing to a session based approach? Or do you have a better suggestion?
kapa.ai
kapa.ai6d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I understand you're looking to adapt your authentication approach for external API calls given Wasp's move from JWT to sessions. Let me explain how you can work with Wasp's current session-based authentication system. Understanding Wasp's Current Auth System Wasp now uses sessions for authentication instead of JWTs:
Wasp's auth uses sessions to keep track of the logged-in user. The session is stored in localStorage on the client and in the database on the server. Under the hood, Wasp uses the excellent Lucia Auth v3 library for session management.
Auth Overview - Sessions Options for External API Authentication You have a few options for handling authentication from external applications: Option 1: Continue Using Custom JWT (Recommended) Even though Wasp internally uses sessions, you can still implement your custom JWT solution for external API access. This is actually a common pattern - using sessions for your web app and JWT for API access. Your current JWT implementation is a good approach for external API authentication. The issue you're facing is likely related to how the token is being validated rather than the approach itself. Option 2: Create a Session-Based API Key System If you want to align with Wasp's session approach: 1. Create an API endpoint that generates a long-lived API key for external applications 2. Store this key in your database associated with the user 3. Have external applications send this key in headers 4. Validate the key on your protected endpoints Option 3: OAuth-style Flow Implement an OAuth-style flow where: 1. External app redirects to your Wasp app for authentication 2. After login, redirect back with a temporary code 3. Exchange this code for an access token via a secure backend channel Implementation Recommendation Based on the knowledge sources and your needs, I recommend sticking with your JWT approach but fixing the validation issues: 1. Create a separate middleware for JWT validation that doesn't rely on Wasp's built-in auth:
// src/server/middleware/jwtAuth.js
import jwt from 'jsonwebtoken';

export const jwtAuth = (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];

if (!token) {
return res.status(401).json({ message: "No token provided", data: {} });
}

try {
const secret = process.env.JWT_SECRET || 'your_default_secret';
const decoded = jwt.verify(token, secret);
req.user = decoded; // Attach the decoded user to the request
next();
} catch (err) {
console.error('Token verification error:', err);
return res.status(401).json({ message: "Invalid credentials", data: {} });
}
};
// src/server/middleware/jwtAuth.js
import jwt from 'jsonwebtoken';

export const jwtAuth = (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];

if (!token) {
return res.status(401).json({ message: "No token provided", data: {} });
}

try {
const secret = process.env.JWT_SECRET || 'your_default_secret';
const decoded = jwt.verify(token, secret);
req.user = decoded; // Attach the decoded user to the request
next();
} catch (err) {
console.error('Token verification error:', err);
return res.status(401).json({ message: "Invalid credentials", data: {} });
}
};
2. Use this middleware in your API endpoints:
// src/apis.js
import { jwtAuth } from './server/middleware/jwtAuth';

export const yourProtectedApi = async (req, res, context) => {
// Apply JWT auth middleware
jwtAuth(req, res, () => {
// This will only execute if JWT validation passes
// Access the user via req.user
const userId = req.user.id;

// Your API logic here
res.json({ status: 'success', data: 'Protected data' });
});
};
// src/apis.js
import { jwtAuth } from './server/middleware/jwtAuth';

export const yourProtectedApi = async (req, res, context) => {
// Apply JWT auth middleware
jwtAuth(req, res, () => {
// This will only execute if JWT validation passes
// Access the user via req.user
const userId = req.user.id;

// Your API logic here
res.json({ status: 'success', data: 'Protected data' });
});
};
3. In your main.wasp file, set auth: false for these endpoints since you're handling auth manually:
api yourProtectedApi {
fn: import { yourProtectedApi } from "@src/apis",
httpRoute: (GET, "/api/protected-data"),
auth: false // We're handling auth manually
}
api yourProtectedApi {
fn: import { yourProtectedApi } from "@src/apis",
httpRoute: (GET, "/api/protected-data"),
auth: false // We're handling auth manually
}
This approach gives you full control over the authentication process for external applications while still allowing Wasp to use its session-based auth for the web application. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Kynetix, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
toticozeni
toticozeni5d ago
So you're sending information from wasp application to external API. Are you sure that the token you need to send is not defined in that external services settings somewhere? If so, you could include it in your project via environment variables and just include it in fetch header.
Kynetix
KynetixOP5d ago
@franjo the chatbot embedded in Wasp is kinda sandboxed - it can't access the applications variables & stuff, (except via some vars defined within). So it's as good as sending the data from a different application. Basically, I generate the token in Wasp and pass it to the chatbot, then when the chatbot calls the Wasp API, it passes the token (Authorization: Bearer XXXXXX) in the header.
toticozeni
toticozeni4d ago
In this situation, I would recommend setting up a dedicated access token specifically for the chatbot. You can pre-generate a random token and inject it into your Wasp application via environment variables. Then, you would expose a custom API route with auth: false, since we’ll handle authentication manually inside the route handler. The idea is to check whether the bearer token from the incoming request matches the token stored in your environment variables. Here’s a quick, minimal working example: .env
CHATBOT_ACCESS_TOKEN=your-secret-random-token
CHATBOT_ACCESS_TOKEN=your-secret-random-token
main.wasp
api chatbot {
fn: import { chatbot } from "@src/apis/chatbot",
httpRoute: (POST, "/chatbot"),
auth: false
}
api chatbot {
fn: import { chatbot } from "@src/apis/chatbot",
httpRoute: (POST, "/chatbot"),
auth: false
}
src/apis/chatbots.ts
import { HttpError } from 'wasp/server'
import { Chatbot } from 'wasp/server/api'

export const chatbot: Chatbot = async (req, res) => {
const authHeader = req.headers['authorization']

if (!authHeader || !authHeader.startsWith('Bearer ')) {
throw new HttpError(401, 'Missing or malformed Authorization header.')
}

const accessToken = authHeader.slice(7)

if (accessToken !== process.env.CHATBOT_ACCESS_TOKEN) {
throw new HttpError(403, 'Invalid access token.')
}

res.json({ ok: true, message: 'Chatbot handshake successful.' })
}
import { HttpError } from 'wasp/server'
import { Chatbot } from 'wasp/server/api'

export const chatbot: Chatbot = async (req, res) => {
const authHeader = req.headers['authorization']

if (!authHeader || !authHeader.startsWith('Bearer ')) {
throw new HttpError(401, 'Missing or malformed Authorization header.')
}

const accessToken = authHeader.slice(7)

if (accessToken !== process.env.CHATBOT_ACCESS_TOKEN) {
throw new HttpError(403, 'Invalid access token.')
}

res.json({ ok: true, message: 'Chatbot handshake successful.' })
}
This is a minimal example that uses a basic string comparison for the token check. Not really production grade quality, but it should help you get started. Of course instead of returning Chatbot handshake successful you would actually do what you want in here. Hope it helps. 😁
Kynetix
KynetixOP2d ago
Thanks, that works great man!
toticozeni
toticozeni2d ago
Great. Glad we got it.

Did you find this page helpful?