just throwin there
This commit is contained in:
commit
278d7cf05d
52 changed files with 5712 additions and 0 deletions
12
.cargo/config.toml
Normal file
12
.cargo/config.toml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
[build]
|
||||||
|
rustflags = ["--cfg=has_std", "-Zthreads=6"]
|
||||||
|
|
||||||
|
[target.x86_64-unknown-linux-gnu]
|
||||||
|
rustflags = ["-Csplit-debuginfo=unpacked", "-Clink-arg=-fuse-ld=mold"]
|
||||||
|
|
||||||
|
[profile.release.build-override]
|
||||||
|
inherits = "release"
|
||||||
|
|
||||||
|
[registries.Technologygeek]
|
||||||
|
index = "sparse+https://source.technologygeek.ru/api/packages/Technologygeek/cargo/"
|
||||||
|
credential-provider = ["cargo:token"]
|
||||||
3
.cargo/container_release.toml
Normal file
3
.cargo/container_release.toml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
[build]
|
||||||
|
rustflags = ["--cfg=has_std", "-Zthreads=6", "-Zlocation-detail=none", "-Cpanic=abort"]
|
||||||
|
target = ["x86_64-unknown-linux-musl"]
|
||||||
8
.containerignore
Normal file
8
.containerignore
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
Containerfile
|
||||||
|
.envrc
|
||||||
|
target
|
||||||
|
Cargo.lock
|
||||||
|
dev-volumes
|
||||||
|
adsbot.conf.d.example
|
||||||
|
adsbot.log
|
||||||
|
adsbot.db
|
||||||
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
/target
|
||||||
|
/dev-volumes
|
||||||
|
.envrc
|
||||||
|
adsbot.db
|
||||||
|
adsbot.log
|
||||||
|
adsbot.conf
|
||||||
3066
Cargo.lock
generated
Normal file
3066
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
69
Cargo.toml
Normal file
69
Cargo.toml
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
[package]
|
||||||
|
name = "adsbot"
|
||||||
|
version = "0.1.0"
|
||||||
|
rust-version = "1.95"
|
||||||
|
edition = "2024"
|
||||||
|
license = "MIT"
|
||||||
|
license-file = "LICENSE"
|
||||||
|
authors = ["Svyatoslav Pushkarev <spushk@spushk.ru>"]
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
## Rt
|
||||||
|
tokio.version = "^1"
|
||||||
|
tokio.features = ["full"]
|
||||||
|
deadpool.version = "^0.13"
|
||||||
|
deadpool.features = ["rt_tokio_1", "serde"]
|
||||||
|
async-trait.version = "^0.1"
|
||||||
|
## Logging
|
||||||
|
tracing.version = "^0.1"
|
||||||
|
tracing.features = ["max_level_debug", "release_max_level_info"]
|
||||||
|
tracing-subscriber.version = "^0.3"
|
||||||
|
tracing-subscriber.features = ["chrono"]
|
||||||
|
## Database
|
||||||
|
diesel.version = "^2"
|
||||||
|
diesel.features = ["chrono", "sqlite"]
|
||||||
|
diesel_migrations.version = "^2"
|
||||||
|
diesel_migrations.features = ["sqlite"]
|
||||||
|
libsqlite3-sys.version = "^0"
|
||||||
|
libsqlite3-sys.features = ["bundled"]
|
||||||
|
## Marshal
|
||||||
|
serde.version = "^1"
|
||||||
|
serde.features = ["derive"]
|
||||||
|
serde_json.version = "^1"
|
||||||
|
toml.version = "^1"
|
||||||
|
serde_urlencoded.version = "^0.7"
|
||||||
|
urlencoding.version = "^2"
|
||||||
|
## Net
|
||||||
|
teloxide.version = "^0.17"
|
||||||
|
teloxide.default-features = false
|
||||||
|
teloxide.features = ["tracing", "nightly", "ctrlc_handler", "rustls", "macros"]
|
||||||
|
oauth2.version = "^5"
|
||||||
|
reqwest.version = "^0.12"
|
||||||
|
reqwest.default-features = false
|
||||||
|
reqwest.features = ["charset", "http2", "rustls-tls", "json"]
|
||||||
|
## Util
|
||||||
|
chrono.version = "^0.4"
|
||||||
|
regex.version = "^1"
|
||||||
|
## Codegen
|
||||||
|
thiserror.version = "^2"
|
||||||
|
const-str.version = "^1"
|
||||||
|
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
opt-level = 0
|
||||||
|
lto = "off"
|
||||||
|
codegen-units = 256
|
||||||
|
panic = "unwind"
|
||||||
|
debug = "full"
|
||||||
|
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
opt-level = 3
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
opt-level = 3
|
||||||
|
lto = "fat"
|
||||||
|
codegen-units = 1
|
||||||
|
panic = "abort"
|
||||||
|
debug = "none"
|
||||||
|
strip = "symbols"
|
||||||
65
Containerfile
Normal file
65
Containerfile
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
FROM source.spushk.ru/rustyworks/rust-alpine-mimalloc:1.95 as build
|
||||||
|
WORKDIR /build
|
||||||
|
ENV OPENSSL_DIR=/usr
|
||||||
|
ENV TARGET_CC=x86_64-linux-musl-clang
|
||||||
|
ENV CARGO_BUILD_TARGET=x86_64-unknown-linux-musl
|
||||||
|
COPY .cargo .cargo
|
||||||
|
COPY rust-toolchain.toml rust-toolchain.toml
|
||||||
|
RUN --mount=type=secret,id=cargo-token \
|
||||||
|
--mount=type=cache,target=/usr/local/rustup,id=rustup_cache \
|
||||||
|
cat /run/secrets/cargo-token | cargo login --quiet --registry Technologygeek
|
||||||
|
|
||||||
|
FROM build as planner
|
||||||
|
WORKDIR /build
|
||||||
|
COPY . .
|
||||||
|
RUN --mount=type=cache,target=/usr/local/cargo/registry,id=cargo_registry \
|
||||||
|
--mount=type=cache,target=/usr/local/rustup,id=rustup_cache \
|
||||||
|
cargo chef prepare --recipe-path=recipe.json
|
||||||
|
|
||||||
|
FROM build as build-debug
|
||||||
|
WORKDIR /build
|
||||||
|
COPY --from=planner /build/recipe.json recipe.json
|
||||||
|
RUN --mount=type=cache,target=/usr/local/cargo/registry,id=cargo_registry \
|
||||||
|
--mount=type=cache,target=/usr/local/rustup,id=rustup_cache \
|
||||||
|
cargo --config=.cargo/container_debug.toml \
|
||||||
|
chef cook --recipe-path=recipe.json
|
||||||
|
COPY . .
|
||||||
|
RUN --mount=type=cache,target=/usr/local/cargo/registry,id=cargo_registry \
|
||||||
|
--mount=type=cache,target=/usr/local/rustup,id=rustup_cache \
|
||||||
|
cargo --config=.cargo/container_debug.toml \
|
||||||
|
test
|
||||||
|
RUN --mount=type=cache,target=/usr/local/cargo/registry,id=cargo_registry \
|
||||||
|
--mount=type=cache,target=/usr/local/rustup,id=rustup_cache \
|
||||||
|
cargo --config=.cargo/container_debug.toml \
|
||||||
|
build
|
||||||
|
|
||||||
|
FROM build as build-release
|
||||||
|
WORKDIR /build
|
||||||
|
COPY --from=planner /build/recipe.json recipe.json
|
||||||
|
RUN --mount=type=cache,target=/usr/local/cargo/registry,id=cargo_registry \
|
||||||
|
--mount=type=cache,target=/usr/local/rustup,id=rustup_cache \
|
||||||
|
cargo --config=.cargo/container_release.toml \
|
||||||
|
chef cook --release --recipe-path=recipe.json
|
||||||
|
COPY . .
|
||||||
|
RUN --mount=type=cache,target=/usr/local/cargo/registry,id=cargo_registry \
|
||||||
|
--mount=type=cache,target=/usr/local/rustup,id=rustup_cache \
|
||||||
|
cargo --config=.cargo/container_release.toml \
|
||||||
|
build --release
|
||||||
|
|
||||||
|
FROM scratch as app
|
||||||
|
WORKDIR /
|
||||||
|
VOLUME /adsbot.db
|
||||||
|
VOLUME /adsbot.log
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
FROM app as app-debug
|
||||||
|
WORKDIR /
|
||||||
|
COPY --from=build-debug /build/target/x86_64-unknown-linux-musl/debug/adsbot /adsbot
|
||||||
|
ENV RUST_LOG="debug"
|
||||||
|
ENTRYPOINT [ "/adsbot" ]
|
||||||
|
|
||||||
|
FROM app as app-release
|
||||||
|
WORKDIR /
|
||||||
|
COPY --from=build-release /build/target/x86_64-unknown-linux-musl/release/adsbot /adsbot
|
||||||
|
ENV RUST_LOG="info"
|
||||||
|
ENTRYPOINT [ "/adsbot" ]
|
||||||
52
Makefile.toml
Normal file
52
Makefile.toml
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
[env]
|
||||||
|
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
||||||
|
|
||||||
|
[env.development]
|
||||||
|
PROD = false
|
||||||
|
DEV = true
|
||||||
|
_MK_IMAGE_TARGET = 'app-debug'
|
||||||
|
_MK_IMAGE = 'source.spushk.ru/rustyworks/adsbot:debug'
|
||||||
|
|
||||||
|
[env.production]
|
||||||
|
PROD = true
|
||||||
|
DEV = false
|
||||||
|
_MK_IMAGE_TARGET = 'app-release'
|
||||||
|
_MK_IMAGE = 'source.spushk.ru/rustyworks/adsbot:v0.1'
|
||||||
|
|
||||||
|
[tasks.rustfmt]
|
||||||
|
command = "cargo"
|
||||||
|
args = ["fmt", "--", "--emit=files"]
|
||||||
|
|
||||||
|
[tasks.format]
|
||||||
|
dependencies = ["rustfmt"]
|
||||||
|
|
||||||
|
[tasks.build]
|
||||||
|
workspace = false
|
||||||
|
command = "cargo"
|
||||||
|
args = ["build"]
|
||||||
|
|
||||||
|
[tasks.image]
|
||||||
|
workspace = false
|
||||||
|
condition.env_set = ["_MK_IMAGE_TARGET", "_MK_IMAGE"]
|
||||||
|
command = "podman"
|
||||||
|
args = [
|
||||||
|
"build",
|
||||||
|
"--target", "${_MK_IMAGE_TARGET}",
|
||||||
|
"-t", "${_MK_IMAGE}",
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
|
||||||
|
[tasks.image-view]
|
||||||
|
workspace = false
|
||||||
|
condition.env_set = ["_MK_IMAGE"]
|
||||||
|
condition.files_exist = ["${CARGO_MAKE_WORKING_DIRECTORY}/dev-volumes"]
|
||||||
|
command = "podman"
|
||||||
|
args = [
|
||||||
|
"run",
|
||||||
|
"--rm",
|
||||||
|
"-p3000:3000",
|
||||||
|
"-v./dev-volumes/adsbot.conf:/adsbot.conf",
|
||||||
|
"-v./dev-volumes/adsbot.log:/adsbot.log",
|
||||||
|
"-v./dev-volumes/adsbot.db:/adsbot.db",
|
||||||
|
"${_MK_IMAGE}"
|
||||||
|
]
|
||||||
232
README.md
Normal file
232
README.md
Normal file
|
|
@ -0,0 +1,232 @@
|
||||||
|
Very simple bot which will monitor VK ADS form leads and pass them to telegram upstream. Just throwin it here coz friend asked.
|
||||||
|
|
||||||
|
## VK ADS API lead forms
|
||||||
|
|
||||||
|
See the [configuration example](./adsbot.conf.example)
|
||||||
|
|
||||||
|
## Arbitrary POST forms (TBD)
|
||||||
|
|
||||||
|
The arbitrary POST form is created with `adsbot.conf/leadbot/features/formlead.d` TOML
|
||||||
|
configuration. The format is explained in the example.
|
||||||
|
|
||||||
|
POST request head shall contain `Authorization` header with one of the configured secret values.
|
||||||
|
|
||||||
|
POST request raw body size in bytes is limited by 4KiB.
|
||||||
|
|
||||||
|
Request raw body may be:
|
||||||
|
|
||||||
|
- Either valid UTF-8 JSON string with `Content-Type: application/json`
|
||||||
|
- Or a messagepack encoded message with `Content-type: application/msgpack`
|
||||||
|
- Or a raw text, which is reported as-is without parsing with `Content-type: text/plain`
|
||||||
|
|
||||||
|
### Response
|
||||||
|
|
||||||
|
Depending on the request criteria and server state
|
||||||
|
|
||||||
|
### form
|
||||||
|
|
||||||
|
Parsed request body shall contain the field `form`, which is an array limited
|
||||||
|
by 128 entries.
|
||||||
|
|
||||||
|
Excessive entries shall not be reported, form entries are reported in the order of presense.
|
||||||
|
|
||||||
|
Each of entries must follow the schema:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
type: "object",
|
||||||
|
"properties": {
|
||||||
|
"t": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["text","tel","personal","yn"]
|
||||||
|
},
|
||||||
|
"d": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Any form entry, which does not conform to the specified schema, will not be processed.
|
||||||
|
|
||||||
|
#### `t`/`d` fields
|
||||||
|
|
||||||
|
**"text"** type:
|
||||||
|
|
||||||
|
With the `"t": "text"` field set on the POST data, the `d` field is expected to
|
||||||
|
follow the schema:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"q": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The form question/field name to display in report"
|
||||||
|
},
|
||||||
|
"a": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The user answer/value to display in report"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The "text" entry shall be included into report as-is.
|
||||||
|
|
||||||
|
**"tel"** type:
|
||||||
|
|
||||||
|
With the `"t": "tel"` field set on the POST data, the `d` field is expected to
|
||||||
|
follow the schema:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"q": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The form question/field name to display in report"
|
||||||
|
},
|
||||||
|
"a": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The value, which will be treated as personal phone number",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
When possible the "tel" entry shall be included into report as `tel:` anchor/link,
|
||||||
|
and (when possible) shall be hidden under protective block, which does not grant visual access to the phone number without manual interaction or authorization.
|
||||||
|
|
||||||
|
**"personal"** type:
|
||||||
|
|
||||||
|
With the `"t": "personal"` field set on the POST data, the `d` field is expected to
|
||||||
|
follow the schema:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"q": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The form question/field name to display in report"
|
||||||
|
},
|
||||||
|
"a": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The value, which will be treated as personal information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
When possible shall be hidden under protective block, which does not grant visual access to the phone number without manual interaction or authorization.
|
||||||
|
|
||||||
|
**"yesno"** type:
|
||||||
|
|
||||||
|
With the `"t": "yn"` field set on the POST data, the `d` field is expected to
|
||||||
|
follow the schema:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"q": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The form question/field name to display in report"
|
||||||
|
},
|
||||||
|
"a": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "The value, which will be treated as yes/no answer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### example
|
||||||
|
|
||||||
|
|
||||||
|
The following shall not be parsed and will be reported as-is
|
||||||
|
|
||||||
|
```
|
||||||
|
-- HEADERS --
|
||||||
|
Authorization: pqo8jdp9:p183ycnpdo1
|
||||||
|
Content-Type: text/plain
|
||||||
|
-- BODY --
|
||||||
|
I am a text. I wanna MANY alpacas. I demand:
|
||||||
|
|
||||||
|
- At least 1 black alpaca
|
||||||
|
- At most 4 white alpacas
|
||||||
|
- All alpacas to be either black or white
|
||||||
|
- Exactly 666 alpacas
|
||||||
|
```
|
||||||
|
|
||||||
|
The following shall be parsed as JSON
|
||||||
|
|
||||||
|
```
|
||||||
|
-- HEADERS --
|
||||||
|
Authorization: 0192mu:odump298yfcniudo8c3mo
|
||||||
|
Content-type: application/json
|
||||||
|
-- BODY --
|
||||||
|
{
|
||||||
|
"form": [
|
||||||
|
{
|
||||||
|
"t": "personal",
|
||||||
|
"d": {
|
||||||
|
"q": "First name",
|
||||||
|
"a": "Danis"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "text",
|
||||||
|
"d": {
|
||||||
|
"q": "How much aplacas do you have?",
|
||||||
|
"a": "120"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "tel",
|
||||||
|
"d": {
|
||||||
|
"q": "Phone",
|
||||||
|
"a": "88005553535"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "yn",
|
||||||
|
"d": {
|
||||||
|
"q": "Do you want another aplaca?",
|
||||||
|
"a": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
**Software requirements:**
|
||||||
|
|
||||||
|
- `cargo-make`
|
||||||
|
- `diesel-cli`
|
||||||
|
- `podman`
|
||||||
|
|
||||||
|
**Prerequistes:**
|
||||||
|
|
||||||
|
- Create the `dev-volumes/{adsbot.log,adsbot.db,adsbot.conf}` directories,
|
||||||
|
and configure the `dev-volumes/adsbot.conf` by example provided in `adsbot.conf.example`
|
||||||
|
|
||||||
|
**Altering database schema**:
|
||||||
|
|
||||||
|
Dont forget to create appropriate migrations by
|
||||||
|
|
||||||
|
```sh
|
||||||
|
diesel migration generate --diff-schema=<SCHEMA.RS> <MIGRATION_NAME>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building from source
|
||||||
|
|
||||||
|
`cargo make build` for static binary build
|
||||||
|
|
||||||
|
`cargo make image` for container image
|
||||||
|
|
||||||
|
Please, note, that by default on each program startup the license and authors information from Cargo.toml are printed into the log.
|
||||||
|
If you want to disable it - set the `LOG_CREDENTIALS="none"` env variable during the build
|
||||||
10
adsbot.conf.example/leadbot/adsbot.toml
Normal file
10
adsbot.conf.example/leadbot/adsbot.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
[telegram.bot]
|
||||||
|
# Telegram bot api token
|
||||||
|
token = "TOKEN"
|
||||||
|
|
||||||
|
[[telegram.admin]]
|
||||||
|
user = 111111111
|
||||||
|
|
||||||
|
[[logging.telegram]]
|
||||||
|
Chat ID, which will receive logs. For private chat with user - go to the bot and ask him /echo id
|
||||||
|
chat = 22222222222
|
||||||
2
adsbot.conf.example/leadbot/features/echo.d/echo.toml
Normal file
2
adsbot.conf.example/leadbot/features/echo.d/echo.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
info="Keep this directory existing to activate echoing features"
|
||||||
|
|
||||||
17
adsbot.conf.example/leadbot/features/formlead.d/example.toml
Normal file
17
adsbot.conf.example/leadbot/features/formlead.d/example.toml
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Unique (for the formlead feature) identifier. Must be valid URL subpath
|
||||||
|
id = "unique_id_url_safe"
|
||||||
|
|
||||||
|
[[form.post]]
|
||||||
|
# The display name for the form report
|
||||||
|
name = "Display name"
|
||||||
|
# within the current example POST request is accepted at /unique_id_url_safe/subpath_under_id
|
||||||
|
path = "subpath_under_id"
|
||||||
|
# The request sender shall pass "AUTHORIZATION"
|
||||||
|
# "xqoi83nyra0s98d:4e7b44d9a7b220e2b4bd8ba60085f0aa"
|
||||||
|
clients = [
|
||||||
|
{id="xqoi83nyra0s98d", secret="4e7b44d9a7b220e2b4bd8ba60085f0aa"}
|
||||||
|
]
|
||||||
|
# The following destinations will receive form reports
|
||||||
|
reports = [
|
||||||
|
{telegram = {chat = -10000000000000}}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
# The unique (for the vkadslead feature) id. Must be valid URL subpath
|
||||||
|
id = "unique_id_url_safe"
|
||||||
|
|
||||||
|
[api]
|
||||||
|
# Client ID received from VK ADS api
|
||||||
|
client_id = "VKADS API CLIENT ID"
|
||||||
|
# Client secret receiver from VK ADS api
|
||||||
|
client_secret = "VKADS API CLIENT SECRET"
|
||||||
|
|
||||||
|
[[telegram.admin]]
|
||||||
|
user = 111111111
|
||||||
|
|
||||||
|
[[form]]
|
||||||
|
# Display name for the form report
|
||||||
|
name = "Display name"
|
||||||
|
# Form identifier as shown by VK ADS
|
||||||
|
id = "VKADS form id"
|
||||||
|
# I forgot what this does
|
||||||
|
anonymous = false
|
||||||
|
# The following destinations shall receive form reports
|
||||||
|
reports = [
|
||||||
|
{telegram = {chat = -10000000000000}}
|
||||||
|
]
|
||||||
13
diesel.toml
Normal file
13
diesel.toml
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
# For documentation on how to configure this file,
|
||||||
|
# see https://diesel.rs/guides/configuring-diesel-cli
|
||||||
|
|
||||||
|
[print_schema.feature_vkadslead]
|
||||||
|
file = "src/features/vkadslead/db/schema.rs"
|
||||||
|
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
|
||||||
|
|
||||||
|
[print_schema.integration_telegram]
|
||||||
|
file = "src/telegram/db/schema.rs"
|
||||||
|
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
|
||||||
|
|
||||||
|
[migrations_directory]
|
||||||
|
dir = "migrations"
|
||||||
0
migrations/.keep
Normal file
0
migrations/.keep
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
DROP TABLE IF EXISTS `features_vkadslead_clientauth`;
|
||||||
|
DROP TABLE IF EXISTS `features_vkadslead_formsync`;
|
||||||
19
migrations/2025-09-10-144245_init_feature_vkadslead/up.sql
Normal file
19
migrations/2025-09-10-144245_init_feature_vkadslead/up.sql
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
-- Your SQL goes here
|
||||||
|
CREATE TABLE IF NOT EXISTS `features_vkadslead_clientauth` (
|
||||||
|
`instance` TEXT NOT NULL PRIMARY KEY,
|
||||||
|
`client_id` TEXT NOT NULL,
|
||||||
|
`access_token` TEXT NOT NULL,
|
||||||
|
`ctime` TIMESTAMP NOT NULL,
|
||||||
|
`expires_in` INTEGER,
|
||||||
|
`refresh_token` TEXT,
|
||||||
|
`scope` TEXT,
|
||||||
|
`token_type` TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `features_vkadslead_formsync` (
|
||||||
|
`instance_id` TEXT NOT NULL,
|
||||||
|
`form_id` TEXT NOT NULL,
|
||||||
|
`stime` TIMESTAMP NOT NULL,
|
||||||
|
PRIMARY KEY (`instance_id`, `form_id`),
|
||||||
|
FOREIGN KEY (`instance_id`) REFERENCES `features_vkadslead_clientauth` (`instance`)
|
||||||
|
);
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
DROP TABLE IF EXISTS `integrations_telegram_auth`;
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
-- Your SQL goes here
|
||||||
|
CREATE TABLE IF NOT EXISTS `integrations_telegram_auth` (
|
||||||
|
`id` INTEGER NOT NULL PRIMARY KEY,
|
||||||
|
`token` TEXT NOT NULL
|
||||||
|
);
|
||||||
3
rust-toolchain.toml
Normal file
3
rust-toolchain.toml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "nightly-2026-05-10"
|
||||||
|
components = ["rust-src"]
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue