mirror of
https://github.com/System-End/hackatime.git
synced 2026-04-19 19:55:16 +00:00
Add physical mail model
This commit is contained in:
parent
4405b5bdcc
commit
55503499ff
5 changed files with 114 additions and 2 deletions
|
|
@ -56,4 +56,6 @@ GITHUB_CLIENT_SECRET=your_github_client_secret_here
|
|||
|
||||
SKYLIGHT_AUTHENTICATION=replace_me
|
||||
|
||||
IPINFO_API_KEY=replace_me
|
||||
IPINFO_API_KEY=replace_me
|
||||
|
||||
MAIL_HACKCLUB_TOKEN=replace_me
|
||||
38
app/jobs/check_streak_physical_mail_job.rb
Normal file
38
app/jobs/check_streak_physical_mail_job.rb
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
class CheckStreakPhysicalMailJob < ApplicationJob
|
||||
queue_as :literally_whenever
|
||||
|
||||
include GoodJob::ActiveJobExtensions::Concurrency
|
||||
|
||||
good_job_control_concurrency_with(
|
||||
total_limit: 1,
|
||||
key: -> { "check_streak_physical_mail_job" },
|
||||
drop: true
|
||||
)
|
||||
|
||||
def perform
|
||||
streaks = Heartbeat.daily_streaks_for_users(users_with_recent_heartbeats)
|
||||
|
||||
over_7_day_streaks = streaks.select { |_, streak| streak > 7 }.keys
|
||||
|
||||
over_7_day_streaks.each do |user_id|
|
||||
next if PhysicalMail.going_out.exists?(user_id: user_id, mission_type: :first_streak)
|
||||
|
||||
user = User.find(user_id)
|
||||
|
||||
# Create the physical mail record
|
||||
PhysicalMail.create!(
|
||||
user: user,
|
||||
mission_type: :first_streak,
|
||||
status: :pending
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def users_with_recent_heartbeats
|
||||
Heartbeat.where(time: 1.hour.ago..Time.current)
|
||||
.distinct
|
||||
.pluck(:user_id)
|
||||
end
|
||||
end
|
||||
49
app/models/physical_mail.rb
Normal file
49
app/models/physical_mail.rb
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
class PhysicalMail < ApplicationRecord
|
||||
belongs_to :user
|
||||
|
||||
scope :going_out, -> { where(status: :pending).or(where(status: :sent)) }
|
||||
|
||||
enum :status, {
|
||||
pending: 0,
|
||||
sent: 1,
|
||||
failed: 2
|
||||
}
|
||||
|
||||
enum :mission_type, {
|
||||
hackatime_first_time_7_streak: 0
|
||||
}
|
||||
|
||||
def deliver!
|
||||
slug = "hackatime_#{mission_type.to_s.underscore.gsub("_", "-")}"
|
||||
|
||||
flavors = FlavorText.compliment
|
||||
flavors.concat(FlavorText.rare_compliment) if rand(10) == 0
|
||||
|
||||
# authorization: Bearer <token>
|
||||
response = HTTP.auth("Bearer #{ENV["MAIL_HACKCLUB_TOKEN"]}").post("https://mail.hackclub.com/api/v1/letter_queues/#{slug}", json: {
|
||||
recipient_email: user.email,
|
||||
address: user_address,
|
||||
rubber_stamps: flavors.sample,
|
||||
idempotency_key: "physical_mail_#{id}",
|
||||
metadata: {
|
||||
attributes: attributes
|
||||
}
|
||||
})
|
||||
|
||||
if response.status.success?
|
||||
update(status: :sent)
|
||||
else
|
||||
update(status: :failed)
|
||||
raise "Failed to deliver physical mail: #{response.body}"
|
||||
end
|
||||
rescue => e
|
||||
update(status: :failed)
|
||||
raise e
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_address
|
||||
user.address
|
||||
end
|
||||
end
|
||||
12
db/migrate/20250514150404_create_physical_mails.rb
Normal file
12
db/migrate/20250514150404_create_physical_mails.rb
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
class CreatePhysicalMails < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
create_table :physical_mails do |t|
|
||||
t.references :user, null: false, foreign_key: true
|
||||
t.integer :mission_type, null: false
|
||||
t.integer :status, null: false, default: 0
|
||||
t.string :theseus_id
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
13
db/schema.rb
generated
13
db/schema.rb
generated
|
|
@ -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_05_13_184040) do
|
||||
ActiveRecord::Schema[8.0].define(version: 2025_05_14_150404) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pg_catalog.plpgsql"
|
||||
|
||||
|
|
@ -253,6 +253,16 @@ ActiveRecord::Schema[8.0].define(version: 2025_05_13_184040) do
|
|||
t.index ["user_id"], name: "index_mailing_addresses_on_user_id"
|
||||
end
|
||||
|
||||
create_table "physical_mails", force: :cascade do |t|
|
||||
t.bigint "user_id", null: false
|
||||
t.integer "mission_type", null: false
|
||||
t.integer "status", default: 0, null: false
|
||||
t.string "theseus_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["user_id"], name: "index_physical_mails_on_user_id"
|
||||
end
|
||||
|
||||
create_table "project_repo_mappings", force: :cascade do |t|
|
||||
t.bigint "user_id", null: false
|
||||
t.string "project_name", null: false
|
||||
|
|
@ -372,6 +382,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_05_13_184040) do
|
|||
add_foreign_key "leaderboard_entries", "leaderboards"
|
||||
add_foreign_key "leaderboard_entries", "users"
|
||||
add_foreign_key "mailing_addresses", "users"
|
||||
add_foreign_key "physical_mails", "users"
|
||||
add_foreign_key "project_repo_mappings", "users"
|
||||
add_foreign_key "sign_in_tokens", "users"
|
||||
add_foreign_key "wakatime_mirrors", "users"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue