diff --git a/app/jobs/one_time/set_user_timezone_from_slack_job.rb b/app/jobs/one_time/set_user_timezone_from_slack_job.rb new file mode 100644 index 0000000..5a2fb71 --- /dev/null +++ b/app/jobs/one_time/set_user_timezone_from_slack_job.rb @@ -0,0 +1,32 @@ +class OneTime::SetUserTimezoneFromSlackJob < ApplicationJob + queue_as :default + + def perform + User.where.not(slack_uid: nil).find_each(batch_size: 100) do |user| + begin + user_response = HTTP.auth("Bearer #{user.slack_access_token}") + .get("https://slack.com/api/users.info?user=#{user.slack_uid}") + + user_data = JSON.parse(user_response.body.to_s) + + next unless user_data["ok"] + + timezone = user_data.dig("user", "tz") + next unless timezone.present? + + # Convert IANA timezone to ActiveSupport timezone + begin + tz = ActiveSupport::TimeZone.find_tzinfo(timezone) + user.update!( + timezone: tz.name, + ) + Rails.logger.info "Updated timezone for user #{user.id} to #{tz.name}" + rescue TZInfo::InvalidTimezoneIdentifier => e + Rails.logger.error "Invalid timezone #{timezone} for user #{user.id}: #{e.message}" + end + rescue => e + Rails.logger.error "Failed to update timezone for user #{user.id}: #{e.message}" + end + end + end +end diff --git a/db/migrate/20250319142656_add_timezone_to_users.rb b/db/migrate/20250319142656_add_timezone_to_users.rb new file mode 100644 index 0000000..ee4cce1 --- /dev/null +++ b/db/migrate/20250319142656_add_timezone_to_users.rb @@ -0,0 +1,6 @@ +class AddTimezoneToUsers < ActiveRecord::Migration[8.0] + def change + add_column :users, :timezone, :string, default: "UTC" + add_index :users, :timezone + end +end diff --git a/db/schema.rb b/db/schema.rb index ce79b65..ee3bb20 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_03_15_030446) do +ActiveRecord::Schema[8.0].define(version: 2025_03_19_142656) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" @@ -150,6 +150,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_03_15_030446) do t.text "fields_hash" t.integer "source_type", null: false t.inet "ip_address" + t.index ["category", "time"], name: "index_heartbeats_on_category_and_time" t.index ["fields_hash"], name: "index_heartbeats_on_fields_hash", unique: true t.index ["user_id"], name: "index_heartbeats_on_user_id" end @@ -242,7 +243,9 @@ ActiveRecord::Schema[8.0].define(version: 2025_03_15_030446) do t.string "slack_scopes", default: [], array: true t.text "slack_access_token" t.integer "hackatime_extension_text_type", default: 0, null: false + t.string "timezone", default: "UTC" t.index ["slack_uid"], name: "index_users_on_slack_uid", unique: true + t.index ["timezone"], name: "index_users_on_timezone" end create_table "versions", force: :cascade do |t|