Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ I also tried to make it as **generic** and **reusable** as possible to cover mos
- Support for a range of foundational and embedding models (DeepSeek, Llama, Mistral, Sentence Transformers, etc.) via LangChain, Together.AI, and Hugging Face
- **API Examples**
- **Backoffice:** Lob (USPS Mail), Paypal, Quickbooks, Stripe, Twilio (text messaging)
- **Data, Media & Entertainment:** Alpha Vantage (stocks and finance info) with ChartJS, Github, Foursquare, Last.fm, New York Times, PubChem (chemical information), Trakt.tv (movies/TV), Twitch, Tumblr (OAuth 1.0a example), Web Scraping
- **Data, Media & Entertainment:** Alpha Vantage (stocks and finance info) with ChartJS, Github, Foursquare, Last.fm, New York Times, PubChem (chemical information), Trakt.tv (movies/TV), Twitch, Tumblr (OAuth 1.0a example), Web Scraping, Wikipedia
- **Maps and Location:** Google Maps, HERE Maps
- **Productivity:** Google Drive, Google Sheets

Expand Down Expand Up @@ -459,6 +459,19 @@ The OpenAI moderation API for checking harmful inputs is free to use as long as

<hr>

<img src="https://upload.wikimedia.org/wikipedia/commons/8/80/Wikipedia-logo-v2.svg" height="75">

**Wikipedia API** uses the public REST API which doesn't require any API keys or authentication. The Wikipedia API provides access to Wikipedia content and metadata.

- **No setup required** - The Wikipedia REST API is completely free and open
- **API Documentation**: Visit <a href="https://en.wikipedia.org/api/rest_v1/" target="_blank">Wikipedia REST API</a> for full documentation
- **Rate Limits**: Please be respectful of Wikipedia's servers and don't make excessive requests
- **Example endpoints used**:
- Search: `https://en.wikipedia.org/api/rest_v1/page/search/{query}`
- Page summary: `https://en.wikipedia.org/api/rest_v1/page/summary/{title}`

<hr>

## Web Analytics

This project supports integrating web analytics tools such as Google Analytics 4 and Facebook Pixel, along with Open Graph metadata for social sharing. Below are instructions to help you set up these features in your application.
Expand Down
1 change: 1 addition & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ app.get('/api/chart', apiController.getChart);
app.get('/api/google/sheets', passportConfig.isAuthenticated, passportConfig.isAuthorized, apiController.getGoogleSheets);
app.get('/api/quickbooks', passportConfig.isAuthenticated, passportConfig.isAuthorized, apiController.getQuickbooks);
app.get('/api/trakt', apiController.getTrakt);
app.get('/api/wikipedia', apiController.getWikipedia);
app.get('/api/pubchem', apiController.getPubChem);

/**
Expand Down
13 changes: 10 additions & 3 deletions controllers/ai.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,14 @@ const { ChatTogetherAI } = require('@langchain/community/chat_models/togetherai'
const { HumanMessage } = require('@langchain/core/messages');
const { CacheBackedEmbeddings } = require('langchain/embeddings/cache_backed');
const { MongoClient } = require('mongodb');
// eslint-disable-next-line import/extensions
const pdfjsLib = require('pdfjs-dist/legacy/build/pdf.mjs');
// Using dynamic import for pdfjs-dist due to ESM compatibility
let pdfjsLib;
const getPdfjsLib = async () => {
if (!pdfjsLib) {
pdfjsLib = await import('pdfjs-dist/legacy/build/pdf.mjs');
}
return pdfjsLib;
};

/**
* GET /ai
Expand Down Expand Up @@ -243,8 +249,9 @@ exports.postRagIngest = async (req, res) => {

// Process the PDF file
try {
const pdfjs = await getPdfjsLib();
const loader = new PDFLoader(filePath, {
pdfjs: () => Promise.resolve(pdfjsLib),
pdfjs: () => Promise.resolve(pdfjs),
});
const docs = await loader.load();
// Split the document into chunks
Expand Down
54 changes: 49 additions & 5 deletions controllers/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ const cheerio = require('cheerio');
const { LastFmNode } = require('lastfm');
const multer = require('multer');
const { OAuth } = require('oauth');
// Disable eslint rule for @octakit/rest until the following github issue is resolved
// github npm package bug: https://github.com/octokit/rest.js/issues/446
// eslint-disable-next-line import/no-unresolved
const { Octokit } = require('@octokit/rest');
const stripe = require('stripe')(process.env.STRIPE_SKEY);
// Using dynamic import for @octokit/rest due to ESM compatibility
let OctokitClass;
const getOctokit = async () => {
if (!OctokitClass) {
const { Octokit } = await import('@octokit/rest');
OctokitClass = Octokit;
}
return OctokitClass;
};
const stripe = process.env.STRIPE_SKEY ? require('stripe')(process.env.STRIPE_SKEY) : null;
const twilioClient = require('twilio')(process.env.TWILIO_SID, process.env.TWILIO_TOKEN);
const googledrive = require('@googleapis/drive');
const googlesheets = require('@googleapis/sheets');
Expand Down Expand Up @@ -168,6 +173,7 @@ exports.getGithub = async (req, res, next) => {
let userInfo;
let userRepos;
let userEvents;
const Octokit = await getOctokit();
if (githubToken) {
github = new Octokit({
auth: req.user.tokens.find((token) => token.kind === 'github').accessToken,
Expand Down Expand Up @@ -481,6 +487,10 @@ exports.getStripe = (req, res) => {
* Make a payment.
*/
exports.postStripe = (req, res) => {
if (!stripe) {
req.flash('errors', { msg: 'Stripe API key not configured.' });
return res.redirect('/api/stripe');
}
const { stripeToken, stripeEmail } = req.body;
stripe.charges.create(
{
Expand Down Expand Up @@ -1444,6 +1454,40 @@ exports.getTrakt = async (req, res, next) => {
}
};

/**
* GET /api/wikipedia
* Wikipedia API example.
*/
exports.getWikipedia = async (req, res, next) => {
const searchTerm = req.query.search || 'Node.js';

try {
// Search for articles
const searchResponse = await fetch(`https://en.wikipedia.org/api/rest_v1/page/search/${encodeURIComponent(searchTerm)}?limit=5`);
if (!searchResponse.ok) throw new Error('Wikipedia search failed');
const searchResults = await searchResponse.json();

// Get summary for the first result if available
let summary = null;
if (searchResults.pages && searchResults.pages.length > 0) {
const firstResult = searchResults.pages[0];
const summaryResponse = await fetch(`https://en.wikipedia.org/api/rest_v1/page/summary/${encodeURIComponent(firstResult.key)}`);
if (summaryResponse.ok) {
summary = await summaryResponse.json();
}
}

res.render('api/wikipedia', {
title: 'Wikipedia API',
searchTerm,
searchResults: searchResults.pages || [],
summary
});
} catch (error) {
next(error);
}
};

/**
* GET /api/pubchem
* PubChem API example - Chemical information for Aspirin.
Expand Down
Loading