mirror of
https://github.com/Sysbot-org/tgscraper.git
synced 2025-01-08 09:55:50 +01:00
Added 'version' field (might not work on older versions), improved Postman schema, initial OpenAPI implementation
This commit is contained in:
parent
3eef215858
commit
137960dea2
@ -33,13 +33,33 @@ class SchemaExtractor
|
||||
'answerPreCheckoutQuery'
|
||||
];
|
||||
|
||||
private Dom $dom;
|
||||
|
||||
private string $version;
|
||||
|
||||
/**
|
||||
* SchemaExtractor constructor.
|
||||
* @param LoggerInterface $logger
|
||||
* @param string $url
|
||||
* @throws ChildNotFoundException
|
||||
* @throws CircularException
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws ContentLengthException
|
||||
* @throws LogicalException
|
||||
* @throws StrictException
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function __construct(private LoggerInterface $logger, private string $url = Versions::LATEST)
|
||||
{
|
||||
$this->dom = new Dom();
|
||||
try {
|
||||
$this->dom->loadFromURL($this->url);
|
||||
} catch (Throwable $e) {
|
||||
$this->logger->critical(sprintf('Unable to load data from URL "%s": %s', $this->url, $e->getMessage()));
|
||||
throw $e;
|
||||
}
|
||||
$this->version = $this->parseVersion();
|
||||
$this->logger->info('Bot API version: ' . $this->version);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,6 +96,28 @@ class SchemaExtractor
|
||||
return ['description' => $description, 'table' => $table, 'extended_by' => $extendedBy];
|
||||
}
|
||||
|
||||
private function parseVersion(): string
|
||||
{
|
||||
/** @var Dom\Node\AbstractNode $element */
|
||||
$element = $this->dom->find('h3')[0];
|
||||
$tag = '';
|
||||
while ($tag != 'p') {
|
||||
try {
|
||||
$element = $element->nextSibling();
|
||||
} catch (ChildNotFoundException | ParentNotFoundException) {
|
||||
continue;
|
||||
}
|
||||
$tag = $element->tag->name();
|
||||
}
|
||||
$versionNumbers = explode('.', str_replace('Bot API ', '', $element->innerText));
|
||||
return sprintf(
|
||||
'%s.%s.%s',
|
||||
$versionNumbers[0] ?? '1',
|
||||
$versionNumbers[1] ?? '0',
|
||||
$versionNumbers[2] ?? '0'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws ChildNotFoundException
|
||||
@ -88,28 +130,24 @@ class SchemaExtractor
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws Throwable
|
||||
*/
|
||||
#[ArrayShape(['version' => "string", 'methods' => "array", 'types' => "array"])]
|
||||
public function extract(): array
|
||||
{
|
||||
$dom = new Dom;
|
||||
try {
|
||||
$dom->loadFromURL($this->url);
|
||||
$elements = $this->dom->find('h4');
|
||||
} catch (Throwable $e) {
|
||||
$this->logger->critical(sprintf('Unable to load data from URL "%s": %s', $this->url, $e->getMessage()));
|
||||
throw $e;
|
||||
}
|
||||
try {
|
||||
$elements = $dom->find('h4');
|
||||
} catch (Throwable $e) {
|
||||
$this->logger->critical(sprintf('Unable to load data from URL "%s": %s', $this->url, $e->getMessage()));
|
||||
throw $e;
|
||||
}
|
||||
$data = [];
|
||||
$data = ['version' => $this->version];
|
||||
/* @var Dom\Node\AbstractNode $element */
|
||||
foreach ($elements as $element) {
|
||||
if (!str_contains($name = $element->text, ' ')) {
|
||||
$isMethod = lcfirst($name) == $name;
|
||||
$path = $isMethod ? 'methods' : 'types';
|
||||
['description' => $description, 'table' => $table, 'extended_by' => $extendedBy] = self::parseNode($element);
|
||||
['description' => $description, 'table' => $table, 'extended_by' => $extendedBy] = self::parseNode(
|
||||
$element
|
||||
);
|
||||
$data[$path][] = self::generateElement(
|
||||
$name,
|
||||
trim($description),
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace TgScraper;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
@ -27,6 +28,11 @@ use Throwable;
|
||||
class Generator
|
||||
{
|
||||
|
||||
/**
|
||||
* Path to templates directory.
|
||||
*/
|
||||
public const TEMPLATES_DIRECTORY = __DIR__ . '/../templates';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
@ -53,8 +59,8 @@ class Generator
|
||||
?array $schema = null
|
||||
) {
|
||||
if (empty($schema)) {
|
||||
$extractor = new SchemaExtractor($this->logger, $this->url);
|
||||
try {
|
||||
$extractor = new SchemaExtractor($this->logger, $this->url);
|
||||
$this->logger->info('Schema not provided, extracting from URL.');
|
||||
$schema = $extractor->extract();
|
||||
} catch (Throwable $e) {
|
||||
@ -179,6 +185,14 @@ class Generator
|
||||
return Yaml::dump($this->schema, $inline, $indent, $flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toOpenApi(): string
|
||||
{
|
||||
throw new BadMethodCallException('Not implemented');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Thanks to davtur19 (https://github.com/davtur19/TuriBotGen/blob/master/postman.php)
|
||||
@ -189,24 +203,16 @@ class Generator
|
||||
public function toPostman(
|
||||
int $options = 0
|
||||
): string {
|
||||
$result = [
|
||||
'info' => [
|
||||
'name' => 'Telegram Bot API',
|
||||
'schema' => 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json'
|
||||
],
|
||||
'variable' => [
|
||||
'key' => 'token',
|
||||
'value' => '1234:AAbbcc',
|
||||
'type' => 'string'
|
||||
]
|
||||
];
|
||||
$template = file_get_contents(self::TEMPLATES_DIRECTORY . '/postman.json');
|
||||
$result = json_decode($template, true);
|
||||
$result['info']['version'] = $this->schema['version'];
|
||||
foreach ($this->schema['methods'] as $method) {
|
||||
$formData = [];
|
||||
if (!empty($method['fields'])) {
|
||||
foreach ($method['fields'] as $field) {
|
||||
$formData[] = [
|
||||
'key' => $field['name'],
|
||||
'value' => '',
|
||||
'disabled' => !$field['required'],
|
||||
'description' => sprintf(
|
||||
'%s. %s',
|
||||
$field['required'] ? 'Required' : 'Optional',
|
||||
|
144
templates/openapi.json
Normal file
144
templates/openapi.json
Normal file
@ -0,0 +1,144 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Telegram Bot API",
|
||||
"description": "Auto-generated OpenAPI schema by TGScraper.",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"url": "https://api.telegram.org/bot{token}",
|
||||
"variables": {
|
||||
"token": {
|
||||
"default": "1234:AAbbcc",
|
||||
"description": "Bot's unique authentication token, given by @BotFather."
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"externalDocs": {
|
||||
"description": "Official Telegram Bot API documentation",
|
||||
"url": "https://core.telegram.org/bots/api"
|
||||
},
|
||||
"components": {
|
||||
"responses": {
|
||||
"BadRequest": {
|
||||
"description": "Bad request, you have provided malformed data.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Unauthorized": {
|
||||
"description": "The authorization token is invalid or it has been revoked.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Forbidden": {
|
||||
"description": "This action is forbidden.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"NotFound": {
|
||||
"description": "The specified resource was not found.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Conflict": {
|
||||
"description": "There is a conflict with another instance using webhook or polling.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"TooManyRequests": {
|
||||
"description": "You're doing too many requests, retry after a while.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"schemas": {
|
||||
"Response": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ok"
|
||||
],
|
||||
"properties": {
|
||||
"ok": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Success": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"result"
|
||||
],
|
||||
"properties": {
|
||||
"result": {
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Error": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"error_code",
|
||||
"description"
|
||||
],
|
||||
"properties": {
|
||||
"error_code": {
|
||||
"type": "integer"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"parameters": {
|
||||
"$ref": "#/components/schemas/ResponseParameters"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"paths": {}
|
||||
}
|
15
templates/postman.json
Normal file
15
templates/postman.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"info": {
|
||||
"name": "Telegram Bot API",
|
||||
"description": "Auto-generated Postman collection by TGScraper.",
|
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"variable": {
|
||||
"key": "token",
|
||||
"description": "Bot's unique authentication token, given by @BotFather.",
|
||||
"type": "string",
|
||||
"value": "1234:AAbbcc"
|
||||
},
|
||||
"item": []
|
||||
}
|
Loading…
Reference in New Issue
Block a user