From d9450fde4a0a5946d8a5db2bc373137427fc7dc1 Mon Sep 17 00:00:00 2001 From: Muhsin Keloth Date: Wed, 26 Mar 2025 11:12:32 +0530 Subject: [PATCH] feat: Added Instagram channel migration (#11181) This PR is part of https://github.com/chatwoot/chatwoot/pull/11054 to make the review cycle easier. --- app/models/account.rb | 1 + app/models/channel/instagram.rb | 28 +++++++++++++++++++ .../20250326034635_add_instagram_channel.rb | 13 +++++++++ db/schema.rb | 12 +++++++- spec/factories/channel/channel_instagram.rb | 13 +++++++++ spec/models/channel/instagram_spec.rb | 17 +++++++++++ 6 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 app/models/channel/instagram.rb create mode 100644 db/migrate/20250326034635_add_instagram_channel.rb create mode 100644 spec/factories/channel/channel_instagram.rb create mode 100644 spec/models/channel/instagram_spec.rb diff --git a/app/models/account.rb b/app/models/account.rb index e6216873c..eb95194c5 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -56,6 +56,7 @@ class Account < ApplicationRecord has_many :data_imports, dependent: :destroy_async has_many :email_channels, dependent: :destroy_async, class_name: '::Channel::Email' has_many :facebook_pages, dependent: :destroy_async, class_name: '::Channel::FacebookPage' + has_many :instagram_channels, dependent: :destroy_async, class_name: '::Channel::Instagram' has_many :hooks, dependent: :destroy_async, class_name: 'Integrations::Hook' has_many :inboxes, dependent: :destroy_async has_many :labels, dependent: :destroy_async diff --git a/app/models/channel/instagram.rb b/app/models/channel/instagram.rb new file mode 100644 index 000000000..fcfcb852e --- /dev/null +++ b/app/models/channel/instagram.rb @@ -0,0 +1,28 @@ +# == Schema Information +# +# Table name: channel_instagram +# +# id :bigint not null, primary key +# access_token :string not null +# expires_at :datetime not null +# created_at :datetime not null +# updated_at :datetime not null +# account_id :integer not null +# instagram_id :string not null +# +# Indexes +# +# index_channel_instagram_on_instagram_id (instagram_id) UNIQUE +# +class Channel::Instagram < ApplicationRecord + include Channelable + + self.table_name = 'channel_instagram' + + validates :access_token, presence: true + validates :instagram_id, uniqueness: true, presence: true + + def name + 'Instagram' + end +end diff --git a/db/migrate/20250326034635_add_instagram_channel.rb b/db/migrate/20250326034635_add_instagram_channel.rb new file mode 100644 index 000000000..6882caf6a --- /dev/null +++ b/db/migrate/20250326034635_add_instagram_channel.rb @@ -0,0 +1,13 @@ +class AddInstagramChannel < ActiveRecord::Migration[7.0] + def change + create_table :channel_instagram do |t| + t.string :access_token, null: false + t.datetime :expires_at, null: false + t.integer :account_id, null: false + t.string :instagram_id, null: false + t.timestamps + end + + add_index :channel_instagram, :instagram_id, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 0818d1117..1f7217cd8 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[7.0].define(version: 2025_03_15_202035) do +ActiveRecord::Schema[7.0].define(version: 2025_03_26_034635) do # These extensions should be enabled to support this database enable_extension "pg_stat_statements" enable_extension "pg_trgm" @@ -377,6 +377,16 @@ ActiveRecord::Schema[7.0].define(version: 2025_03_15_202035) do t.index ["page_id"], name: "index_channel_facebook_pages_on_page_id" end + create_table "channel_instagram", force: :cascade do |t| + t.string "access_token", null: false + t.datetime "expires_at", null: false + t.integer "account_id", null: false + t.string "instagram_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["instagram_id"], name: "index_channel_instagram_on_instagram_id", unique: true + end + create_table "channel_line", force: :cascade do |t| t.integer "account_id", null: false t.string "line_channel_id", null: false diff --git a/spec/factories/channel/channel_instagram.rb b/spec/factories/channel/channel_instagram.rb new file mode 100644 index 000000000..9a0d33bb5 --- /dev/null +++ b/spec/factories/channel/channel_instagram.rb @@ -0,0 +1,13 @@ +FactoryBot.define do + factory :channel_instagram, class: 'Channel::Instagram' do + account + access_token { SecureRandom.hex(32) } + instagram_id { SecureRandom.hex(16) } + expires_at { 60.days.from_now } + updated_at { 25.hours.ago } + + after(:create) do |channel| + create(:inbox, channel: channel, account: channel.account) + end + end +end diff --git a/spec/models/channel/instagram_spec.rb b/spec/models/channel/instagram_spec.rb new file mode 100644 index 000000000..901fe392e --- /dev/null +++ b/spec/models/channel/instagram_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Channel::Instagram do + let(:channel) { create(:channel_instagram) } + + it { is_expected.to validate_presence_of(:account_id) } + it { is_expected.to validate_presence_of(:access_token) } + it { is_expected.to validate_presence_of(:instagram_id) } + it { is_expected.to belong_to(:account) } + it { is_expected.to have_one(:inbox).dependent(:destroy_async) } + + it 'has a valid name' do + expect(channel.name).to eq('Instagram') + end +end