Skip to content

Instantly share code, notes, and snippets.

@mainarthur
Created June 16, 2021 11:39
Show Gist options
  • Save mainarthur/560b82655d4e78181bdf5104232ed666 to your computer and use it in GitHub Desktop.
Save mainarthur/560b82655d4e78181bdf5104232ed666 to your computer and use it in GitHub Desktop.
const { default: axios } = require('axios')
const { snakeCase, camelCase, stringifyQuery } = require('../util/requests')
const NodeElement = require('./NodeElement')
/**
* @typedef Post
* @property {String} path
* @property {String} url
* @property {String} title
* @property {String} description
* @property {String} authorName
* @property {String} authorUrl
* @property {String} imageUrl
* @property {Array<import('./NodeElement').Node>} content
*/
class Telegraph {
baseApiUrl = 'https://api.telegra.ph'
/**
*
* @param {Object} params
* @param {String} [params.token] token or shortName is required
* @param {String} [params.shortName] 1-32 characters
* @param {String} [params.authorName] 0-128 characters
* @param {String} [params.authorUrl] 0-512 characters
*/
constructor({ token, shortName, authorName, authorUrl }) {
if (typeof token !== 'string' && token)
throw new Error('"token" is not a string')
if (typeof shortName !== 'string' && shortName)
throw new Error('"shortName" is not a string')
if (!token && !shortName)
throw new Error('"token" or "shortName" is required')
if (typeof authorName !== 'string' && authorName)
throw new Error('"authorName" is not a string')
if (typeof authorUrl !== 'string' && authorUrl)
throw new Error('"authorUrl" is not a string')
if (shortName) this.shortName = shortName
if (token) this.accessToken = token
if (authorName) this.authorName = authorName
if (authorUrl) this.authorUrl = authorUrl
this.axios = axios.create()
this.axios.interceptors.response.use(
(value) => {
const { ok, result, description } = value.data
if (ok) return camelCase(result)
throw new Error(description)
},
(error) => {
const response = error?.response
if (response) {
const { ok, description } = response?.data ?? { ok: true }
if (!ok) throw new Error(description)
}
},
)
this.axios.interceptors.request.use((value) => {
const { formData, queryOptions } = value.data
value.data = formData
value.url += `?${stringifyQuery(snakeCase(queryOptions))}`
return value
})
}
/**
*
* @param {String} method method name
* @returns {String}
*/
_buildUrl(method) {
return `${this.baseApiUrl}/${method}`
}
/**
* @private
* @param {String} method Telegram Bot Api method name
* @param {Object} [options] Request Options
* @param {Object} [options.formData] Request FormData
* @param {Object} [options.queryOptions] Request query options
*
* @returns {Promise<Object>}
*/
_request(method, options = {}) {
const url = this._buildUrl(method)
return this.axios.post(url, options, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
}
/**
* @returns {Promise<boolean>}
*/
async create() {
if (this.accessToken) return true
const { shortName, authorName, authorUrl } = this
const { accessToken } = await this._request('createAccount', {
queryOptions: { shortName, authorName, authorUrl },
})
this.accessToken = accessToken
return true
}
/**
*
* @param {String} text
* @param {String} title
*
* @returns {Promise<Post>}
*/
async createPost(text, title) {
const content = text
.split('\n')
.map((line) => new NodeElement('p', { children: [line] }))
const { authorName, authorUrl, accessToken } = this
return this._request('createPost', {
queryOptions: { title, accessToken, content, authorName, authorUrl },
})
}
}
module.exports = Telegraph
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment