Skip to content

Instantly share code, notes, and snippets.

@atomkirk
Created November 15, 2025 02:55
Show Gist options
  • Select an option

  • Save atomkirk/9ca4b78cc30cedd6c55f9a086ab22b25 to your computer and use it in GitHub Desktop.

Select an option

Save atomkirk/9ca4b78cc30cedd6c55f9a086ab22b25 to your computer and use it in GitHub Desktop.
defmodule Integrator.Scheduler do
use Oban.Worker, queue: :events, max_attempts: 5
require Logger
import Ecto.Query
require Logger
alias Integrator.Intercom
alias Integrator.Notion
alias Integrator.UserMatcher
alias Integrator.Slack
alias Integrator.TicketGenerator
alias Integrator.Slugify
alias Integrator.TicketMatcher
alias Integrator.SlackChannel
alias Integrator.Tickets
alias Phoenix.PubSub
alias Integrator.Scheduler
alias Oban.Job
def schedule_next_task(args) do
args
|> Oban.Job.new(worker: __MODULE__, schedule_in: 5)
|> Oban.insert()
end
@impl Oban.Worker
def perform(
%Oban.Job{
args: %{
"task" => "fetch_intercom_conversations",
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Intercom.get_texts(conversation_id, intercom_token) do
{:ok, texts} ->
Logger.info("Fetched texts for conversation #{conversation_id}")
schedule_next_task(%{
"task" => "fetch_slack_messages",
"conversations" => texts,
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to fetch texts for conversation #{conversation_id}")
{:snooze, 5}
end
end
def perform(
%Oban.Job{
args: %{
"task" => "fetch_slack_messages",
"conversations" => conversations,
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Notion.get_all(notion_token, notion_database_id) do
{:ok, %{tickets: tickets_in_notion, has_more: _has_more}} ->
Logger.info("Fetched tickets from Notion")
schedule_next_task(%{
"task" => "fetch_notion_tickets",
"conversations" => conversations,
"tickets_in_notion" => tickets_in_notion,
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to fetch tickets from Notion")
{:snooze, 5}
end
end
def perform(
%Oban.Job{
args: %{
"task" => "fetch_notion_tickets",
"conversations" => conversations,
"tickets_in_notion" => tickets_in_notion,
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Slack.get_all_channels(slack_token) do
{:ok, channels} ->
Logger.info("Fetched channels from Slack")
Scheduler.schedule_next_task(%{
"task" => "find_matching_tickets",
"conversations" => conversations,
"tickets_in_notion" => tickets_in_notion,
"slack_channels" => channels,
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to fetch channels from Slack")
{:snooze, 5}
end
end
def perform(
%Oban.Job{
args: %{
"task" => "find_matching_tickets",
"conversations" => conversations,
"tickets_in_notion" => tickets_in_notion,
"slack_channels" => slack_channels,
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case IO.inspect(
TicketMatcher.find_matching_ticket(conversations, tickets_in_notion, slack_channels)
) do
{:ok, %{ticket: nil, channel: nil}} ->
Logger.info("Matched tickets no ticket or channel")
Scheduler.schedule_next_task(%{
"task" => "create_notion_ticket_and_slack_channel",
"conversations" => conversations,
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
{:ok, %{ticket: ticket, channel: nil}} ->
Logger.info("Matched tickets with ticket")
Scheduler.schedule_next_task(%{
"task" => "create_channel_and_update_ticket",
"conversations" => conversations,
"conversation_id" => conversation_id,
"ticket" => ticket,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
{:ok, %{ticket: nil, channel: channel}} ->
Logger.info("Matched tickets with channel")
Scheduler.schedule_next_task(%{
"task" => "create_ticket_and_update_channel",
"conversations" => conversations,
"conversation_id" => conversation_id,
"channel" => channel,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
{:ok, %{ticket: ticket, channel: channel}} ->
Logger.info("Matched tickets with channel and ticket")
Scheduler.schedule_next_task(%{
"task" => "update_ticket_and_channel",
"conversations" => conversations,
"conversation_id" => conversation_id,
"channel" => channel,
"ticket" => ticket,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
{:error, "No content was found in the conversation."} ->
:ok
_ ->
Logger.error("Failed to match tickets")
{:snooze, 5}
end
end
## FIRST ACTION
def perform(
%Oban.Job{
args: %{
"task" => "create_notion_ticket_and_slack_channel",
"conversations" => conversations,
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case TicketGenerator.generate_ticket_info(conversations) do
{:ok, ticket_info} ->
Logger.info("Generated ticket info")
schedule_next_task(%{
"task" => "create_notion_ticket_and_slack_channel_task_get_conversation_url",
"ticket_info" => ticket_info,
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to generate ticket info")
{:snooze, 5}
end
end
# New separate function to get the conversation URL
def perform(
%Oban.Job{
args: %{
"task" => "create_notion_ticket_and_slack_channel_task_get_conversation_url",
"ticket_info" => ticket_info,
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Intercom.get_conversation_url(conversation_id, intercom_token) do
{:ok, conversation_url} ->
Logger.info("Retrieved Intercom conversation URL")
schedule_next_task(%{
"task" => "create_notion_ticket_and_slack_channel_task_create_notion_ticket",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to retrieve Intercom conversation URL")
{:snooze, 5}
end
end
def perform(
%Oban.Job{
args: %{
"task" => "create_notion_ticket_and_slack_channel_task_create_notion_ticket",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Notion.create_ticket(
ticket_info["title"],
ticket_info["summary"],
conversation_url,
notion_token,
notion_database_id
) do
{:ok, body} ->
notion_url = body["url"]
notion_page_id = body["id"]
id_with_jmp =
body["properties"]["ID"]["unique_id"]["prefix"] <>
"-" <>
Integer.to_string(body["properties"]["ID"]["unique_id"]["number"])
slug_for_title = Slugify.make_slug(ticket_info["title"])
title_for_slack = id_with_jmp <> "-" <> slug_for_title
schedule_next_task(%{
"task" => "create_notion_ticket_and_slack_channel_task_create_slack_channel",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"id_with_jmp" => id_with_jmp,
"title_for_slack" => title_for_slack,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
Logger.info("Ticket created in Notion")
:ok
_ ->
Logger.error("Failed to create ticket in Notion")
{:snooze, 5}
end
end
def perform(
%Oban.Job{
args: %{
"task" => "create_notion_ticket_and_slack_channel_task_create_slack_channel",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"id_with_jmp" => id_with_jmp,
"title_for_slack" => title_for_slack,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Slack.create_project_channel(title_for_slack, notion_url, slack_token) do
{:ok, channel_id, channel_url} ->
Logger.info("Channel created in Slack")
schedule_next_task(%{
"task" => "create_notion_ticket_and_slack_channel_task_fetch_intercom_admins",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"id_with_jmp" => id_with_jmp,
"title_for_slack" => title_for_slack,
"slack_channel_id" => channel_id,
"slack_channel_url" => channel_url,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
{:error, "name_taken"} ->
schedule_next_task(%{
"task" => "create_notion_ticket_and_slack_channel_task_create_slack_channel",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"id_with_jmp" => id_with_jmp,
"title_for_slack" => title_for_slack <> "New",
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to create channel in Slack")
{:snooze, 5}
end
end
def perform(
%Oban.Job{
args: %{
"task" => "create_notion_ticket_and_slack_channel_task_fetch_intercom_admins",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"id_with_jmp" => id_with_jmp,
"title_for_slack" => title_for_slack,
"slack_channel_id" => channel_id,
"slack_channel_url" => channel_url,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Intercom.get_conversation_admins(conversation_id, intercom_token) do
{:ok, intercom_admins} ->
Logger.info("Fetched admins from Intercom")
schedule_next_task(%{
"task" => "create_notion_ticket_and_slack_channel_task_fetch_slack_users",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"id_with_jmp" => id_with_jmp,
"title_for_slack" => title_for_slack,
"slack_channel_id" => channel_id,
"slack_channel_url" => channel_url,
"intercom_admins" => intercom_admins,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to fetch admins from Intercom")
{:snooze, 5}
end
end
def perform(
%Oban.Job{
args: %{
"task" => "create_notion_ticket_and_slack_channel_task_fetch_slack_users",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"id_with_jmp" => id_with_jmp,
"title_for_slack" => title_for_slack,
"slack_channel_id" => channel_id,
"slack_channel_url" => channel_url,
"intercom_admins" => intercom_admins,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Slack.get_users(slack_token) do
{:ok, slack_users} ->
{_status, best_matches} =
UserMatcher.get_best_matches_for_adding_to_slack(intercom_admins, slack_users)
schedule_next_task(%{
"task" => "create_notion_ticket_and_slack_channel_task_create_ticket",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"id_with_jmp" => id_with_jmp,
"title_for_slack" => title_for_slack,
"slack_channel_id" => channel_id,
"slack_channel_url" => channel_url,
"intercom_admins" => intercom_admins,
"slack_users" => slack_users,
"best_matches" => best_matches,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
Logger.info("Fetched users from Slack")
:ok
_ ->
Logger.error("Failed to fetch users from Slack")
{:snooze, 5}
end
end
def perform(
%Oban.Job{
args: %{
"task" => "create_notion_ticket_and_slack_channel_task_create_ticket",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"id_with_jmp" => id_with_jmp,
"title_for_slack" => title_for_slack,
"slack_channel_id" => channel_id,
"slack_channel_url" => channel_url,
"intercom_admins" => intercom_admins,
"slack_users" => slack_users,
"best_matches" => best_matches,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Slack.invite_users_to_channel(channel_id, best_matches, slack_token) do
{:ok, _} ->
Logger.info("Invited users to channel")
schedule_next_task(%{
"task" => "create_notion_ticket_and_slack_channel_task_create_ticket_update_slack",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"id_with_jmp" => id_with_jmp,
"title_for_slack" => title_for_slack,
"slack_channel_id" => channel_id,
"slack_channel_url" => channel_url,
"intercom_admins" => intercom_admins,
"slack_users" => slack_users,
"best_matches" => best_matches,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
{:error,
%{
"error" => "already_in_channel",
"errors" => [
%{"error" => "already_in_channel", "ok" => false, "user" => _}
],
"ok" => false
}} ->
Logger.info("Users already in channel")
Tickets.create_ticket(%{
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"notion_ticket_name" => ticket_info["title"],
"notion_children" => ticket_info["summary"],
"slack_channel_name" => title_for_slack,
"intercom_conversation_url" => conversation_url,
"intercom_conversation_id" => Integer.to_string(conversation_id),
"slack_channel_url" => channel_url,
"user_id" => user_id
})
Logger.info("Ticket created in Database")
PubSub.broadcast(
Integrator.PubSub,
"tickets_update" <> Integer.to_string(user_id),
{:tickets_updated, "Fetching all tickets"}
)
:ok
_ ->
Logger.error("Failed to invite users to channel")
{:snooze, 5}
end
end
def perform(
%Oban.Job{
args: %{
"task" => "create_notion_ticket_and_slack_channel_task_create_ticket_update_slack",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"id_with_jmp" => _id_with_jmp,
"title_for_slack" => title_for_slack,
"slack_channel_id" => _channel_id,
"slack_channel_url" => channel_url,
"intercom_admins" => _intercom_admins,
"slack_users" => _slack_users,
"best_matches" => _best_matches,
"slack_token" => _slack_token,
"intercom_token" => _intercom_token,
"notion_token" => notion_token,
"notion_database_id" => _notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Notion.edit_slack_channel(notion_page_id, channel_url, notion_token) do
{:ok, _} ->
Logger.info("Notion ticket updated with Slack channel link")
Tickets.create_ticket(%{
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"notion_ticket_name" => ticket_info["title"],
"notion_children" => ticket_info["summary"],
"slack_channel_name" => title_for_slack,
"intercom_conversation_url" => conversation_url,
"intercom_conversation_id" => Integer.to_string(conversation_id),
"slack_channel_url" => channel_url,
"user_id" => user_id
})
Logger.info("Ticket created in Database")
PubSub.broadcast(
Integrator.PubSub,
"tickets_update" <> Integer.to_string(user_id),
{:tickets_updated, "Fetching all tickets"}
)
:ok
_ ->
Logger.error("Failed to invite users to channel")
{:snooze, 5}
end
end
## SECOND ACTION
# First function in the sequence
def perform(
%Oban.Job{
args: %{
"task" => "create_channel_and_update_ticket",
"conversations" => conversations,
"conversation_id" => conversation_id,
"ticket" => ticket,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case TicketGenerator.generate_ticket_info(conversations) do
{:ok, ticket_info} ->
notion_page_id = ticket["id"]
notion_url = ticket["url"]
Logger.info("Generated ticket info for existing ticket")
schedule_next_task(%{
"task" => "create_channel_and_update_ticket_task_get_conversation_url",
"ticket_info" => ticket_info,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to generate ticket info")
{:snooze, 5}
end
end
# New separate function to get the conversation URL
def perform(
%Oban.Job{
args: %{
"task" => "create_channel_and_update_ticket_task_get_conversation_url",
"ticket_info" => ticket_info,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Intercom.get_conversation_url(conversation_id, intercom_token) do
{:ok, conversation_url} ->
Logger.info("Retrieved Intercom conversation URL")
schedule_next_task(%{
"task" => "create_channel_and_update_ticket_task_get_notion_page",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to retrieve Intercom conversation URL")
{:snooze, 5}
end
end
# Function to get the Notion page details
def perform(
%Oban.Job{
args: %{
"task" => "create_channel_and_update_ticket_task_get_notion_page",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => _notion_url,
"notion_page_id" => notion_page_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Notion.get_page(notion_page_id, notion_token) do
{:ok, body} ->
id_with_jmp =
body["properties"]["ID"]["unique_id"]["prefix"] <>
"-" <>
Integer.to_string(body["properties"]["ID"]["unique_id"]["number"])
slug_for_title = Slugify.make_slug(ticket_info["title"])
title_for_slack = id_with_jmp <> "-" <> slug_for_title
Logger.info("Retrieved Notion page details")
schedule_next_task(%{
"task" => "create_channel_and_update_ticket_task_create_slack_channel",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => body["url"],
"notion_page_id" => notion_page_id,
"title_for_slack" => title_for_slack,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to retrieve Notion page")
{:snooze, 5}
end
end
# Next function in the sequence
def perform(
%Oban.Job{
args: %{
"task" => "create_channel_and_update_ticket_task_create_slack_channel",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"title_for_slack" => title_for_slack,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Slack.create_project_channel(title_for_slack, notion_url, slack_token) do
{:ok, channel_id, channel_url} ->
Logger.info("Channel created in Slack")
schedule_next_task(%{
"task" => "create_channel_and_update_ticket_task_fetch_intercom_admins",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"title_for_slack" => title_for_slack,
"slack_channel_id" => channel_id,
"slack_channel_url" => channel_url,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
{:error, "name_taken"} ->
schedule_next_task(%{
"task" => "create_channel_and_update_ticket_task_create_slack_channel",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"title_for_slack" => title_for_slack <> "New",
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to create channel in Slack")
{:snooze, 5}
end
end
# Next function
def perform(
%Oban.Job{
args: %{
"task" => "create_channel_and_update_ticket_task_fetch_intercom_admins",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"title_for_slack" => title_for_slack,
"slack_channel_id" => channel_id,
"slack_channel_url" => channel_url,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Intercom.get_conversation_admins(conversation_id, intercom_token) do
{:ok, intercom_admins} ->
Logger.info("Fetched admins from Intercom")
schedule_next_task(%{
"task" => "create_channel_and_update_ticket_task_fetch_slack_users",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"title_for_slack" => title_for_slack,
"slack_channel_id" => channel_id,
"slack_channel_url" => channel_url,
"intercom_admins" => intercom_admins,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to fetch admins from Intercom")
{:snooze, 5}
end
end
# Next function
def perform(
%Oban.Job{
args: %{
"task" => "create_channel_and_update_ticket_task_fetch_slack_users",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"title_for_slack" => title_for_slack,
"slack_channel_id" => channel_id,
"slack_channel_url" => channel_url,
"intercom_admins" => intercom_admins,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Slack.get_users(slack_token) do
{:ok, slack_users} ->
{_status, best_matches} =
UserMatcher.get_best_matches_for_adding_to_slack(intercom_admins, slack_users)
schedule_next_task(%{
"task" => "create_channel_and_update_ticket_task_finish",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"title_for_slack" => title_for_slack,
"slack_channel_id" => channel_id,
"slack_channel_url" => channel_url,
"best_matches" => best_matches,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
Logger.info("Fetched users from Slack")
:ok
_ ->
Logger.error("Failed to fetch users from Slack")
{:snooze, 5}
end
end
# Final function in the sequence
def perform(
%Oban.Job{
args: %{
"task" => "create_channel_and_update_ticket_task_finish",
"ticket_info" => ticket_info,
"conversation_url" => _conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"title_for_slack" => title_for_slack,
"slack_channel_id" => channel_id,
"slack_channel_url" => channel_url,
"best_matches" => best_matches,
"slack_token" => slack_token,
"intercom_token" => _intercom_token,
"notion_token" => notion_token,
"notion_database_id" => _notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Slack.invite_users_to_channel(channel_id, best_matches, slack_token) do
{:ok, _} ->
Logger.info("Invited users to channel")
# Update Notion ticket with Slack channel link
Notion.edit_slack_channel(notion_page_id, channel_url, notion_token)
Logger.info("Notion ticket updated with Slack channel and Intercom conversation links")
ticket =
Tickets.get_ticket_by_intercom_conversation_id(conversation_id |> Integer.to_string())
Tickets.update_ticket(ticket, %{
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"notion_ticket_name" => ticket_info["title"],
"notion_children" => ticket_info["summary"],
"slack_channel_name" => title_for_slack,
"intercom_conversation_id" => Integer.to_string(conversation_id),
"slack_channel_url" => channel_url
})
Logger.info("Ticket updated in Database")
PubSub.broadcast(
Integrator.PubSub,
"tickets_update" <> Integer.to_string(user_id),
{:tickets_updated, "Fetching all tickets"}
)
:ok
{:error,
%{
"error" => "already_in_channel",
"errors" => [
%{"error" => "already_in_channel", "ok" => false, "user" => _}
],
"ok" => false
}} ->
Logger.info("Users already in channel")
ticket =
Tickets.get_ticket_by_intercom_conversation_id(conversation_id |> Integer.to_string())
Tickets.update_ticket(ticket, %{
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"notion_ticket_name" => ticket_info["title"],
"notion_children" => ticket_info["summary"],
"slack_channel_name" => title_for_slack,
"intercom_conversation_id" => Integer.to_string(conversation_id),
"slack_channel_url" => channel_url
})
Logger.info("Ticket updated in Database")
PubSub.broadcast(
Integrator.PubSub,
"tickets_update" <> Integer.to_string(user_id),
{:tickets_updated, "Fetching all tickets"}
)
:ok
_ ->
Logger.error("Failed to invite users to channel")
{:snooze, 5}
end
end
## THIRD ACTION
# Starting function to create ticket and update existing channel
def perform(
%Oban.Job{
args: %{
"task" => "create_ticket_and_update_channel",
"conversations" => conversations,
"conversation_id" => conversation_id,
"channel" => channel,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case TicketGenerator.generate_ticket_info(conversations) do
{:ok, ticket_info} ->
# Get channel information
slack_channel_id = channel["id"]
slack_channel_url = channel["url"]
Logger.info("Generated ticket info")
schedule_next_task(%{
"task" => "create_ticket_and_update_channel_task_get_conversation_url",
"ticket_info" => ticket_info,
"conversation_id" => conversation_id,
"slack_channel_id" => slack_channel_id,
"slack_channel_url" => slack_channel_url,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to generate ticket info")
{:snooze, 5}
end
end
# Separate task to get the conversation URL
def perform(
%Oban.Job{
args: %{
"task" => "create_ticket_and_update_channel_task_get_conversation_url",
"ticket_info" => ticket_info,
"conversation_id" => conversation_id,
"slack_channel_id" => slack_channel_id,
"slack_channel_url" => slack_channel_url,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
# Get the conversation URL as a separate step
case Intercom.get_conversation_url(conversation_id, intercom_token) do
{:ok, conversation_url} ->
Logger.info("Retrieved Intercom conversation URL")
schedule_next_task(%{
"task" => "create_ticket_and_update_channel_task_create_notion_ticket",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"slack_channel_id" => slack_channel_id,
"slack_channel_url" => slack_channel_url,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to get Intercom conversation URL")
{:snooze, 5}
end
end
# Create the Notion ticket
def perform(
%Oban.Job{
args: %{
"task" => "create_ticket_and_update_channel_task_create_notion_ticket",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"slack_channel_id" => slack_channel_id,
"slack_channel_url" => slack_channel_url,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Notion.create_ticket(
ticket_info["title"],
ticket_info["summary"],
conversation_url,
notion_token,
notion_database_id
) do
{:ok, body} ->
notion_url = body["url"]
notion_page_id = body["id"]
id_with_jmp =
body["properties"]["ID"]["unique_id"]["prefix"] <>
"-" <>
Integer.to_string(body["properties"]["ID"]["unique_id"]["number"])
slug_for_title = Slugify.make_slug(ticket_info["title"])
title_for_slack = id_with_jmp <> "-" <> slug_for_title
# Update the Notion ticket with the Slack channel link right away
Notion.edit_slack_channel(notion_page_id, slack_channel_url, notion_token)
schedule_next_task(%{
"task" => "create_ticket_and_update_channel_task_update_slack_channel",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"slack_channel_id" => slack_channel_id,
"slack_channel_url" => slack_channel_url,
"title_for_slack" => title_for_slack,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
Logger.info("Ticket created in Notion")
:ok
_ ->
Logger.error("Failed to create ticket in Notion")
{:snooze, 5}
end
end
# Update the Slack channel name and topic
def perform(
%Oban.Job{
args: %{
"task" => "create_ticket_and_update_channel_task_update_slack_channel",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"slack_channel_id" => slack_channel_id,
"slack_channel_url" => slack_channel_url,
"title_for_slack" => title_for_slack,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
# Update the channel name
case Slack.rename_slack_channel(slack_token, slack_channel_id, title_for_slack) do
{:ok, _} ->
# Update the channel topic
case SlackChannel.set_topic(slack_channel_id, notion_url, slack_token) do
{:ok, _} ->
Logger.info("Channel updated in Slack")
schedule_next_task(%{
"task" => "create_ticket_and_update_channel_task_fetch_intercom_admins",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"slack_channel_id" => slack_channel_id,
"slack_channel_url" => slack_channel_url,
"title_for_slack" => title_for_slack,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to update channel topic")
{:snooze, 5}
end
_ ->
Logger.error("Failed to rename Slack channel")
{:snooze, 5}
end
end
# Fetch Intercom admins
def perform(
%Oban.Job{
args: %{
"task" => "create_ticket_and_update_channel_task_fetch_intercom_admins",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"slack_channel_id" => slack_channel_id,
"slack_channel_url" => slack_channel_url,
"title_for_slack" => title_for_slack,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Intercom.get_conversation_admins(conversation_id, intercom_token) do
{:ok, intercom_admins} ->
Logger.info("Fetched admins from Intercom")
schedule_next_task(%{
"task" => "create_ticket_and_update_channel_task_fetch_slack_users",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"slack_channel_id" => slack_channel_id,
"slack_channel_url" => slack_channel_url,
"title_for_slack" => title_for_slack,
"intercom_admins" => intercom_admins,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to fetch admins from Intercom")
{:snooze, 5}
end
end
# Fetch Slack users and find best matches
def perform(
%Oban.Job{
args: %{
"task" => "create_ticket_and_update_channel_task_fetch_slack_users",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"slack_channel_id" => slack_channel_id,
"slack_channel_url" => slack_channel_url,
"title_for_slack" => title_for_slack,
"intercom_admins" => intercom_admins,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Slack.get_users(slack_token) do
{:ok, slack_users} ->
{_status, best_matches} =
UserMatcher.get_best_matches_for_adding_to_slack(intercom_admins, slack_users)
schedule_next_task(%{
"task" => "create_ticket_and_update_channel_task_invite_users",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"slack_channel_id" => slack_channel_id,
"slack_channel_url" => slack_channel_url,
"title_for_slack" => title_for_slack,
"best_matches" => best_matches,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
Logger.info("Matched Intercom admins with Slack users")
:ok
_ ->
Logger.error("Failed to fetch users from Slack")
{:snooze, 5}
end
end
# Invite users to the channel and finalize the process
def perform(
%Oban.Job{
args: %{
"task" => "create_ticket_and_update_channel_task_invite_users",
"ticket_info" => ticket_info,
"conversation_url" => conversation_url,
"conversation_id" => conversation_id,
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"slack_channel_id" => slack_channel_id,
"slack_channel_url" => slack_channel_url,
"title_for_slack" => title_for_slack,
"best_matches" => best_matches,
"slack_token" => slack_token,
"intercom_token" => _intercom_token,
"notion_token" => _notion_token,
"notion_database_id" => _notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Slack.invite_users_to_channel(slack_channel_id, best_matches, slack_token) do
{:ok, _} ->
Logger.info("Users invited to Slack channel")
# Create ticket in database
Tickets.create_ticket(%{
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"notion_ticket_name" => ticket_info["title"],
"notion_children" => ticket_info["summary"],
"slack_channel_name" => title_for_slack,
"intercom_conversation_url" => conversation_url,
"intercom_conversation_id" => Integer.to_string(conversation_id),
"slack_channel_url" => slack_channel_url,
"user_id" => user_id
})
Logger.info("Ticket created in Database")
PubSub.broadcast(
Integrator.PubSub,
"tickets_update" <> Integer.to_string(user_id),
{:tickets_updated, "Fetching all tickets"}
)
:ok
{:error,
%{
"error" => "already_in_channel",
"errors" => [
%{"error" => "already_in_channel", "ok" => false, "user" => _}
],
"ok" => false
}} ->
Logger.info("Users already in channel")
# Create ticket in database
Tickets.create_ticket(%{
"notion_url" => notion_url,
"notion_page_id" => notion_page_id,
"notion_ticket_name" => ticket_info["title"],
"notion_children" => ticket_info["summary"],
"slack_channel_name" => title_for_slack,
"intercom_conversation_url" => conversation_url,
"intercom_conversation_id" => Integer.to_string(conversation_id),
"slack_channel_url" => slack_channel_url,
"user_id" => user_id
})
Logger.info("Ticket created in Database")
PubSub.broadcast(
Integrator.PubSub,
"tickets_update" <> Integer.to_string(user_id),
{:tickets_updated, "Fetching all tickets"}
)
:ok
_ ->
Logger.error("Failed to invite users to channel")
{:snooze, 5}
end
end
## FOURTH FUNCTION
# First function in the update ticket and channel workflow
def perform(
%Oban.Job{
args: %{
"task" => "update_ticket_and_channel",
"conversations" => _conversations,
"conversation_id" => conversation_id,
"channel" => channel,
"ticket" => ticket,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
# Start the workflow by getting the conversation URL
schedule_next_task(%{
"task" => "update_ticket_and_channel_task_get_conversation_url",
"conversation_id" => conversation_id,
"channel" => channel,
"ticket" => ticket,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
end
# Get conversation URL from Intercom
def perform(
%Oban.Job{
args: %{
"task" => "update_ticket_and_channel_task_get_conversation_url",
"conversation_id" => conversation_id,
"channel" => channel,
"ticket" => ticket,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Intercom.get_conversation_url(conversation_id, intercom_token) do
{:ok, conversation_url} ->
Logger.info("Retrieved Intercom conversation URL")
schedule_next_task(%{
"task" => "update_ticket_and_channel_task_get_notion_page",
"conversation_id" => conversation_id,
"conversation_url" => conversation_url,
"channel" => channel,
"ticket" => ticket,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to retrieve Intercom conversation URL")
{:snooze, 5}
end
end
# Get the Notion page details
def perform(
%Oban.Job{
args: %{
"task" => "update_ticket_and_channel_task_get_notion_page",
"conversation_id" => conversation_id,
"conversation_url" => conversation_url,
"channel" => channel,
"ticket" => ticket,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Notion.get_page(ticket["id"], notion_token) do
{:ok, body} ->
notion_page_id = body["id"]
Logger.info("Retrieved Notion page details")
schedule_next_task(%{
"task" => "update_ticket_and_channel_task_fetch_intercom_admins",
"conversation_id" => conversation_id,
"conversation_url" => conversation_url,
"channel" => channel,
"notion_page_id" => notion_page_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to retrieve Notion page")
{:snooze, 5}
end
end
# Fetch admins from Intercom
def perform(
%Oban.Job{
args: %{
"task" => "update_ticket_and_channel_task_fetch_intercom_admins",
"conversation_id" => conversation_id,
"conversation_url" => conversation_url,
"channel" => channel,
"notion_page_id" => notion_page_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Intercom.get_conversation_admins(conversation_id, intercom_token) do
{:ok, intercom_admins} ->
Logger.info("Fetched admins from Intercom")
schedule_next_task(%{
"task" => "update_ticket_and_channel_task_fetch_slack_users",
"conversation_id" => conversation_id,
"conversation_url" => conversation_url,
"channel" => channel,
"notion_page_id" => notion_page_id,
"intercom_admins" => intercom_admins,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to fetch admins from Intercom")
{:snooze, 5}
end
end
# Fetch users from Slack
def perform(
%Oban.Job{
args: %{
"task" => "update_ticket_and_channel_task_fetch_slack_users",
"conversation_id" => conversation_id,
"conversation_url" => conversation_url,
"channel" => channel,
"notion_page_id" => notion_page_id,
"intercom_admins" => intercom_admins,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Slack.get_users(slack_token) do
{:ok, slack_users} ->
{_status, best_matches} =
UserMatcher.get_best_matches_for_adding_to_slack(intercom_admins, slack_users)
Logger.info("Fetched users from Slack and matched with Intercom admins")
schedule_next_task(%{
"task" => "update_ticket_and_channel_task_invite_users",
"conversation_id" => conversation_id,
"conversation_url" => conversation_url,
"channel" => channel,
"notion_page_id" => notion_page_id,
"best_matches" => best_matches,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to fetch users from Slack")
{:snooze, 5}
end
end
# Invite users to Slack channel
def perform(
%Oban.Job{
args: %{
"task" => "update_ticket_and_channel_task_invite_users",
"conversation_id" => conversation_id,
"conversation_url" => conversation_url,
"channel" => channel,
"notion_page_id" => notion_page_id,
"best_matches" => best_matches,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Slack.invite_users_to_channel(channel["id"], best_matches, slack_token) do
{:ok, _} ->
Logger.info("Users invited to Slack channel")
schedule_next_task(%{
"task" => "update_ticket_and_channel_task_update_notion",
"conversation_id" => conversation_id,
"conversation_url" => conversation_url,
"channel" => channel,
"notion_page_id" => notion_page_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
{:error,
%{
"error" => "already_in_channel",
"errors" => [
%{"error" => "already_in_channel", "ok" => false, "user" => _}
],
"ok" => false
}} ->
Logger.info("Users already in channel")
schedule_next_task(%{
"task" => "update_ticket_and_channel_task_update_notion",
"conversation_id" => conversation_id,
"conversation_url" => conversation_url,
"channel" => channel,
"notion_page_id" => notion_page_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to invite users to channel")
{:snooze, 5}
end
end
# Update Notion with the Intercom conversation link
def perform(
%Oban.Job{
args: %{
"task" => "update_ticket_and_channel_task_update_notion",
"conversation_id" => conversation_id,
"conversation_url" => conversation_url,
"channel" => channel,
"notion_page_id" => notion_page_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
}
} = _job
) do
case Notion.edit_intercom_conversation(notion_page_id, conversation_url, notion_token) do
{:ok, _} ->
Logger.info("Intercom conversation updated in Notion")
schedule_next_task(%{
"task" => "update_ticket_and_channel_task_update_db",
"conversation_id" => conversation_id,
"channel" => channel,
"notion_page_id" => notion_page_id,
"conversation_url" => conversation_url,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"notion_token" => notion_token,
"notion_database_id" => notion_database_id,
"user_id" => user_id
})
:ok
_ ->
Logger.error("Failed to update Intercom conversation in Notion")
{:snooze, 5}
end
end
# Final step: Update the database record
def perform(
%Oban.Job{
args: %{
"task" => "update_ticket_and_channel_task_update_db",
"conversation_id" => conversation_id,
"channel" => channel,
"notion_page_id" => notion_page_id,
"conversation_url" => _conversation_url,
"slack_token" => _slack_token,
"intercom_token" => _intercom_token,
"notion_token" => notion_token,
"notion_database_id" => _notion_database_id,
"user_id" => user_id
}
} = _job
) do
ticket =
Tickets.get_ticket_by_intercom_conversation_id(conversation_id |> Integer.to_string())
case Notion.edit_slack_channel(notion_page_id, ticket.slack_channel_url, notion_token) do
{:ok, _} ->
Logger.info("Channel updated in Slack")
if ticket do
case Tickets.update_ticket(ticket, %{slack_channel_url: channel["url"]}) do
{:ok, _updated_ticket} ->
Logger.info("Ticket updated in DB")
PubSub.broadcast(
Integrator.PubSub,
"tickets_update" <> Integer.to_string(user_id),
{:tickets_updated, "Fetching all tickets"}
)
:ok
_ ->
Logger.error("Failed to update ticket in DB")
{:snooze, 5}
end
else
Logger.error("Ticket not found in DB")
{:snooze, 5}
end
_ ->
Logger.error("Failed to update channel in Notion")
{:snooze, 5}
end
end
def perform(
%Oban.Job{
args: %{
"task" => "handle_ticket_moved_to_done",
"channel_id" => channel_id,
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"user_id" => user_id
}
} = _job
) do
case Slack.send_message(
channel_id,
"Ticket has been completed and moved to Done",
slack_token
) do
{:ok, _} ->
Logger.info("Message sent to Slack channel")
schedule_next_task(%{
"task" => "handle_ticket_moved_to_done_task_send_intercom_message",
"conversation_id" => conversation_id,
"slack_token" => slack_token,
"intercom_token" => intercom_token,
"user_id" => user_id
})
_ ->
Logger.error("Failed to send message to Slack channel")
{:snooze, 5}
end
end
def perform(
%Oban.Job{
args: %{
"task" => "handle_ticket_moved_to_done_task_send_intercom_message",
"conversation_id" => conversation_id,
"slack_token" => _slack_token,
"intercom_token" => intercom_token,
"user_id" => user_id
}
} = _job
) do
case Intercom.send_message(
conversation_id |> String.to_integer(),
"Ticket has been completed and Closed , Thanks for your patience",
intercom_token
) do
{:ok, _} ->
Logger.info("Message sent to Intercom conversation")
ticket =
Tickets.get_ticket_by_intercom_conversation_id(conversation_id)
Tickets.update_ticket(ticket, %{is_done: true})
PubSub.broadcast(
Integrator.PubSub,
"tickets_update" <> Integer.to_string(user_id),
{:tickets_updated, "Fetching all tickets"}
)
Logger.info("Ticket updated in DB")
:ok
_ ->
Logger.error("Failed to send message to Intercom conversation")
{:snooze, 5}
end
end
def perform(%Oban.Job{args: _} = _job) do
:ok
end
def cancel(key) do
from(j in Job, where: fragment("? ->> ? = ?", j.args, "id", ^key))
|> Oban.cancel_all_jobs()
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment