Safebooru functionality added

This commit is contained in:
Dmitry Anderson 2024-10-26 18:21:50 +02:00
parent a1e6284a16
commit 07704dbaff
5 changed files with 165 additions and 149 deletions

View File

@ -9,7 +9,7 @@ When new user starts the bot it sends him a captcha. After passing the captcha u
### Safebooru image search ### Safebooru image search
To search images via safebooru just type in your message prompt<br> To search images via safebooru just type in your message prompt<br>
`@mental_illness_center_bot safebooru <tags>`<br> `@mental_illness_center_bot sfbr <tags>`<br>
and it will find images for you. and it will find images for you.
## TODO: ## TODO:

View File

@ -6,6 +6,8 @@ import { Database } from "../../repo/exports.ts";
import { CompiledConfig } from "../../cfg/config.ts"; import { CompiledConfig } from "../../cfg/config.ts";
import { checkUser, checkUserOnNewChatMember, onMemberLeftChat, checkUserOnStart } from "./user_managment.ts"; import { checkUser, checkUserOnNewChatMember, onMemberLeftChat, checkUserOnStart } from "./user_managment.ts";
import { checkCaptchaSolution, initUserCaptcha } from "./captcha.ts"; import { checkCaptchaSolution, initUserCaptcha } from "./captcha.ts";
import { getSafebooruPosts } from "../../external/safebooru.ts";
import { handleSafebooruQuery } from "./safebooru.ts";
interface ChatMemberUpdateStatus { interface ChatMemberUpdateStatus {
joined: boolean, joined: boolean,
@ -76,4 +78,8 @@ export const init = (bot: Bot<Ctx>, db: Kysely<Database>, cfg: CompiledConfig) =
} }
await next() await next()
}) })
bot.inlineQuery(/sfbr */, async ctx => {
await handleSafebooruQuery(ctx, getSafebooruPosts)
})
} }

View File

@ -0,0 +1,30 @@
import { InlineQueryResultBuilder, type InlineQueryContext } from "https://deno.land/x/grammy/mod.ts";
import type { InlineQueryResult } from "https://deno.land/x/grammy_types/inline.ts";
import type { Ctx } from "../ctx.ts";
import type { GetSafebooruPostsFunc } from "../../external/safebooru.ts";
import { SAFEBOORU_HOST } from "../../external/safebooru.ts";
export const DEFAULT_POSTS_LIMIT = 30
export const DEFAULT_START_PAGE_ID = 0
export const handleSafebooruQuery = async (
ctx: InlineQueryContext<Ctx>,
getPosts: GetSafebooruPostsFunc
): Promise<void> => {
// Remove the safebooru refix
const query = ctx.inlineQuery.query.slice("safebooru".length)
const tags = query.split(" ")
// So we make a request, get some posts in a structure
const posts = await getPosts(DEFAULT_POSTS_LIMIT, DEFAULT_START_PAGE_ID, tags)
const results: InlineQueryResult[] = []
posts.map((post) => {
results.push(InlineQueryResultBuilder.photo(`id-${post.id}`, post.file_url, {
thumbnail_url: post.preview_url,
caption: `[source](https://${SAFEBOORU_HOST}/index.php?page=post&s=view&id=${post.id})`,
parse_mode: "MarkdownV2",
}))
})
// await ctx.answerInlineQuery(results, { cache_time: 0 })
await ctx.api.answerInlineQuery(ctx.inlineQuery.id, results, { cache_time: 1 })
}

274
deno.lock
View File

