mirror of
https://github.com/tdlight-team/tdlight-telegram-bot-api.git
synced 2024-11-23 04:26:51 +01:00
Merge remote-tracking branch 'upstream/master' into merge-upstream
This commit is contained in:
commit
f2e7e45fc0
@ -3,17 +3,20 @@ Language: Cpp
|
||||
# BasedOnStyle: Google
|
||||
AccessModifierOffset: -1
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveMacros: false
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveMacros: None
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignConsecutiveBitFields: None
|
||||
AlignConsecutiveDeclarations: None
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: true
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: None # All
|
||||
AllowShortIfStatementsOnASingleLine: Never # WithoutElse
|
||||
AllowShortLambdasOnASingleLine: Inline # All
|
||||
@ -24,10 +27,11 @@ AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BitFieldColonSpacing: Both
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
@ -37,12 +41,15 @@ BraceWrapping:
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeConceptDeclarations: true
|
||||
BreakBeforeInheritanceComma: true # false
|
||||
BreakInheritanceList: BeforeComma # BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
@ -60,21 +67,30 @@ Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: true
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- Q_FOREACH_THIS_LIST_MUST_BE_NON_EMPTY
|
||||
IncludeBlocks: Preserve
|
||||
#IndentCaseBlocks: false
|
||||
IncludeCategories:
|
||||
- Regex: '.*'
|
||||
Priority: 0
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseBlocks: false
|
||||
IndentCaseLabels: true
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentRequires: false
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
# InsertTrailingCommas: None
|
||||
# JavaScriptQuotes: Leave
|
||||
# JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
LambdaBodyIndentation: Signature
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
@ -91,15 +107,22 @@ PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Right
|
||||
PPIndentWidth: -1
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: false # true
|
||||
SortIncludes: false # disabled, because we need case insensitive sort
|
||||
ShortNamespaceLines: 0 # 1
|
||||
SortIncludes: CaseInsensitive # CaseSensitive
|
||||
# SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: false # true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
@ -109,10 +132,13 @@ SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 2
|
||||
SpacesInAngles: false
|
||||
SpacesInAngles: Never
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: 1 # -1
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Auto
|
||||
|
@ -6,7 +6,7 @@ if (POLICY CMP0065)
|
||||
cmake_policy(SET CMP0065 NEW)
|
||||
endif()
|
||||
|
||||
project(TelegramBotApi VERSION 5.5.1 LANGUAGES CXX)
|
||||
project(TelegramBotApi VERSION 5.7 LANGUAGES CXX)
|
||||
|
||||
if (POLICY CMP0069)
|
||||
option(TELEGRAM_BOT_API_ENABLE_LTO "Use \"ON\" to enable Link Time Optimization.")
|
||||
|
42
README.md
42
README.md
@ -72,7 +72,7 @@ The maximum number of messages to be deleted in a single batch is determined by
|
||||
###### Returns `true`
|
||||
|
||||
##### Command `ping`
|
||||
Send an MTProto ping message to the telegram servers.
|
||||
Send an MTProto ping message to the telegram servers.
|
||||
Useful to detect the delay of the bot api server.
|
||||
|
||||
###### Parameters
|
||||
@ -149,7 +149,7 @@ The bot will now receive Updates for all received media, even if a destruction t
|
||||
<a name="user-mode"></a>
|
||||
### User Mode
|
||||
|
||||
You can allow user accounts to access the bot api with the command-line option `--allow-users` or set the env variable
|
||||
You can allow user accounts to access the bot api with the command-line option `--allow-users` or set the env variable
|
||||
`TELEGRAM_ALLOW_USERS` to `1` when using docker. User Mode is disabled by default, so only bots can access the api.
|
||||
|
||||
You can now log into the bot api with user accounts to create userbots running on your account.
|
||||
@ -161,37 +161,37 @@ Note: Never send your 2fa password over a plain http connection. Make sure https
|
||||
|
||||
Parameters:
|
||||
- `phone_number`: `string`. The phone number of your Telegram Account.
|
||||
|
||||
|
||||
Returns your `user_token` as `string`. You can use this just like a normal bot token on the `/user` endpoint
|
||||
|
||||
|
||||
2. Send the received code to `{api_url}/user{user_token}/authcode`
|
||||
|
||||
Parameters:
|
||||
- `code`: `int`. The code send to you by Telegram In-App or by SMS
|
||||
|
||||
Will send `{"ok": true, "result": true}` on success.
|
||||
|
||||
|
||||
Will send `{"ok": true, "result": true}` on success.
|
||||
|
||||
3. Optional: Send your 2fa password to `{api_url}/user{user_token}/2fapassword`
|
||||
|
||||
|
||||
Parameters:
|
||||
- `password`: `string`. Password for 2fa authentication
|
||||
|
||||
Will send `{"ok": true, "result": true}` on success.
|
||||
|
||||
4. Optional: Register the user by calling `{api_url}/user{user_token}/registerUser`.
|
||||
|
||||
|
||||
Will send `{"ok": true, "result": true}` on success.
|
||||
|
||||
4. Optional: Register the user by calling `{api_url}/user{user_token}/registerUser`.
|
||||
|
||||
User registration is disabled by default. You can enable it with the `--allow-users-registration` command line
|
||||
option or the env variable `TELEGRAM_ALLOW_USERS_REGISTRATION` set to `1` when using docker.
|
||||
|
||||
|
||||
Parameters:
|
||||
- `first_name`: `string`. First name for the new account.
|
||||
- `last_name`: `string`, optional. Last name for the new account.
|
||||
|
||||
Will send `{"ok": true, "result": true}` on success.
|
||||
|
||||
You are now logged in and can use all methods like in the bot api, just replace the
|
||||
`/bot{bot_token}/` in your urls with `/user{token}/`.
|
||||
|
||||
|
||||
Will send `{"ok": true, "result": true}` on success.
|
||||
|
||||
You are now logged in and can use all methods like in the bot api, just replace the
|
||||
`/bot{bot_token}/` in your urls with `/user{token}/`.
|
||||
|
||||
You only need to authenticate once, the account will stay logged in. You can use the `logOut` method to log out
|
||||
or simply close the session in your account settings.
|
||||
|
||||
@ -226,7 +226,7 @@ It is possible to have multiple user-tokens to multiple client instances on the
|
||||
|
||||
The simplest way to use it is with this docker command:
|
||||
```bash
|
||||
docker run -p 8081:8081 --env TELEGRAM_API_ID=API_ID --env TELEGRAM_API_HASH=API_HASH tdlight/tdlightbotapi
|
||||
docker run -p 8081:8081 --env TELEGRAM_API_ID=API_ID --env TELEGRAM_API_HASH=API_HASH tdlight/tdlightbotapi
|
||||
```
|
||||
|
||||
The simplest way to build `Telegram Bot API server` is to use our [Telegram Bot API server build instructions generator](https://tdlight-team.github.io/tdlight-telegram-bot-api/build.html).
|
||||
|
235
build.html
235
build.html
@ -3,17 +3,184 @@
|
||||
|
||||
<head>
|
||||
<title>Telegram Bot API server build instructions</title>
|
||||
<style>
|
||||
.hide { display: none; }
|
||||
div.main { max-width:1200px; margin: auto; font-size: x-large; }
|
||||
select.large { font-size: large; }
|
||||
</style>
|
||||
<style>
|
||||
:root {
|
||||
--background: #fafafa;
|
||||
--color: black;
|
||||
--color-primary: #0088ff;
|
||||
--color-code-block: #ebf9ff;
|
||||
--color-select-border: rgb(211, 211, 211);
|
||||
--color-checkbox-background: rgb(211, 211, 211);
|
||||
--color-checkbox-tick: #ffffff;
|
||||
--color-copy-success-background: #c1ffc6;
|
||||
--color-copy-success-border: rgb(0, 255, 0);
|
||||
--color-copy-fail-background: #ffcbcb;
|
||||
--color-copy-fail-border: rgb(255, 0, 0);
|
||||
|
||||
color: var(--color);
|
||||
background: var(--background);
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background: #0e0e0e;
|
||||
--color: rgb(190, 190, 190);
|
||||
--color-primary: #0088ff;
|
||||
--color-code-block: #101315;
|
||||
--color-select-border: rgb(54, 54, 54);
|
||||
--color-checkbox-background: rgb(51, 51, 51);
|
||||
--color-checkbox-tick: #ffffff;
|
||||
--color-copy-success-background: #001f00;
|
||||
--color-copy-success-border: rgb(0, 255, 0);
|
||||
--color-copy-fail-background: #1f0000;
|
||||
--color-copy-fail-border: rgb(255, 0, 0);
|
||||
}
|
||||
}
|
||||
body {
|
||||
font-family: 'Segoe UI', Arial, Helvetica, sans-serif;
|
||||
}
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
div.main {
|
||||
max-width: 1250px;
|
||||
padding: 25px;
|
||||
margin: auto;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
.main > div {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#buildCommands {
|
||||
font-family: Consolas, monospace;
|
||||
margin-left: 40px;
|
||||
background: var(--color-code-block);
|
||||
padding: 5px;
|
||||
margin-bottom: 0;
|
||||
display: block;
|
||||
}
|
||||
#buildCommands ul {
|
||||
list-style: '$ ';
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-primary);
|
||||
text-decoration-color: transparent;
|
||||
transition: text-decoration-color 200ms;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
select, button {
|
||||
border: 1px solid var(--color-select-border);
|
||||
background-color: var(--background);
|
||||
color: var(--color);
|
||||
padding: 5px;
|
||||
margin-top: 5px;
|
||||
transition: border 200ms, padding 200ms;
|
||||
border-radius: 999em;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select:focus, button:focus {
|
||||
outline: none;
|
||||
border-color: var(--color-primary);
|
||||
border-width: 2px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
label * {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
input[type=checkbox] {
|
||||
margin-right: 5px;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
background-color: var(--color-checkbox-background);
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
transition: background-color 200ms;
|
||||
}
|
||||
input[type=checkbox]::after {
|
||||
content: "";
|
||||
transition: border-color 200ms;
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
top: 2px;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
border: solid transparent;
|
||||
border-width: 0 3px 3px 0;
|
||||
-webkit-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
input[type=checkbox]:checked {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
input[type=checkbox]:checked::after {
|
||||
border-color: var(--color-checkbox-tick);
|
||||
}
|
||||
|
||||
input[type=radio] {
|
||||
margin-right: 5px;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
background-color: var(--color-checkbox-background);
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
border-radius: 100%;
|
||||
position: relative;
|
||||
transition: background-color 200ms;
|
||||
}
|
||||
input[type=radio]::after {
|
||||
content: "";
|
||||
transition: border-color 200ms;
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 10px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-radius: 100%;
|
||||
background-color: transparent;
|
||||
transition: width 200ms, height 200ms, left 200ms, top 200ms, background-color 100ms;
|
||||
}
|
||||
input[type=radio]:checked::after {
|
||||
background-color: var(--color-primary);
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#copyBuildCommandsButton {
|
||||
margin-left: 40px;
|
||||
}
|
||||
#copyBuildCommandsButton.success {
|
||||
background: var(--color-copy-success-background);
|
||||
border-color: var(--color-copy-success-border);
|
||||
}
|
||||
#copyBuildCommandsButton.fail {
|
||||
background: var(--color-copy-fail-background);
|
||||
border-color: var(--color-copy-fail-border);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body onload="onLoad(true)" onpopstate="onLoad(false)">
|
||||
|
||||
<div class="main">
|
||||
<div id="osSelectDiv" class="large" style="text-align:center;">
|
||||
<div id="osSelectDiv" class="large">
|
||||
<p>Choose an operating system, on which you want to use the Telegram Bot API server:</p>
|
||||
<select id="osSelect" onchange="onOsChanged(false)" autofocus class="large">
|
||||
<option>Choose an operating system:</option>
|
||||
@ -27,7 +194,7 @@ select.large { font-size: large; }
|
||||
<p></p>
|
||||
</div>
|
||||
|
||||
<div id="linuxSelectDiv" class="hide" style="text-align:center;">
|
||||
<div id="linuxSelectDiv" class="hide">
|
||||
<p>Choose a Linux distro, on which you want to use the Telegram Bot API server:</p>
|
||||
<select id="linuxSelect" onchange="onOsChanged(false)" class="large">
|
||||
<option>Choose a Linux distro:</option>
|
||||
@ -45,7 +212,7 @@ select.large { font-size: large; }
|
||||
<p></p>
|
||||
</div>
|
||||
|
||||
<div id="buildOptionsDiv" class="hide" style="text-align:center;">
|
||||
<div id="buildOptionsDiv" class="hide">
|
||||
<div id="buildDebugDiv" class="hide">
|
||||
<label><input type="checkbox" id="buildDebugCheckbox" onchange="onOptionsChanged()"/>Build the debug binary. Debug binaries are much larger and slower than the release one.</label>
|
||||
</div>
|
||||
@ -77,6 +244,13 @@ select.large { font-size: large; }
|
||||
<p></p>
|
||||
</div>
|
||||
|
||||
<div id="buildMacOsHostDiv" class="hide">
|
||||
<span>Choose host architecture:</span><br>
|
||||
<label><input type="radio" id="buildMacOsHostRadioAppleSilicon" name="buildMacOsHostRadio" onchange="onOptionsChanged()" checked/>Apple silicon</label>
|
||||
<label><input type="radio" id="buildMacOsHostRadioIntel" name="buildMacOsHostRadio" onchange="onOptionsChanged()"/>Intel</label>
|
||||
<p></p>
|
||||
</div>
|
||||
|
||||
<div id="buildBitnessDiv" class="hide">
|
||||
<span>Choose for which bitness you want to build the Telegram Bot API server:</span><br>
|
||||
<label><input type="radio" id="buildBitnessRadio64" name="buildBitnessRadio" onchange="onOptionsChanged()" checked/>64</label>
|
||||
@ -91,13 +265,16 @@ select.large { font-size: large; }
|
||||
<p></p>
|
||||
</div>
|
||||
|
||||
<div id="buildTextDiv" class="hide" style="text-align:center;">
|
||||
<div id="buildTextDiv" class="hide">
|
||||
<p id="buildText">Hidden text</p>
|
||||
</div>
|
||||
|
||||
<div id="buildCommandsDiv" class="hide" style="text-align:left;">
|
||||
<div id="buildCommandsDiv" class="hide">
|
||||
<p id="buildPre">Hidden text</p>
|
||||
<code id="buildCommands">Empty commands</code>
|
||||
<button id="copyBuildCommandsButton" onclick="copyBuildInstructions()">
|
||||
<span id="copyBuildCommandsText">Copy</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -193,6 +370,8 @@ function onOptionsChanged() {
|
||||
var use_powershell = false;
|
||||
var use_cmd = false;
|
||||
var use_csh = false;
|
||||
var homebrew_install_dir = '';
|
||||
var os_mac_host_name = '';
|
||||
if (os_windows) {
|
||||
document.getElementById('buildShellDiv').style.display = 'block';
|
||||
use_powershell = document.getElementById('buildShellRadioPowerShell').checked;
|
||||
@ -205,6 +384,18 @@ function onOptionsChanged() {
|
||||
} else {
|
||||
document.getElementById('buildShellBsdDiv').style.display = 'none';
|
||||
}
|
||||
if (os_mac) {
|
||||
document.getElementById('buildMacOsHostDiv').style.display = 'block';
|
||||
if (document.getElementById('buildMacOsHostRadioAppleSilicon').checked) {
|
||||
homebrew_install_dir = '/opt/homebrew';
|
||||
os_mac_host_name = 'Apple silicon';
|
||||
} else {
|
||||
homebrew_install_dir = '/usr/local';
|
||||
os_mac_host_name = 'Intel';
|
||||
}
|
||||
} else {
|
||||
document.getElementById('buildMacOsHostDiv').style.display = 'none';
|
||||
}
|
||||
|
||||
var use_msvc = os_windows;
|
||||
var use_vcpkg = os_windows;
|
||||
@ -312,7 +503,7 @@ function onOptionsChanged() {
|
||||
var cmake = 'cmake';
|
||||
if (os_mac) {
|
||||
commands.push('xcode-select --install');
|
||||
commands.push('/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"');
|
||||
commands.push('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"');
|
||||
commands.push('brew install gperf cmake openssl');
|
||||
} else if (os_linux && linux_distro !== 'Other') {
|
||||
switch (linux_distro) {
|
||||
@ -435,7 +626,7 @@ function onOptionsChanged() {
|
||||
|
||||
cmake_init_options = getBacicCmakeInitOptions();
|
||||
if (os_mac) {
|
||||
cmake_init_options.push('-DOPENSSL_ROOT_DIR=/usr/local/opt/openssl/');
|
||||
cmake_init_options.push('-DOPENSSL_ROOT_DIR=' + homebrew_install_dir + '/opt/openssl/');
|
||||
}
|
||||
cmake_init_options.push('-DCMAKE_INSTALL_PREFIX:PATH=' + install_dir);
|
||||
if (use_vcpkg) {
|
||||
@ -485,6 +676,26 @@ function onOptionsChanged() {
|
||||
}
|
||||
commands.push((use_powershell ? 'dir ' : 'ls -l ') + install_dir + '/bin/tdlight-telegram-bot-api*');
|
||||
document.getElementById('buildCommands').innerHTML = '<ul><li>' + commands.join('</li><li>') + '</li></ul>';
|
||||
document.getElementById('copyBuildCommandsButton').style.display = commands.includes('exit') ? 'none' : 'block';
|
||||
}
|
||||
|
||||
function copyBuildInstructions() {
|
||||
var text = document.getElementById('buildCommands').innerText;
|
||||
|
||||
function resetButtonState (state) {
|
||||
document.getElementById('copyBuildCommandsButton').classList.remove(state);
|
||||
document.getElementById('copyBuildCommandsText').innerText = "Copy";
|
||||
}
|
||||
|
||||
navigator.clipboard.writeText(text).then(result => {
|
||||
document.getElementById('copyBuildCommandsButton').classList.add('success');
|
||||
document.getElementById('copyBuildCommandsText').innerText = "Copied!";
|
||||
setTimeout(() => resetButtonState('success'), 5000);
|
||||
}, error => {
|
||||
document.getElementById('copyBuildCommandsButton').classList.add('fail');
|
||||
document.getElementById('copyBuildCommandsText').innerText = "Couldn't copy :(";
|
||||
setTimeout(() => resetButtonState('fail'), 5000);
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
2
td
2
td
@ -1 +1 @@
|
||||
Subproject commit 5a76413990ff96653bfda32d37f38ee825be65d8
|
||||
Subproject commit 1e1ab5d1b0e4811e6d9e1584a82da08448d0cada
|
File diff suppressed because it is too large
Load Diff
@ -11,11 +11,11 @@
|
||||
#include "telegram-bot-api/WebhookActor.h"
|
||||
|
||||
#include "td/telegram/ClientActor.h"
|
||||
#include "td/telegram/td_api.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
#include "td/actor/SignalSlot.h"
|
||||
#include "td/actor/Timeout.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/Container.h"
|
||||
@ -36,12 +36,12 @@ struct ClientParameters;
|
||||
|
||||
namespace td_api = td::td_api;
|
||||
|
||||
class Client : public WebhookActor::Callback {
|
||||
class Client final : public WebhookActor::Callback {
|
||||
public:
|
||||
Client(td::ActorShared<> parent, const td::string &bot_token, bool is_user, bool is_test_dc, td::int64 tqueue_id,
|
||||
std::shared_ptr<const ClientParameters> parameters, td::ActorId<BotStatActor> stat_actor);
|
||||
|
||||
void send(PromisedQueryPtr query) override;
|
||||
void send(PromisedQueryPtr query) final;
|
||||
|
||||
void close();
|
||||
|
||||
@ -65,8 +65,6 @@ class Client : public WebhookActor::Callback {
|
||||
|
||||
static constexpr int32 MAX_CONCURRENTLY_SENT_CHAT_MESSAGES = 1000; // some unreasonably big value
|
||||
|
||||
static constexpr int32 MESSAGES_CACHE_TIME = 3600;
|
||||
|
||||
static constexpr std::size_t MIN_PENDING_UPDATES_WARNING = 200;
|
||||
|
||||
static constexpr int64 GREAT_MINDS_SET_ID = 1842540969984001;
|
||||
@ -413,7 +411,7 @@ class Client : public WebhookActor::Callback {
|
||||
|
||||
static object_ptr<td_api::MaskPoint> mask_index_to_point(int32 index);
|
||||
|
||||
td::Result<td::vector<object_ptr<td_api::InputSticker>>> get_input_stickers(const Query *query) const;
|
||||
td::Result<td::vector<object_ptr<td_api::inputSticker>>> get_input_stickers(const Query *query, bool is_masks) const;
|
||||
|
||||
static td::Result<td::string> get_passport_element_hash(Slice encoded_hash);
|
||||
|
||||
@ -459,7 +457,9 @@ class Client : public WebhookActor::Callback {
|
||||
td::Result<td::vector<object_ptr<td_api::InputMessageContent>>> get_input_message_contents(
|
||||
const Query *query, td::JsonValue &&value) const;
|
||||
|
||||
static object_ptr<td_api::messageSendOptions> get_message_send_options(bool disable_notification, object_ptr<td_api::MessageSchedulingState> &&scheduling_state);
|
||||
static object_ptr<td_api::messageSendOptions> get_message_send_options(bool disable_notification,
|
||||
bool protect_content,
|
||||
object_ptr<td_api::MessageSchedulingState> &&scheduling_state);
|
||||
|
||||
static td::Result<td::vector<td::string>> get_poll_options(const Query *query);
|
||||
|
||||
@ -622,11 +622,11 @@ class Client : public WebhookActor::Callback {
|
||||
void process_register_user_query(PromisedQueryPtr &query);
|
||||
|
||||
|
||||
void webhook_verified(td::string cached_ip_address) override;
|
||||
void webhook_success() override;
|
||||
void webhook_error(Status status) override;
|
||||
void webhook_closed(Status status) override;
|
||||
void hangup_shared() override;
|
||||
void webhook_verified(td::string cached_ip_address) final;
|
||||
void webhook_success() final;
|
||||
void webhook_error(Status status) final;
|
||||
void webhook_closed(Status status) final;
|
||||
void hangup_shared() final;
|
||||
int32 get_webhook_max_connections(const Query *query) const;
|
||||
static bool get_webhook_fix_ip_address(const Query *query);
|
||||
void do_set_webhook(PromisedQueryPtr query, bool was_deleted);
|
||||
@ -665,13 +665,13 @@ class Client : public WebhookActor::Callback {
|
||||
|
||||
void long_poll_wakeup(bool force_flag);
|
||||
|
||||
void start_up() override;
|
||||
void start_up() final;
|
||||
|
||||
void raw_event(const td::Event::Raw &event) override;
|
||||
void raw_event(const td::Event::Raw &event) final;
|
||||
|
||||
void loop() override;
|
||||
void loop() final;
|
||||
|
||||
void timeout_expired() override;
|
||||
void timeout_expired() final;
|
||||
|
||||
struct UserInfo {
|
||||
enum class Type { Regular, Deleted, Bot, Unknown };
|
||||
@ -768,10 +768,6 @@ class Client : public WebhookActor::Callback {
|
||||
td::string get_chat_description(int64 chat_id) const;
|
||||
|
||||
struct MessageInfo {
|
||||
mutable double access_time = 1e20;
|
||||
mutable const MessageInfo *lru_next = nullptr;
|
||||
mutable const MessageInfo *lru_prev = nullptr;
|
||||
|
||||
int64 id = 0;
|
||||
int64 sender_user_id = 0;
|
||||
int64 sender_chat_id = 0;
|
||||
@ -842,9 +838,6 @@ class Client : public WebhookActor::Callback {
|
||||
|
||||
void remove_replies_to_message(int64 chat_id, int64 reply_to_message_id, bool only_from_cache);
|
||||
void delete_message(int64 chat_id, int64 message_id, bool only_from_cache);
|
||||
static void delete_messages_lru(void *client_void);
|
||||
void schedule_next_delete_messages_lru();
|
||||
void update_message_lru(const MessageInfo *message_info) const;
|
||||
|
||||
void add_new_message(object_ptr<td_api::message> &&message, bool is_edited);
|
||||
void process_new_message_queue(int64 chat_id);
|
||||
@ -995,7 +988,6 @@ class Client : public WebhookActor::Callback {
|
||||
|
||||
static std::unordered_map<td::string, Status (Client::*)(PromisedQueryPtr &query)> methods_;
|
||||
|
||||
MessageInfo messages_lru_root_;
|
||||
std::unordered_map<FullMessageId, std::unique_ptr<MessageInfo>, FullMessageIdHash> messages_; // message cache
|
||||
std::unordered_map<int64, UserInfo> users_; // user info cache
|
||||
std::unordered_map<int64, GroupInfo> groups_; // group info cache
|
||||
@ -1007,8 +999,6 @@ class Client : public WebhookActor::Callback {
|
||||
std::unordered_map<FullMessageId, std::unordered_set<int64>, FullMessageIdHash>
|
||||
yet_unsent_reply_message_ids_; // message -> replies to it
|
||||
|
||||
td::Timeout next_delete_messages_lru_timeout_;
|
||||
|
||||
std::unordered_map<int32, td::vector<PromisedQueryPtr>> file_download_listeners_;
|
||||
std::unordered_set<int32> download_started_file_ids_;
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "telegram-bot-api/StatsJson.h"
|
||||
|
||||
#include "td/telegram/ClientActor.h"
|
||||
#include "td/telegram/td_api.h"
|
||||
|
||||
#include "td/db/binlog/Binlog.h"
|
||||
#include "td/db/binlog/ConcurrentBinlog.h"
|
||||
|
@ -76,9 +76,9 @@ class ClientManager final : public td::Actor {
|
||||
static PromisedQueryPtr get_webhook_restore_query(td::Slice token, bool is_user, td::Slice webhook_info,
|
||||
std::shared_ptr<SharedData> shared_data);
|
||||
|
||||
void start_up() override;
|
||||
void raw_event(const td::Event::Raw &event) override;
|
||||
void hangup_shared() override;
|
||||
void start_up() final;
|
||||
void raw_event(const td::Event::Raw &event) final;
|
||||
void hangup_shared() final;
|
||||
void close_db();
|
||||
void finish_close();
|
||||
};
|
||||
|
@ -6,13 +6,13 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
|
||||
#include "td/db/KeyValueSyncInterface.h"
|
||||
#include "td/db/TQueue.h"
|
||||
|
||||
#include "td/net/GetHostByNameActor.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/List.h"
|
||||
#include "td/utils/port/IPAddress.h"
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
namespace td {
|
||||
class NetQueryStats;
|
||||
}
|
||||
} // namespace td
|
||||
|
||||
namespace telegram_bot_api {
|
||||
|
||||
|
@ -9,12 +9,12 @@
|
||||
#include "telegram-bot-api/ClientManager.h"
|
||||
#include "telegram-bot-api/Query.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
|
||||
#include "td/net/HttpInboundConnection.h"
|
||||
#include "td/net/HttpQuery.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/Slice.h"
|
||||
|
||||
@ -24,15 +24,15 @@ namespace telegram_bot_api {
|
||||
|
||||
struct SharedData;
|
||||
|
||||
class HttpConnection : public td::HttpInboundConnection::Callback {
|
||||
class HttpConnection final : public td::HttpInboundConnection::Callback {
|
||||
public:
|
||||
explicit HttpConnection(td::ActorId<ClientManager> client_manager, std::shared_ptr<SharedData> shared_data)
|
||||
: client_manager_(client_manager), shared_data_(std::move(shared_data)) {
|
||||
}
|
||||
|
||||
void handle(td::unique_ptr<td::HttpQuery> http_query, td::ActorOwn<td::HttpInboundConnection> connection) override;
|
||||
void handle(td::unique_ptr<td::HttpQuery> http_query, td::ActorOwn<td::HttpInboundConnection> connection) final;
|
||||
|
||||
void wakeup() override;
|
||||
void wakeup() final;
|
||||
|
||||
private:
|
||||
td::FutureActor<td::unique_ptr<Query>> result_;
|
||||
@ -40,7 +40,7 @@ class HttpConnection : public td::HttpInboundConnection::Callback {
|
||||
td::ActorOwn<td::HttpInboundConnection> connection_;
|
||||
std::shared_ptr<SharedData> shared_data_;
|
||||
|
||||
void hangup() override {
|
||||
void hangup() final {
|
||||
connection_.release();
|
||||
stop();
|
||||
}
|
||||
|
@ -6,11 +6,11 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
|
||||
#include "td/net/HttpInboundConnection.h"
|
||||
#include "td/net/TcpListener.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
|
||||
#include "td/utils/BufferedFd.h"
|
||||
#include "td/utils/FloodControlFast.h"
|
||||
#include "td/utils/format.h"
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
namespace telegram_bot_api {
|
||||
|
||||
class HttpServer : public td::TcpListener::Callback {
|
||||
class HttpServer final : public td::TcpListener::Callback {
|
||||
public:
|
||||
HttpServer(td::string ip_address, int port,
|
||||
std::function<td::ActorOwn<td::HttpInboundConnection::Callback>()> creator)
|
||||
@ -39,7 +39,7 @@ class HttpServer : public td::TcpListener::Callback {
|
||||
td::ActorOwn<td::TcpListener> listener_;
|
||||
td::FloodControlFast flood_control_;
|
||||
|
||||
void start_up() override {
|
||||
void start_up() final {
|
||||
auto now = td::Time::now();
|
||||
auto wakeup_at = flood_control_.get_wakeup_at();
|
||||
if (wakeup_at > now) {
|
||||
@ -53,13 +53,13 @@ class HttpServer : public td::TcpListener::Callback {
|
||||
actor_shared(this, 1), ip_address_);
|
||||
}
|
||||
|
||||
void hangup_shared() override {
|
||||
void hangup_shared() final {
|
||||
LOG(ERROR) << "TCP listener was closed";
|
||||
listener_.release();
|
||||
yield();
|
||||
}
|
||||
|
||||
void accept(td::SocketFd fd) override {
|
||||
void accept(td::SocketFd fd) final {
|
||||
auto scheduler_count = td::Scheduler::instance()->sched_count();
|
||||
auto scheduler_id = scheduler_count - 1;
|
||||
if (scheduler_id > 0) {
|
||||
@ -70,7 +70,7 @@ class HttpServer : public td::TcpListener::Callback {
|
||||
.release();
|
||||
}
|
||||
|
||||
void loop() override {
|
||||
void loop() final {
|
||||
if (listener_.empty()) {
|
||||
start_up();
|
||||
}
|
||||
|
@ -8,23 +8,23 @@
|
||||
|
||||
#include "telegram-bot-api/ClientManager.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
|
||||
#include "td/net/HttpInboundConnection.h"
|
||||
#include "td/net/HttpQuery.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
|
||||
#include "td/utils/buffer.h"
|
||||
|
||||
namespace telegram_bot_api {
|
||||
|
||||
class HttpStatConnection : public td::HttpInboundConnection::Callback {
|
||||
class HttpStatConnection final : public td::HttpInboundConnection::Callback {
|
||||
public:
|
||||
explicit HttpStatConnection(td::ActorId<ClientManager> client_manager) : client_manager_(client_manager) {
|
||||
}
|
||||
void handle(td::unique_ptr<td::HttpQuery> http_query, td::ActorOwn<td::HttpInboundConnection> connection) override;
|
||||
void handle(td::unique_ptr<td::HttpQuery> http_query, td::ActorOwn<td::HttpInboundConnection> connection) final;
|
||||
|
||||
void wakeup() override;
|
||||
void wakeup() final;
|
||||
|
||||
private:
|
||||
bool as_json_;
|
||||
@ -32,7 +32,7 @@ class HttpStatConnection : public td::HttpInboundConnection::Callback {
|
||||
td::ActorId<ClientManager> client_manager_;
|
||||
td::ActorOwn<td::HttpInboundConnection> connection_;
|
||||
|
||||
void hangup() override {
|
||||
void hangup() final {
|
||||
connection_.release();
|
||||
stop();
|
||||
}
|
||||
|
@ -8,11 +8,11 @@
|
||||
|
||||
#include "telegram-bot-api/ClientParameters.h"
|
||||
|
||||
#include "td/net/HttpFile.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
|
||||
#include "td/net/HttpFile.h"
|
||||
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/JsonBuilder.h"
|
||||
@ -30,7 +30,7 @@ namespace telegram_bot_api {
|
||||
|
||||
class BotStatActor;
|
||||
|
||||
class Query : public td::ListNode {
|
||||
class Query final : public td::ListNode {
|
||||
public:
|
||||
enum class State : td::int8 { Query, OK, Error };
|
||||
|
||||
@ -170,7 +170,7 @@ td::StringBuilder &operator<<(td::StringBuilder &sb, const Query &query);
|
||||
// https://stackoverflow.com/questions/26947704/implicit-conversion-failure-from-initializer-list
|
||||
extern std::unordered_map<td::string, std::unique_ptr<td::VirtuallyJsonable>> empty_parameters;
|
||||
|
||||
class JsonParameters : public td::Jsonable {
|
||||
class JsonParameters final : public td::Jsonable {
|
||||
public:
|
||||
explicit JsonParameters(const std::unordered_map<td::string, std::unique_ptr<td::VirtuallyJsonable>> ¶meters)
|
||||
: parameters_(parameters) {
|
||||
@ -188,7 +188,7 @@ class JsonParameters : public td::Jsonable {
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class JsonQueryOk : public td::Jsonable {
|
||||
class JsonQueryOk final : public td::Jsonable {
|
||||
public:
|
||||
JsonQueryOk(const T &result, td::Slice description) : result_(result), description_(description) {
|
||||
}
|
||||
@ -206,7 +206,7 @@ class JsonQueryOk : public td::Jsonable {
|
||||
td::Slice description_;
|
||||
};
|
||||
|
||||
class JsonQueryError : public td::Jsonable {
|
||||
class JsonQueryError final : public td::Jsonable {
|
||||
public:
|
||||
JsonQueryError(
|
||||
int error_code, td::Slice description,
|
||||
|
@ -157,7 +157,7 @@ class BotStatActor final : public td::Actor {
|
||||
BotStatActor(const BotStatActor &) = delete;
|
||||
BotStatActor &operator=(const BotStatActor &other) = delete;
|
||||
BotStatActor(BotStatActor &&) = default;
|
||||
BotStatActor &operator=(BotStatActor &&other) {
|
||||
BotStatActor &operator=(BotStatActor &&other) noexcept {
|
||||
if (!empty()) {
|
||||
do_stop();
|
||||
}
|
||||
@ -166,7 +166,7 @@ class BotStatActor final : public td::Actor {
|
||||
parent_ = other.parent_;
|
||||
return *this;
|
||||
}
|
||||
~BotStatActor() override = default;
|
||||
~BotStatActor() final = default;
|
||||
|
||||
template <class EventT>
|
||||
void add_event(const EventT &event, double now) {
|
||||
|
@ -152,11 +152,11 @@ td::Status WebhookActor::create_connection() {
|
||||
}
|
||||
|
||||
VLOG(webhook) << "Create connection through proxy " << parameters_->webhook_proxy_ip_address_;
|
||||
class Callback : public td::TransparentProxy::Callback {
|
||||
class Callback final : public td::TransparentProxy::Callback {
|
||||
public:
|
||||
Callback(td::ActorId<WebhookActor> actor, td::int64 id) : actor_(actor), id_(id) {
|
||||
}
|
||||
void set_result(td::Result<td::BufferedFd<td::SocketFd>> result) override {
|
||||
void set_result(td::Result<td::BufferedFd<td::SocketFd>> result) final {
|
||||
send_closure(std::move(actor_), &WebhookActor::on_socket_ready_async, std::move(result), id_);
|
||||
CHECK(actor_.empty());
|
||||
}
|
||||
@ -169,7 +169,7 @@ td::Status WebhookActor::create_connection() {
|
||||
send_closure(std::move(actor_), &WebhookActor::on_socket_ready_async, td::Status::Error("Canceled"), id_);
|
||||
}
|
||||
}
|
||||
void on_connected() override {
|
||||
void on_connected() final {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@ -356,7 +356,7 @@ void WebhookActor::load_updates() {
|
||||
|
||||
auto offset = tqueue_offset_;
|
||||
auto limit = td::min(SharedData::TQUEUE_EVENT_BUFFER_SIZE, max_loaded_updates_ - queue_updates_.size());
|
||||
auto updates = mutable_span(parameters_->shared_data_->event_buffer_, limit);
|
||||
td::MutableSpan<td::TQueue::Event> updates(parameters_->shared_data_->event_buffer_, limit);
|
||||
|
||||
auto now = td::Time::now();
|
||||
auto unix_time_now = parameters_->shared_data_->get_unix_time(now);
|
||||
|
@ -41,7 +41,7 @@ namespace telegram_bot_api {
|
||||
|
||||
struct ClientParameters;
|
||||
|
||||
class WebhookActor : public td::HttpOutboundConnection::Callback {
|
||||
class WebhookActor final : public td::HttpOutboundConnection::Callback {
|
||||
public:
|
||||
class Callback : public td::Actor {
|
||||
public:
|
||||
@ -139,7 +139,7 @@ class WebhookActor : public td::HttpOutboundConnection::Callback {
|
||||
double next_ip_address_resolve_time_ = 0;
|
||||
td::FutureActor<td::IPAddress> future_ip_address_;
|
||||
|
||||
class Connection : public td::ListNode {
|
||||
class Connection final : public td::ListNode {
|
||||
public:
|
||||
Connection() = default;
|
||||
Connection(const Connection &) = delete;
|
||||
@ -190,26 +190,26 @@ class WebhookActor : public td::HttpOutboundConnection::Callback {
|
||||
td::Status send_update() TD_WARN_UNUSED_RESULT;
|
||||
void send_updates();
|
||||
|
||||
void loop() override;
|
||||
void handle(td::unique_ptr<td::HttpQuery> response) override;
|
||||
void loop() final;
|
||||
void handle(td::unique_ptr<td::HttpQuery> response) final;
|
||||
|
||||
void hangup_shared() override;
|
||||
void hangup_shared() final;
|
||||
|
||||
void hangup() override;
|
||||
void hangup() final;
|
||||
|
||||
void tear_down() override;
|
||||
void tear_down() final;
|
||||
|
||||
void start_up() override;
|
||||
void start_up() final;
|
||||
|
||||
bool check_ip_address(const td::IPAddress &addr) const;
|
||||
|
||||
void on_error(td::Status status);
|
||||
void on_connection_error(td::Status error) override;
|
||||
void on_connection_error(td::Status error) final;
|
||||
void on_webhook_error(td::Slice error);
|
||||
void on_webhook_verified();
|
||||
};
|
||||
|
||||
class JsonUpdate : public td::Jsonable {
|
||||
class JsonUpdate final : public td::Jsonable {
|
||||
public:
|
||||
JsonUpdate(td::int32 id, td::Slice update) : id_(id), update_(update) {
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ int main(int argc, char *argv[]) {
|
||||
auto start_time = td::Time::now();
|
||||
auto shared_data = std::make_shared<SharedData>();
|
||||
auto parameters = std::make_unique<ClientParameters>();
|
||||
parameters->version_ = "5.5.1";
|
||||
parameters->version_ = "5.7";
|
||||
parameters->shared_data_ = shared_data;
|
||||
parameters->start_time_ = start_time;
|
||||
auto net_query_stats = td::create_net_query_stats();
|
||||
@ -320,22 +320,23 @@ int main(int argc, char *argv[]) {
|
||||
options.add_checked_option('c', "max-connections", "maximum number of open file descriptors",
|
||||
td::OptionParser::parse_integer(max_connections));
|
||||
|
||||
|
||||
options.add_checked_option('\0', "max-batch-operations", PSLICE() << "maximum number of batch operations (default: " << parameters->max_batch_operations << ")",
|
||||
td::OptionParser::parse_integer(parameters->max_batch_operations));
|
||||
td::OptionParser::parse_integer(parameters->max_batch_operations));
|
||||
options.add_checked_option('\0', "file-expiration-time",
|
||||
PSLICE() << "downloaded files expire after this amount of seconds of not being used (defaults to " << parameters->file_expiration_timeout_seconds_ << ")",
|
||||
td::OptionParser::parse_integer(parameters->file_expiration_timeout_seconds_));
|
||||
|
||||
options.add_checked_option(
|
||||
'\0', "proxy", PSLICE() << "HTTP proxy server for outgoing webhook requests in the format http://host:port",
|
||||
[&](td::Slice address) {
|
||||
if (td::begins_with(address, "http://")) {
|
||||
address.remove_prefix(7);
|
||||
} else if (td::begins_with(address, "https://")) {
|
||||
address.remove_prefix(8);
|
||||
}
|
||||
return parameters->webhook_proxy_ip_address_.init_host_port(address.str());
|
||||
});
|
||||
|
||||
options.add_checked_option('\0', "proxy",
|
||||
"HTTP proxy server for outgoing webhook requests in the format http://host:port",
|
||||
[&](td::Slice address) {
|
||||
if (td::begins_with(address, "http://")) {
|
||||
address.remove_prefix(7);
|
||||
} else if (td::begins_with(address, "https://")) {
|
||||
address.remove_prefix(8);
|
||||
}
|
||||
return parameters->webhook_proxy_ip_address_.init_host_port(address.str());
|
||||
});
|
||||
options.add_check([&] {
|
||||
if (parameters->api_id_ <= 0 || parameters->api_hash_.empty()) {
|
||||
return td::Status::Error("You must provide valid api-id and api-hash obtained at https://my.telegram.org");
|
||||
|
Loading…
Reference in New Issue
Block a user