Skip to content

Commit

Permalink
Post new episode notifications to Zulip
Browse files Browse the repository at this point in the history
  • Loading branch information
jerodsanto committed Sep 25, 2024
1 parent 58ac25b commit d4388a8
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 3 deletions.
2 changes: 2 additions & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ config :changelog,
snap_token: System.get_env("SNAP_TOKEN"),
typesense_url: System.get_env("TYPESENSE_URL"),
typesense_api_key: System.get_env("TYPESENSE_API_KEY"),
zulip_user: System.get_env("ZULIP_USER"),
zulip_api_key: System.get_env("ZULIP_API_KEY"),
# 60 = one minute, 3600 = one hour, 86,400 = one day, 604,800 = one week, 31,536,000 = one year
cdn_cache_control_s3:
System.get_env(
Expand Down
5 changes: 4 additions & 1 deletion lib/changelog/oban_workers/social_poster.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Changelog.ObanWorkers.SocialPoster do
"""
use Oban.Worker

alias Changelog.{Bsky, Episode, Repo, Social, Slack}
alias Changelog.{Bsky, Episode, Repo, Social, Slack, Zulip}

@impl Oban.Worker
def perform(%Oban.Job{args: %{"episode_id" => episode_id}}) do
Expand All @@ -13,6 +13,7 @@ defmodule Changelog.ObanWorkers.SocialPoster do
post_bsky_new_episode_message(episode)
post_social_new_episode_message(episode)
post_slack_new_episode_message(episode)
post_zulip_new_episode_message(episode)

:ok
end
Expand All @@ -26,6 +27,8 @@ defmodule Changelog.ObanWorkers.SocialPoster do
Slack.Client.message("#main", message)
end

defp post_zulip_new_episode_message(episode), do: Zulip.post(episode)

def queue(episode = %Episode{}) do
%{"episode_id" => episode.id} |> new() |> Oban.insert()
end
Expand Down
42 changes: 42 additions & 0 deletions lib/changelog/zulip/client.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
defmodule Changelog.Zulip.Client do
use HTTPoison.Base

def process_url(url), do: "https://changelog.zulipchat.com/api/v1#{url}"

def process_response_body(body) do
try do
Jason.decode!(body)
rescue
_ -> body
end
end

def process_request_headers(headers) do
username = Application.get_env(:changelog, :zulip_user)
password = Application.get_env(:changelog, :zulip_api_key)
auth = Base.encode64("#{username}:#{password}")
[
{"authorization", "Basic #{auth}"},
{"content-type", "application/x-www-form-urlencoded"} | headers]
end

def handle({:ok, %{status_code: 200, body: body}}), do: body
def handle({:ok, %{status_code: 400, body: body}}), do: handle({:error, %{reason: body["msg"]}})
def handle({:error, %{reason: reason}}), do: %{"ok" => false, "error" => "#{reason}"}

def get_message(message_id) do
"/messages/#{message_id}"
|> get()
|> handle()
end

def post_message(channel, topic, content) do
channel = URI.encode_www_form(channel)
topic = URI.encode_www_form(topic)
text = URI.encode_www_form(content)

"/messages"
|> post(~s(type=stream&to=#{channel}&topic=#{topic}&content=#{text}))
|> handle()
end
end
30 changes: 30 additions & 0 deletions lib/changelog/zulip/zulip.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
defmodule Changelog.Zulip do

alias Changelog.Zulip.Client
alias Changelog.Episode
alias ChangelogWeb.EpisodeView

def post(episode = %Episode{}) do
episode = Episode.preload_all(episode)

channel = episode.podcast.slug
topic = "#{episode.slug}: #{episode.title}"
content = """
#{episode.summary}
🔗 #{EpisodeView.share_url(episode)}
"""

case Client.post_message(channel, topic, content) do
%{"result" => "success"} -> cross_post(episode, topic)
_else -> nil
end
end

defp cross_post(episode, topic) do
channel = "general"
content = "#{EpisodeView.podcast_name_and_number(episode)}! Discuss 👉 #**#{channel}>#{topic}**"

Client.post_message(channel, "new episodes", content)
end
end
8 changes: 6 additions & 2 deletions test/changelog/notifier_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule Changelog.NotifierTest do

import Mock

alias Changelog.{Bsky, Notifier, Slack, Social, Subscription, NewsItem, EpisodeRequest}
alias Changelog.{Bsky, EpisodeRequest, NewsItem, Notifier, Slack, Social, Subscription, Zulip}
alias ChangelogWeb.Email

describe "notify/1 with news item comment" do
Expand Down Expand Up @@ -188,7 +188,8 @@ defmodule Changelog.NotifierTest do
setup_with_mocks([
{Bsky, [], [post: fn _ -> true end]},
{Slack.Client, [], [message: fn _, _ -> true end]},
{Social, [], [post: fn _ -> true end]}
{Social, [], [post: fn _ -> true end]},
{Zulip, [], [post: fn _ -> true end]}
]) do
:ok
end
Expand All @@ -205,6 +206,7 @@ defmodule Changelog.NotifierTest do
assert called(Slack.Client.message("#main", :_))
assert called(Bsky.post(:_))
assert called(Social.post(:_))
assert called(Zulip.post(:_))
end

test "when episode has guests but none of them have 'thanks' set" do
Expand All @@ -223,6 +225,7 @@ defmodule Changelog.NotifierTest do
assert called(Slack.Client.message("#main", :_))
assert called(Bsky.post(:_))
assert called(Social.post(:_))
assert called(Zulip.post(:_))
end

test "when episode has guests and some of them have 'thanks' set" do
Expand All @@ -245,6 +248,7 @@ defmodule Changelog.NotifierTest do
assert called(Slack.Client.message("#main", :_))
assert called(Bsky.post(:_))
assert called(Social.post(:_))
assert called(Zulip.post(:_))
end

test "when episode was requested" do
Expand Down

0 comments on commit d4388a8

Please sign in to comment.