@ -1,156 +1,138 @@
{ {
"version": "3", "version": "4",
"packages": { "specifiers": {
"specifiers": { "jsr:@std/path@*": "1.0.6",
"jsr:@std/path": "jsr:@std/path@1.0.6", "npm:@types/node@*": "18.16.19",
"npm:@types/node": "npm:@types/node@18.16.19", "npm:@types/pg@*": "8.11.10",
"npm:@types/pg": "npm:@types/pg@8.11.10", "npm:kysely@*": "0.27.4",
"npm:kysely": "npm:kysely@0.27.4", "npm:pg@*": "8.13.0"
"npm:pg": "npm:pg@8.13.0" },
"jsr": {
"@std/path@1.0.6": {
"integrity": "ab2c55f902b380cf28e0eec501b4906e4c1960d13f00e11cfbcd21de15f18fed"
}
},
"npm": {
"@types/node@18.16.19": {
"integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA=="
}, },
"jsr": { "@types/pg@8.11.10": {
"@std/path@1.0.6": { "integrity": "sha512-LczQUW4dbOQzsH2RQ5qoeJ6qJPdrcM/DcMLoqWQkMLMsq83J5lAX3LXjdkWdpscFy67JSOWDnh7Ny/sPFykmkg==",
"integrity": "ab2c55f902b380cf28e0eec501b4906e4c1960d13f00e11cfbcd21de15f18fed" "dependencies": [
} "@types/node",
"pg-protocol",
"pg-types@4.0.2"
]
}, },
"npm": { "kysely@0.27.4": {
"@types/node@18.16.19": { "integrity": "sha512-dyNKv2KRvYOQPLCAOCjjQuCk4YFd33BvGdf/o5bC7FiW+BB6snA81Zt+2wT9QDFzKqxKa5rrOmvlK/anehCcgA=="
"integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==", },
"dependencies": {} "obuf@1.1.2": {
}, "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg=="
"@types/pg@8.11.10": { },
"integrity": "sha512-LczQUW4dbOQzsH2RQ5qoeJ6qJPdrcM/DcMLoqWQkMLMsq83J5lAX3LXjdkWdpscFy67JSOWDnh7Ny/sPFykmkg==", "pg-cloudflare@1.1.1": {
"dependencies": { "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q=="
"@types/node": "@types/node@18.16.19", },
"pg-protocol": "pg-protocol@1.7.0", "pg-connection-string@2.7.0": {
"pg-types": "pg-types@4.0.2" "integrity": "sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA=="
} },
}, "pg-int8@1.0.1": {
"kysely@0.27.4": { "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="
"integrity": "sha512-dyNKv2KRvYOQPLCAOCjjQuCk4YFd33BvGdf/o5bC7FiW+BB6snA81Zt+2wT9QDFzKqxKa5rrOmvlK/anehCcgA==", },
"dependencies": {} "pg-numeric@1.0.2": {
}, "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw=="
"obuf@1.1.2": { },
"integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "pg-pool@3.7.0_pg@8.13.0": {
"dependencies": {} "integrity": "sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==",
}, "dependencies": [
"pg-cloudflare@1.1.1": { "pg"
"integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", ]
"dependencies": {} },
}, "pg-protocol@1.7.0": {
"pg-connection-string@2.7.0": { "integrity": "sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ=="
"integrity": "sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==", },
"dependencies": {} "pg-types@2.2.0": {
}, "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
"pg-int8@1.0.1": { "dependencies": [
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", "pg-int8",
"dependencies": {} "postgres-array@2.0.0",
}, "postgres-bytea@1.0.0",
"pg-numeric@1.0.2": { "postgres-date@1.0.7",
"integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", "postgres-interval@1.2.0"
"dependencies": {} ]
}, },
"pg-pool@3.7.0_pg@8.13.0": { "pg-types@4.0.2": {
"integrity": "sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==", "integrity": "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==",
"dependencies": { "dependencies": [
"pg": "pg@8.13.0" "pg-int8",
} "pg-numeric",
}, "postgres-array@3.0.2",
"pg-protocol@1.7.0": { "postgres-bytea@3.0.0",
"integrity": "sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==", "postgres-date@2.1.0",
"dependencies": {} "postgres-interval@3.0.0",
}, "postgres-range"
"pg-types@2.2.0": { ]
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", },
"dependencies": { "pg@8.13.0": {
"pg-int8": "pg-int8@1.0.1", "integrity": "sha512-34wkUTh3SxTClfoHB3pQ7bIMvw9dpFU1audQQeZG837fmHfHpr14n/AELVDoOYVDW2h5RDWU78tFjkD+erSBsw==",
"postgres-array": "postgres-array@2.0.0", "dependencies": [
"postgres-bytea": "postgres-bytea@1.0.0", "pg-cloudflare",
"postgres-date": "postgres-date@1.0.7", "pg-connection-string",
"postgres-interval": "postgres-interval@1.2.0" "pg-pool",
} "pg-protocol",
}, "pg-types@2.2.0",
"pg-types@4.0.2": { "pgpass"
"integrity": "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==", ]
"dependencies": { },
"pg-int8": "pg-int8@1.0.1", "pgpass@1.0.5": {
"pg-numeric": "pg-numeric@1.0.2", "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
"postgres-array": "postgres-array@3.0.2", "dependencies": [
"postgres-bytea": "postgres-bytea@3.0.0", "split2"
"postgres-date": "postgres-date@2.1.0", ]
"postgres-interval": "postgres-interval@3.0.0", },
"postgres-range": "postgres-range@1.1.4" "postgres-array@2.0.0": {
} "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="
}, },
"pg@8.13.0": { "postgres-array@3.0.2": {
"integrity": "sha512-34wkUTh3SxTClfoHB3pQ7bIMvw9dpFU1audQQeZG837fmHfHpr14n/AELVDoOYVDW2h5RDWU78tFjkD+erSBsw==", "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog=="
"dependencies": { },
"pg-cloudflare": "pg-cloudflare@1.1.1", "postgres-bytea@1.0.0": {
"pg-connection-string": "pg-connection-string@2.7.0", "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w=="
"pg-pool": "pg-pool@3.7.0_pg@8.13.0", },
"pg-protocol": "pg-protocol@1.7.0", "postgres-bytea@3.0.0": {
"pg-types": "pg-types@2.2.0", "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==",
"pgpass": "pgpass@1.0.5" "dependencies": [
} "obuf"
}, ]
"pgpass@1.0.5": { },
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", "postgres-date@1.0.7": {
"dependencies": { "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="
"split2": "split2@4.2.0" },
} "postgres-date@2.1.0": {
}, "integrity": "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA=="
"postgres-array@2.0.0": { },
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", "postgres-interval@1.2.0": {
"dependencies": {} "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
}, "dependencies": [
"postgres-array@3.0.2": { "xtend"
"integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", ]
"dependencies": {} },
}, "postgres-interval@3.0.0": {
"postgres-bytea@1.0.0": { "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw=="
"integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", },
"dependencies": {} "postgres-range@1.1.4": {
}, "integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w=="
"postgres-bytea@3.0.0": { },
"integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", "split2@4.2.0": {
"dependencies": { "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="
"obuf": "obuf@1.1.2" },
} "xtend@4.0.2": {
}, "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
"postgres-date@1.0.7": {
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
"dependencies": {}
},
"postgres-date@2.1.0": {
"integrity": "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==",
"dependencies": {}
},
"postgres-interval@1.2.0": {
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"dependencies": {
"xtend": "xtend@4.0.2"
}
},
"postgres-interval@3.0.0": {
"integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==",
"dependencies": {}
},
"postgres-range@1.1.4": {
"integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==",
"dependencies": {}
},
"split2@4.2.0": {
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
"dependencies": {}
},
"xtend@4.0.2": {
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"dependencies": {}
}
} }
}, },
"redirects": { "redirects": {
"https://deno.land/x/grammy/mod.ts": "https://deno.land/x/grammy@v1.30.0/mod.ts", "https://deno.land/x/grammy/mod.ts": "https://deno.land/x/grammy@v1.30.0/mod.ts",
"https://deno.land/x/grammy_types/inline.ts": "https://deno.land/x/grammy_types@v3.14.0/inline.ts",
"https://deno.land/x/grammy_types/manage.ts": "https://deno.land/x/grammy_types@v3.14.0/manage.ts" "https://deno.land/x/grammy_types/manage.ts": "https://deno.land/x/grammy_types@v3.14.0/manage.ts"
}, },
"remote": { "remote": {

View File

@ -1,7 +1,5 @@
import { ReqUrlBuilder } from "../utils/url_builder.ts"; import { ReqUrlBuilder } from "../utils/url_builder.ts";
export const DEFAULT_POSTS_LIMIT = 30
export const DEFAULT_START_PAGE_ID = 0
export const SAFEBOORU_HOST = "safebooru.org" export const SAFEBOORU_HOST = "safebooru.org"
export type GetSafebooruPostsFunc = (limit: number, pageId: number, tags: string[]) => Promise<SafebooruPostData[]> export type GetSafebooruPostsFunc = (limit: number, pageId: number, tags: string[]) => Promise<SafebooruPostData[]>