Created
August 20, 2021 15:13
-
-
Save harrisjose/87dadc299df615b4e1fc2aca8ee6de96 to your computer and use it in GitHub Desktop.
Telegram bot using Next.js API Routes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Cors from 'micro-cors' | |
import got from 'got' | |
import { format } from 'date-fns' | |
import { isEmpty, makeYaml } from 'utils' | |
const getContent = (message) => { | |
let { entities, text } = message | |
// Get url for the note | |
let urlEntity = entities.find((e) => e.type === 'url') | |
if (isEmpty(urlEntity)) { | |
throw new Error('No URL found in message') | |
} | |
// Get excerpt for the note | |
let { offset, length } = urlEntity | |
let url = text.slice(offset, offset + length) | |
let excerpt = text | |
.split(url) | |
.find((m) => !isEmpty(m)) | |
.trim() | |
if (isEmpty(excerpt)) { | |
throw new Error('No excerpt found in message') | |
} else { | |
return { url, excerpt } | |
} | |
} | |
const createPost = async (content) => { | |
const createdAt = Date.now() | |
const frontmatter = makeYaml({ | |
createdAt, | |
link: content.url, | |
syndicated: false, | |
layout: 'note', | |
}) | |
const text = content.excerpt | |
const fileContent = `${frontmatter}\n\n${text}\n` | |
const fileName = format(createdAt, 'yyyy-MM-dd-Hmm') + '.md' | |
const url = '...' | |
const payload = { | |
message: 'New note via NotesBot', | |
content: Buffer.from(fileContent).toString('base64'), | |
committer: { | |
name: '...', | |
email: '...', | |
}, | |
} | |
const options = { | |
method: 'PUT', | |
headers: { | |
'Content-Type': 'application/vnd.github.v3+json', | |
Authorization: `token ${process.env.GITHUB_TOKEN}`, | |
}, | |
body: JSON.stringify(payload), | |
} | |
let response = null | |
try { | |
response = await got(url, options) | |
} catch (err) { | |
console.log(err) | |
throw new Error(err.message) | |
} | |
console.log(`Created File: ${fileName}`) | |
} | |
const createReply = (res, chatId, messageId) => (message) => | |
res.status(200).json({ | |
method: 'sendMessage', | |
chat_id: chatId, | |
text: message, | |
reply_to_message_id: messageId || null, | |
disable_notification: true, | |
}) | |
const handler = async (req, res) => { | |
const { | |
query: { token }, | |
body: update, | |
} = req | |
if (token !== process.env.LOCAL_TOKEN || isEmpty(update)) { | |
console.log(token) | |
res.status(500).end('Invalid Auth') | |
} else { | |
const { message } = update || {} | |
const { | |
from: { id: userId } = {}, | |
message_id: messageId, | |
chat: { id: chatId } = {}, | |
} = message || {} | |
const reply = createReply(res, chatId, messageId) | |
if (String(userId) === process.env.USER_ID) { | |
let content = {} | |
try { | |
content = getContent(message) | |
} catch (err) { | |
reply(err.message) | |
return | |
} | |
try { | |
await createPost(content) | |
} catch (err) { | |
reply(`Error occurred while publishing:\n\n${err.message}`) | |
return | |
} | |
reply(`Published!`) | |
} else { | |
reply( | |
'This is a private bot 😅' | |
) | |
} | |
} | |
} | |
const cors = Cors({ | |
allowMethods: ['POST', 'HEAD'], | |
}) | |
export default cors(handler) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment