-
-
Notifications
You must be signed in to change notification settings - Fork 442
Feature/autoreply modes #87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 11 commits
4ae3f53
83015fc
2994d3a
fa0a96c
291892c
4935c8a
ab23e53
b945ed9
7c6f1de
a396f37
f0d20e0
0fcf450
524269b
226c815
b07092d
b1a9405
9b01d1e
8ce1e48
4b404b3
a56416a
315b617
a63eaef
a8cb87a
ea9e125
cf13b53
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| #!/bin/bash | ||
|
|
||
| # Script to create a user via curl | ||
|
|
||
| # Validate the number of arguments | ||
| if [ "$#" -ne 3 ]; then | ||
| echo "Usage: $0 <adminpass> <username> <passwd>" | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Assign arguments to variables | ||
| ADMIN_PASS="$1" | ||
| USERNAME="$2" | ||
| USER_PASSWD="$3" | ||
|
|
||
| # Execute the curl command | ||
| curl -X POST http://localhost:8089/admin/users \ | ||
| -H "Authorization: ${ADMIN_PASS}" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d "{\"name\": \"${USERNAME}\", \"token\": \"${USER_PASSWD}\"}" | ||
|
|
||
| echo # Add a newline for cleaner output |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,9 +24,101 @@ func InitializeDatabase(exPath string) (*sqlx.DB, error) { | |
| config := getDatabaseConfig(exPath) | ||
|
|
||
| if config.Type == "postgres" { | ||
| return initializePostgres(config) | ||
| db, err := initializePostgres(config) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| // Create tables for postgres | ||
| if err := createTables(db, "postgres"); err != nil { | ||
| return nil, fmt.Errorf("failed to create tables for postgres: %w", err) | ||
| } | ||
| return db, nil | ||
| } | ||
|
|
||
| // Default to SQLite | ||
| db, err := initializeSQLite(config) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| return initializeSQLite(config) | ||
| // Create tables for sqlite | ||
| if err := createTables(db, "sqlite"); err != nil { | ||
| return nil, fmt.Errorf("failed to create tables for sqlite: %w", err) | ||
| } | ||
| return db, nil | ||
| } | ||
|
|
||
| func createTables(db *sqlx.DB, dbType string) error { | ||
| // SQL for creating autoreply_modes table | ||
| autoreplyModesTableSQL := ` | ||
| CREATE TABLE IF NOT EXISTS autoreply_modes ( | ||
| user_id TEXT NOT NULL, | ||
| mode_name TEXT NOT NULL, | ||
| phone_number TEXT NOT NULL, | ||
| message TEXT NOT NULL, | ||
| UNIQUE (user_id, mode_name, phone_number) | ||
| );` | ||
|
|
||
| // SQL for creating active_mode table | ||
| activeModeTableSQL := ` | ||
| CREATE TABLE IF NOT EXISTS active_mode ( | ||
| user_id TEXT PRIMARY KEY NOT NULL, | ||
| current_mode_name TEXT NULLABLE | ||
| );` | ||
|
|
||
| // Execute table creation statements | ||
| if _, err := db.Exec(autoreplyModesTableSQL); err != nil { | ||
| return fmt.Errorf("failed to create autoreply_modes table: %w", err) | ||
| } | ||
| if _, err := db.Exec(activeModeTableSQL); err != nil { | ||
| return fmt.Errorf("failed to create active_mode table: %w", err) | ||
| } | ||
|
|
||
| // No initial data for active_mode as it's user-specific and populated on demand. | ||
|
|
||
| // Alter users table to add google_contacts_auth_token column | ||
| alterUsersTableSQL := "" | ||
| if dbType == "postgres" { | ||
| alterUsersTableSQL = `ALTER TABLE users ADD COLUMN IF NOT EXISTS google_contacts_auth_token TEXT;` | ||
| } else { // sqlite | ||
| // Check if column exists first for older SQLite versions. | ||
| // For newer SQLite (3.16.0+), ADD COLUMN is idempotent if the column exists. | ||
| // However, to be safe and support potentially older versions, we can check. | ||
| // A simpler approach for tests or if newer SQLite is guaranteed is just: | ||
| // alterUsersTableSQL = `ALTER TABLE users ADD COLUMN google_contacts_auth_token TEXT;` | ||
| // For robustness in a production-like environment, checking PRAGMA is better. | ||
|
|
||
| // Let's use the simpler ALTER TABLE for now, assuming modern SQLite. | ||
| // If this causes issues, a PRAGMA check can be added. | ||
| alterUsersTableSQL = `ALTER TABLE users ADD COLUMN google_contacts_auth_token TEXT;` | ||
|
|
||
| // Check if column exists to avoid error on re-run with older SQLite | ||
| var columnName string | ||
| query := "SELECT name FROM pragma_table_info('users') WHERE name = 'google_contacts_auth_token';" | ||
| err := db.Get(&columnName, query) | ||
| if err == nil && columnName == "google_contacts_auth_token" { | ||
| // Column already exists, no need to alter | ||
| alterUsersTableSQL = "" | ||
| } else if err != nil && err.Error() != "sql: no rows in result set" { | ||
| // An actual error occurred querying pragma_table_info | ||
| return fmt.Errorf("failed to check users table schema: %w", err) | ||
| } | ||
| // If err is "sql: no rows in result set", column doesn't exist, proceed with ALTER. | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current logic for adding the If the column already exists and you're using an older SQLite version that doesn't make Would you consider restructuring this to check for the column's existence with For example, the logic could be: alterUsersTableSQL := ""
if dbType == "postgres" {
alterUsersTableSQL = `ALTER TABLE users ADD COLUMN IF NOT EXISTS google_contacts_auth_token TEXT;`
} else { // sqlite
var columnName string
query := "SELECT name FROM pragma_table_info('users') WHERE name = 'google_contacts_auth_token';"
err := db.Get(&columnName, query)
// If err is sql.ErrNoRows, column doesn't exist. If err is nil and columnName matches, it exists.
if err == sql.ErrNoRows || (err == nil && columnName != "google_contacts_auth_token") {
// Column does not exist, or a different error occurred during the check (which is handled if err != sql.ErrNoRows below)
alterUsersTableSQL = `ALTER TABLE users ADD COLUMN google_contacts_auth_token TEXT;`
} else if err != nil && err.Error() != "sql: no rows in result set" {
// An actual error occurred querying pragma_table_info, not just 'no rows'
return fmt.Errorf("failed to check users table schema: %w", err)
}
// If err is nil and columnName matched, column exists, alterUsersTableSQL remains ""
}
if alterUsersTableSQL != "" {
if _, err := db.Exec(alterUsersTableSQL); err != nil {
// Handle potential errors, e.g., if SQLite version is very old and ADD COLUMN still fails
// The specific "duplicate column name" check might still be a fallback if needed,
// but the pre-check should reduce its necessity.
if !(dbType == "sqlite" && strings.Contains(err.Error(), "duplicate column name")) {
return fmt.Errorf("failed to alter users table to add google_contacts_auth_token: %w", err)
}
}
} |
||
|
|
||
| if alterUsersTableSQL != "" { | ||
| if _, err := db.Exec(alterUsersTableSQL); err != nil { | ||
| // For SQLite, if the column already exists, this might return an error "duplicate column name" | ||
| // We'll log it and continue if it's that specific error for SQLite. | ||
| if dbType == "sqlite" && strings.Contains(err.Error(), "duplicate column name") { | ||
| // log.Warn().Msg("Column google_contacts_auth_token already exists in users table (SQLite).") | ||
| } else { | ||
| return fmt.Errorf("failed to alter users table to add google_contacts_auth_token: %w", err) | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func getDatabaseConfig(exPath string) DatabaseConfig { | ||
|
|
@@ -70,7 +162,6 @@ func initializePostgres(config DatabaseConfig) (*sqlx.DB, error) { | |
| if err := db.Ping(); err != nil { | ||
| return nil, fmt.Errorf("failed to ping postgres database: %w", err) | ||
| } | ||
|
|
||
| return db, nil | ||
| } | ||
|
|
||
|
|
@@ -89,6 +180,5 @@ func initializeSQLite(config DatabaseConfig) (*sqlx.DB, error) { | |
| if err := db.Ping(); err != nil { | ||
| return nil, fmt.Errorf("failed to ping sqlite database: %w", err) | ||
| } | ||
|
|
||
| return db, nil | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description for
Add/Update Auto-Reply(line 711) states, "If an auto-reply for the given phone number already exists for the user, it will be updated." However, the409 Conflictresponse (line 733) is documented for the case "If an auto-reply for this phone number already exists for the user."This seems contradictory. The current handler implementation (
handlers.go:AddAutoReply) also reflects an "add-only" behavior, returning a409 Conflictif the entry exists, rather than updating it.Could you clarify the intended behavior?
409 Conflictis appropriate.handlers.gowould need to be changed (e.g., usingON CONFLICT DO UPDATEfor PostgreSQL andINSERT OR REPLACEor equivalent for SQLite), and the success status code might need adjustment (e.g.,200 OKfor update,201 Createdfor new).