vercel-grammy
Version:
Utilities for grammY on Vercel
90 lines (89 loc) • 3.2 kB
JavaScript
import { webhookCallback } from 'grammy';
/**
* This method generates a hostname from the options passed to it
* @returns Target hostname
*/
export function getHost({ fallback = process.env.VERCEL_BRANCH_URL ||
process.env.VERCEL_URL ||
'localhost', headers = globalThis.Headers ? new Headers() : {}, header = 'x-forwarded-host', } = {}) {
var _a, _b;
return String((_b = (globalThis.Headers && headers instanceof Headers
? (_a = headers === null || headers === void 0 ? void 0 : headers.get) === null || _a === void 0 ? void 0 : _a.call(headers, header)
: headers[header])) !== null && _b !== void 0 ? _b : fallback);
}
/**
* This method generates a URL from the options passed to it
* @returns Target URL
*/
export function getURL({ host, path = '', ...other } = {}) {
return new URL(path, `https://${host !== null && host !== void 0 ? host : getHost(other)}`).href;
}
/**
* Callback factory for grammY `bot.api.setWebhook` method
* @returns Target callback method
*/
export function setWebhookCallback(bot, { allowedEnvs = ['development'], secretToken: secret_token, onError = 'throw', fallback, header, host, path, url, ...other } = {}) {
return async ({ headers } = {}, { json = jsonResponse } = {}) => {
try {
const env = process.env.VERCEL_ENV || 'development';
if (!allowedEnvs.includes(env))
return json({ ok: false });
const webhookURL = url ||
getURL({
headers,
fallback,
host,
path,
header,
});
const ok = await bot.api.setWebhook(webhookURL, {
secret_token,
...other,
});
return json({ ok });
}
catch (e) {
if (onError === 'throw')
throw e;
console.error(e);
return json(e);
}
};
}
/**
* Callback factory for streaming webhook response
* @returns Target callback method
*/
export function webhookStream(bot, { intervalMilliseconds = 1000, timeoutMilliseconds = 55000, chunk = ' ', ...other } = {}) {
const callback = webhookCallback(bot, 'std/http', {
timeoutMilliseconds,
...other,
});
return (req) => new Response(new ReadableStream({
start: controller => {
const encoder = new TextEncoder();
const streamInterval = setInterval(() => {
controller.enqueue(encoder.encode(chunk));
}, intervalMilliseconds);
return callback(req).finally(() => {
clearInterval(streamInterval);
controller.close();
});
},
}));
}
/**
* This method generates Response objects for JSON
* @returns Target JSON Response
*/
export function jsonResponse(value, { space, status, replacer, statusText, headers = {} } = {}) {
const body = JSON.stringify(value, replacer, space);
return new Response(body, {
headers: {
'Content-Type': 'application/json',
...headers,
},
statusText,
status,
});
}