feat: supported database sqlite and hashing userid

This commit is contained in:
Konrad Geletey 2024-10-20 18:42:00 +03:00
parent d1d0292045
commit 6a52f64753
Signed by: kglt
GPG key ID: 386DEE24B60BD996
7 changed files with 106 additions and 12 deletions

2
.swiftlint.yml Normal file
View file

@ -0,0 +1,2 @@
identifier_name:
min_length: 1

View file

@ -1,5 +1,5 @@
{ {
"originHash" : "5b140fcd6a36165fb4c1302609ef5353bacb59ce0f82996aa0cf66ee021cbb17", "originHash" : "3b48af7783bd7fc90049cfb326f7fac3c85fa65bc3afc5b3c1e0444e5e3fe3ac",
"pins" : [ "pins" : [
{ {
"identity" : "async-http-client", "identity" : "async-http-client",
@ -28,6 +28,15 @@
"version" : "4.15.0" "version" : "4.15.0"
} }
}, },
{
"identity" : "grdb.swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/groue/GRDB.swift.git",
"state" : {
"revision" : "2cf6c756e1e5ef6901ebae16576a7e4e4b834622",
"version" : "6.29.3"
}
},
{ {
"identity" : "multipart-kit", "identity" : "multipart-kit",
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",

View file

@ -4,16 +4,19 @@
import PackageDescription import PackageDescription
var packageDependencies: [Package.Dependency] = [ var packageDependencies: [Package.Dependency] = [
.package(url: "https://github.com/vapor/vapor.git", .upToNextMajor(from: "4.57.0")) .package(url: "https://github.com/nerzh/swift-telegram-sdk", .upToNextMajor(from: "3.0.3")),
.package(url: "https://github.com/vapor/vapor.git", .upToNextMajor(from: "4.57.0")),
.package(url: "https://github.com/apple/swift-crypto.git", .upToNextMajor(from: "3.0.0")),
.package(url: "https://github.com/groue/GRDB.swift.git", .upToNextMajor(from: "6.0.0"))
] ]
var targetDependencies: [PackageDescription.Target.Dependency] = [ var targetDependencies: [PackageDescription.Target.Dependency] = [
.product(name: "Vapor", package: "vapor") .product(name: "Vapor", package: "vapor"),
.product(name: "SwiftTelegramSdk", package: "swift-telegram-sdk"),
.product(name: "Crypto", package: "swift-crypto"),
.product(name: "GRDB", package: "GRDB.swift")
] ]
packageDependencies.append(.package(url: "https://github.com/nerzh/swift-telegram-sdk", .upToNextMajor(from: "3.0.3")))
targetDependencies.append(.product(name: "SwiftTelegramSdk", package: "swift-telegram-sdk"))
let package = Package( let package = Package(
name: "TelegramModeratorBot", name: "TelegramModeratorBot",
dependencies: packageDependencies, dependencies: packageDependencies,

View file

@ -0,0 +1,53 @@
import GRDB
struct User: Codable, FetchableRecord, PersistableRecord {
var userId: String
var publicKey: String
var isSpammer: Bool
}
final class Database: Sendable {
private var dbWriter: any DatabaseWriter
init(_ dbWriter: any GRDB.DatabaseWriter) throws {
self.dbWriter = dbWriter
try migrator.migrate(dbWriter)
}
let dbQueue = try DatabaseQueue(path: "./db.sqlite")
let db = try Connection("./db.sqlite")
#if DEBUG
// Speed up development by nuking the database when migrations change
// See <https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/migrations#The-eraseDatabaseOnSchemaChange-Option>
migrator.eraseDatabaseOnSchemaChange = true
#endif
private var migrator: DatabaseMigrator {
var migrator = DatabaseMigrator()
migrator.registerMigration("v1") { db in
try db.create(table: "users", { t in
t.primaryKey("userId", .text).NotNull()
t.column("publicKey", .text).NotNull()
t.column("isSpammer", .bool)
})
return migrator
}
}
}
extension Database {
static func makeConfiguration(_ base: Configuration = Configuration()) -> Configuration {
var config = base
return config
}
}
extension Database {
func saveUser(_ userId: String, _ publicKey: String, _ isSpammer: Bool) throws {
try dbWriter.write { db in
try User.init(userId: userId, publicKey: publicKey, isSpammer: isSpammer).insert(db)
}
}
}

View file

@ -1,18 +1,42 @@
import Vapor import Vapor
import Crypto
@preconcurrency import SwiftTelegramSdk @preconcurrency import SwiftTelegramSdk
final class DefaultBotHandlers { final class DefaultBotHandlers {
static func addHandlers() async { static func addHandlers(_ bot: TGBot) async {
await defaultBaseHandler() await defaultBaseHandler(bot)
} }
private static func defaultBaseHandler() async { private static func defaultBaseHandler(_ bot: TGBot) async {
await botActor.bot.dispatcher.add(TGBaseHandler({ update in await botActor.bot.dispatcher.add(TGBaseHandler({ update in
guard let message = update.message else { return } guard let message = update.message else { return }
let params: TGSendMessageParams = .init(chatId: .chat(message.chat.id), text: """ let params: TGSendMessageParams = .init(chatId: .chat(message.chat.id), text: """
Help message Help message
""") """)
try await botActor.bot.sendMessage(params: params) try await bot.sendMessage(params: params)
})) }))
} }
private static func sendButtonOfAuth(_ bot: TGBot) async throws {
await bot.dispatcher.add(TGCallbackQueryHandler(pattern: "Subscribe", { update in
bot.log.info("press")
let userId = update.callbackQuery!.from.id
let arrayBytesOfId = withUnsafeBytes(of: userId, Array.init)
let hashedUserIdDigest = SHA512.hash(Data(arrayBytesOfId))
// Convert Digest to hex string
let hashedUserId = Data(hashedUserIdDigest).map { String(format: "%02x", $0) }.joined()
try? Database.saveUser(hashedUserId, "", false)
let params: TGAnswerCallbackQueryParams = .init(
callbackQueryId: update.callbackQuery?.id ?? "0",
text: update.callbackQuery?.data ?? "data not exit",
showAlert: nil,
url: nil,
cacheTime: nil
)
try await bot.answerCallbackQuery(params: params)
}))
}
} }

View file

@ -3,7 +3,9 @@ import Vapor
@preconcurrency import SwiftTelegramSdk @preconcurrency import SwiftTelegramSdk
public func configure(_ app: Application) async throws { public func configure(_ app: Application) async throws {
guard let tgApi: String = Environment.get("TG_BOT_API") else { throw Errors.notVariable("Telegram key is not defined")} guard let tgApi: String = Environment.get("TG_BOT_API") else {
throw Errors.notVariable("Telegram key is not defined")
}
app.logger.logLevel = .debug app.logger.logLevel = .debug
let bot: TGBot = try await .init(connectionType: .longpolling(limit: nil, let bot: TGBot = try await .init(connectionType: .longpolling(limit: nil,
timeout: nil, timeout: nil,
@ -14,7 +16,7 @@ public func configure(_ app: Application) async throws {
botId: tgApi, botId: tgApi,
log: app.logger) log: app.logger)
await botActor.setBot(bot) await botActor.setBot(bot)
await DefaultBotHandlers.addHandlers() await DefaultBotHandlers.addHandlers(bot)
try await botActor.bot.start() try await botActor.bot.start()
// try routes(app) // try routes(app)
} }

View file

@ -1,3 +1,4 @@
enum Errors: Error { enum Errors: Error {
case notVariable(String) case notVariable(String)
case `default`(String)
} }