Build a sidebar AI assistant for Sheets
Add a chat helper inside Northwind's spreadsheet — ask Claude about the current selection.
Published Sep 21, 2025
Northwind’s analysts spend a lot of time staring at ranges of numbers and asking the same kinds of questions — what stands out, which row is the outlier, what would a quick summary say. Answering those questions usually means copying cells into a separate AI chat, losing the link back to the data.
This automation keeps the conversation inside the spreadsheet. A sidebar holds a question box; whatever range is selected is sent to Claude along with the question, and the answer appears in the panel. The analyst never leaves the Sheet, and the assistant always sees exactly the data they are looking at.
What you’ll need
- An HTML file named
Assistant.htmlin the Apps Script project for the sidebar UI. - An Anthropic API key saved as
ANTHROPIC_API_KEYin Script Properties — see Store API keys and secrets securely. - An
onOpentrigger or menu so editors can open the sidebar (added below).
The sidebar (Assistant.html)
<input id="q" placeholder="Ask about the selection">
<button onclick="ask()">Ask</button>
<div id="answer"></div>
<script>
// Send the question to the server function and show whatever it returns.
function ask() {
document.getElementById('answer').textContent = 'Thinking…';
google.script.run
.withSuccessHandler((a) => {
document.getElementById('answer').textContent = a;
})
.withFailureHandler((err) => {
document.getElementById('answer').textContent = 'Error: ' + err.message;
})
.answerAboutSelection(document.getElementById('q').value);
}
</script>
The script
// Claude model and response budget for the assistant.
const ASSISTANT_MODEL = 'claude-sonnet-4-6';
const MAX_TOKENS = 500;
// Cap on how many selected rows are sent, to keep the prompt sensible.
const MAX_ROWS = 50;
/**
* Opens the assistant sidebar inside the active spreadsheet.
*/
function showAssistant() {
const ui = HtmlService.createHtmlOutputFromFile('Assistant')
.setTitle('Ask Claude');
SpreadsheetApp.getUi().showSidebar(ui);
}
/**
* Adds an "AI assistant" menu so editors can open the sidebar.
*/
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('AI assistant')
.addItem('Open assistant', 'showAssistant')
.addToUi();
}
/**
* Sends the current selection plus a question to Claude and returns
* the answer. Called from the sidebar via google.script.run.
*/
function answerAboutSelection(question) {
// Guard against an empty question.
if (!question || !question.trim()) {
return 'Type a question first.';
}
// Read the active range, capped to a sensible number of rows.
const data = SpreadsheetApp.getActiveRange().getValues().slice(0, MAX_ROWS);
if (!data.length) {
return 'Select a range of cells, then ask again.';
}
// Give Claude the data and the question together.
const prompt = 'Northwind data:\n' + JSON.stringify(data) +
'\n\nQuestion: ' + question;
return callClaude(prompt);
}
/**
* Minimal Anthropic API call. The key lives in Script Properties — it
* is never pasted into the code.
*/
function callClaude(prompt) {
const key = PropertiesService.getScriptProperties()
.getProperty('ANTHROPIC_API_KEY');
const res = UrlFetchApp.fetch('https://api.anthropic.com/v1/messages', {
method: 'post',
contentType: 'application/json',
headers: { 'x-api-key': key, 'anthropic-version': '2023-06-01' },
payload: JSON.stringify({
model: ASSISTANT_MODEL,
max_tokens: MAX_TOKENS,
messages: [{ role: 'user', content: prompt }],
}),
muteHttpExceptions: true,
});
return JSON.parse(res.getContentText()).content[0].text.trim();
}
How it works
onOpenruns whenever the spreadsheet is opened and adds an “AI assistant” menu, so editors have a one-click way to launch the sidebar.showAssistantloadsAssistant.htmland shows it as a sidebar titled “Ask Claude”.- In the sidebar, clicking Ask calls
answerAboutSelectionthroughgoogle.script.run, passing the text from the question box. answerAboutSelectionchecks the question is not blank, reads the active range withgetActiveRange, and caps it atMAX_ROWSso a huge selection does not blow the prompt budget.- It builds a prompt that puts the selected data as JSON next to the question,
then hands it to
callClaude. callClaudereads the API key from Script Properties, posts the prompt to the Anthropic API, and returns the text of the reply.- The sidebar’s success handler drops that text into the answer div; the failure handler shows any error instead.
Example run
An analyst selects a range of monthly figures:
| Month | Revenue |
|---|---|
| Jan | 42,000 |
| Feb | 38,500 |
| Mar | 51,200 |
They type “Which month was the outlier and why?” and click Ask. The sidebar shows “Thinking…”, then a reply such as: “March stands out — at 51,200 it is roughly 25% above the Jan–Feb average of 40,250. February is the weakest month. If this is a quarter, the upward jump in March suggests a strong end to the period.”
Run it
This is an on-demand tool — open it when you need it:
- Reload the spreadsheet so the AI assistant menu appears (the
onOpentrigger creates it). - Choose AI assistant → Open assistant.
- Select a range, type a question, and click Ask.
The first run will prompt for authorisation, including permission to make external requests.
Watch out for
- The whole selection is sent to a third-party API. Do not point the assistant at ranges containing personal or confidential data unless that is acceptable under Northwind’s policy.
- The row cap (
MAX_ROWS) protects the prompt budget, but a wide selection with many columns can still be large. Trim the selection or lower the cap if responses get truncated. - The assistant only sees cell values, not formulas, formatting, or context from other tabs. Phrase questions so they make sense from the numbers alone.
- Each question is a fresh API call with no memory of previous ones — there is no conversation history. Include any needed context in the question itself.
callClaudeusesmuteHttpExceptions, so an API error returns a confusing reply rather than throwing. If answers look wrong, logres.getContentText()to see the raw response.
Related
Build a branded approval interface
Approve Northwind requests through a custom UI — clients click, decision is logged.
Updated Nov 8, 2025
Build an interactive quiz or assessment app
Run Northwind tests with scoring and feedback — questions in a Sheet, results in another.
Updated Nov 4, 2025
Build a multi-page web app with routing
Structure a real Northwind app across views — query-param routing, shared layout.
Updated Oct 31, 2025
Build a form-to-PDF web service
Convert Northwind form submissions to PDFs on the fly — POST in, PDF out.
Updated Oct 27, 2025
Build an expiring secure-download generator
Issue time-limited Northwind links via a web app — token in URL, server-side check.
Updated Oct 23, 2025