Current section

Files

Jump to
wax lib mix tasks send_message.ex
Raw

lib/mix/tasks/send_message.ex

defmodule Mix.Tasks.SendMessage do
@moduledoc """
Send test messages
Set the ENV variables DEV_NUMBER, DEV_WA_NUMBER_ID and DEV_SERVER_TOKEN
with the correct values to be able to send messages.
DEV_NUMBER: The number you want the message to be sent to
DEV_WA_NUMBER_ID: The ID of the Whatsapp Cloud API number
DEV_WA_TOKEN: The TOKEN the Whatsapp Phone Number requieres for Authentication
An argument for the message type can be sent. Currently supported message types are:
- text
- document
- image
- interactive
- template
- video
The default message type is `text`
"""
@shortdoc "Echoes arguments"
alias Wax.CloudAPI.{Auth, Messages}
alias Wax.CloudAPI.Media, as: MediaManager
alias Wax.Messages.{Interactive, Media, Message, Template}
alias Wax.Messages.Interactive
alias Wax.Messages.Interactive.Section
use Mix.Task
@media_message_types ~w(audio document image video)
@requirements ["app.start"]
@impl Mix.Task
def run([]) do
run(["text"])
end
def run([message_type]) when message_type in @media_message_types do
Mix.shell().error("Missing file_path parameter.\nEx. mix send_message image test_file.png")
end
def run([message_type, file_path | _]) do
if File.exists?(file_path) do
params = %{file_path: file_path}
do_run(message_type, params)
else
Mix.shell().error("File #{file_path} doesn't exist")
end
end
def run([message_type | _]) do
do_run(message_type)
end
defp do_run(message_type, params \\ %{}) do
to_number = System.get_env("DEV_NUMBER")
wa_number_id = System.get_env("DEV_WA_NUMBER_ID")
token = System.get_env("DEV_WA_TOKEN")
send_message(wa_number_id, to_number, message_type, token, params)
end
defp send_message(nil, _to_number, _message_type, _token, _params),
do: Mix.shell().error("DEV_WA_NUMBER_ID env variable is missing")
defp send_message(_wa_number_id, nil, _message_type, _token, _params),
do: Mix.shell().error("DEV_NUMBER env variable is missing")
defp send_message(_wa_number_id, _tot_number, _message_type, nil, _params),
do: Mix.shell().error("DEV_WA_TOKEN env variable is missing")
defp send_message(wa_number_id, to_number, message_type, token, params) do
auth = %Auth{whatsapp_number_id: wa_number_id, token: token}
with %Message{} = message <- Message.new(to_number),
{:ok, params} <- upload_media_if_required(auth, params),
%Message{} = message <- build_test_message(message, message_type, params),
{:ok, _response} <- Messages.send(message, auth) do
Mix.shell().info("Message sent correctly")
else
{:error, error} when is_binary(error) ->
Mix.shell().error(error)
end
end
# Adds media_id to params if a media upload was made
@spec upload_media_if_required(Auth.t(), map()) ::
{:ok, map()} | {:error, String.t()}
defp upload_media_if_required(auth, %{file_path: file_path} = params) do
case MediaManager.upload_from_path(file_path, auth) do
{:ok, media_id} ->
{:ok, Map.put(params, :media_id, media_id)}
{:error, error} ->
{:error, error}
end
end
defp upload_media_if_required(_auth, params) do
{:ok, params}
end
@spec build_test_message(Message.t(), String.t(), map()) :: Message.t()
defp build_test_message(message, "text", _params) do
now = DateTime.to_iso8601(DateTime.utc_now())
message
|> Message.set_type(:text)
|> Message.set_text("Text message test " <> now)
end
defp build_test_message(message, "audio", %{media_id: media_id}) do
message
|> Message.set_type(:audio)
|> Message.add_audio(media_id)
end
defp build_test_message(message, "document", %{media_id: media_id, file_path: file_path}) do
filename = Path.basename(file_path)
message
|> Message.set_type(:document)
|> Message.add_document(media_id, filename, "This is a document caption")
end
defp build_test_message(message, "image", %{media_id: media_id}) do
message
|> Message.set_type(:image)
|> Message.add_image(media_id, "This is a caption")
end
defp build_test_message(message, "interactive", _params) do
interactive =
Interactive.new()
|> Interactive.put_header(:text, "Header", "Subtexto")
|> Interactive.put_body("BODY")
|> Interactive.put_footer("This is a footer")
|> Interactive.put_button_action(["First Button", "Second Button"])
message
|> Message.set_type(:interactive)
|> Message.add_interactive(interactive)
end
defp build_test_message(message, "interactive-list", _params) do
section_1 =
Section.new()
|> Section.put_title("Section 1 Title")
|> Section.add_row("row1", "Row 1 title", "This is a row with a description")
|> Section.add_row("row2", "Row 2 title")
section_2 =
Section.new()
|> Section.put_title("Section 2 Title")
|> Section.add_row("s21", "Testing", "Description")
interactive =
Interactive.new()
|> Interactive.put_header(:text, "Header", "Subtexto")
|> Interactive.put_body("BODY")
|> Interactive.put_footer("This is a footer")
|> Interactive.put_list_action("A button?", [section_1, section_2])
message
|> Message.set_type(:interactive)
|> Message.add_interactive(interactive)
end
defp build_test_message(message, "interactive-product", _params) do
# You have to have a Catalog with products made on the Whatsapp Bussiness side
interactive =
Interactive.new()
|> Interactive.put_body("BODY")
|> Interactive.put_footer("This is a footer")
|> Interactive.put_product_action("PRODUCT_ID", "bravo")
message
|> Message.set_type(:interactive)
|> Message.add_interactive(interactive)
end
defp build_test_message(message, "interactive-flow", _params) do
# You have to have a Flow created on the Whatsapp Bussiness side
interactive =
Interactive.new()
|> Interactive.put_header(:text, "Header", "Subtexto")
|> Interactive.put_body("BODY")
|> Interactive.put_footer("This is a footer")
|> Interactive.put_flow_action("CTA Button", {:name, "some-flow"})
message
|> Message.set_type(:interactive)
|> Message.add_interactive(interactive)
end
defp build_test_message(message, "interactive-cta-url", _params) do
interactive =
Interactive.new()
|> Interactive.put_header(:text, "Header", "Subtexto")
|> Interactive.put_body("BODY")
|> Interactive.put_footer("This is a footer")
|> Interactive.put_cta_url_action("Visit Page", "https://example.com")
message
|> Message.set_type(:interactive)
|> Message.add_interactive(interactive)
end
defp build_test_message(message, "template", %{media_id: media_id}) do
template_name = "test_url_and_image"
language = "es_MX"
header_params = [
{:image, Media.new_image(media_id)}
]
body_params = [
{:text, "Mr. Test"}
]
button_params = [
{:text, "some_url_suffix"}
]
template =
template_name
|> Template.new(language)
|> Template.add_header(header_params)
|> Template.add_body(body_params)
|> Template.add_button(:url, 0, button_params)
message
|> Message.set_type(:template)
|> Message.add_template(template)
end
defp build_test_message(message, "video", %{media_id: media_id}) do
message
|> Message.set_type(:video)
|> Message.add_video(media_id, "This is a video caption")
end
defp build_test_message(_message, message_type, _params) do
{:error, "Message type #{message_type} not supported"}
end
end