Current section

Files

Jump to
typetalk lib typetalk.ex
Raw

lib/typetalk.ex

defmodule Typetalk do
import Typetalk.Util
@moduledoc """
A [Typetalk](https://typetalk.com) API client library.
[API Doc](https://developer.nulab.com/docs/typetalk)
"""
@type token :: access_token | type_talk_token
@type type_talk_token :: binary
@type access_token :: Typetalk.AccessToken.t
@api_base "https://typetalk.com/api/v1"
@api_v_base "https://typetalk.com/api/v"
defp get(token, path, params \\ []) do
u = build_url(path, params)
IO.puts(u)
build_url(path, params)
|> HTTPoison.get(auth_header(token))
|> handle_response
end
defp get_v(v, token, path, params \\ []) do
u = build_url_v(v, path, params)
IO.puts(u)
u
|> HTTPoison.get(auth_header(token))
|> handle_response
end
defp get_v2(token, path, params) do
get_v(2, token, path, params)
end
defp post(token, path, params \\ []) do
{headers, data} = create_post_data(params)
HTTPoison.post("#{@api_base}/#{path}", data, Map.merge(auth_header(token), headers))
|> handle_response
end
defp create_post_data(params) do
case params do
[] -> {%{"Content-Type" => "application/x-www-form-urlencoded"}, ""}
_ when is_binary(params) -> {%{"Content-Type" => "application/x-www-form-urlencoded"}, params}
_ when is_list(params) -> {%{}, {:form, params}}
# _ -> {%{}, Enum.into(params, [])}
end
end
defp post_file(token, path, file) when is_binary(file) do
data = {:multipart, [{:file, file}]}
HTTPoison.post("#{@api_base}/#{path}", data, auth_header(token))
|> handle_response
end
defp put(token, path, params \\ []) do
{headers, data} = create_post_data(params)
build_url(path, [])
|> HTTPoison.put(data, Map.merge(auth_header(token), headers))
|> handle_response
end
defp put_q(token, path, params \\ []) do
build_url(path, params) # params are passed as query parameters
|> HTTPoison.put("", auth_header(token))
|> handle_response
end
defp put_v(v, token, path, params \\ []) do
{headers, data} = create_post_data(params)
build_url_v(v, path, [])
|> HTTPoison.put(data, Map.merge(auth_header(token), headers))
|> handle_response
end
defp delete(token, path, params \\ []) do
build_url(path, params)
|> HTTPoison.delete(auth_header(token))
|> handle_response
end
defp build_url(path, query_params) do
case query_params do
[] -> "#{@api_base}/#{path}"
_ -> "#{@api_base}/#{path}?#{URI.encode_query(query_params)}"
end
end
defp build_url_v(v, path, query_params) do
case query_params do
[] -> "#{@api_v_base}#{v}/#{path}"
_ -> "#{@api_v_base}#{v}/#{path}?#{URI.encode_query(query_params)}"
end
end
#
# API
#
@doc """
Returns the profile of the caller.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/get-profile)
"""
@spec get_profile(token) :: {:ok, map}|{:error, map}
def get_profile(token) do
get(token, "profile")
end
@doc """
Returns the profile of the given account name.
[API Doc](https://developer.nulab.com/docs/typetalk/api/2/get-friend-profile)
"""
@spec get_friend_profile(token, String.t, Keyword.t) :: {:ok, map}|{:error, map}
def get_friend_profile(token, space_key, options \\ []) do
params = message_options(options)
get_v2(token, "spaces/#{space_key}/profile", params)
end
@doc """
Returns the online status of accounts.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/get-online-status)
"""
@spec get_online_status(token, [integer]) :: {:ok, map}|{:error, map}
def get_online_status(token, account_ids) do
q = Enum.join(account_ids, ",")
get(token, "accounts/status", %{"accountIds" => q})
end
@doc """
Returns the topics.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/get-topics)
"""
@spec get_topics(token, String.t) :: {:ok, map}|{:error, map}
def get_topics(token, space_key) do
get_v2(token, "topics", %{"spaceKey" => space_key})
end
@doc """
Returns direct message topics.
[API Doc](https://developer.nulab.com/docs/typetalk/api/2/get-dm-topics)
"""
@spec get_dm_topics(token, String.t) :: {:ok, map}|{:error, map}
def get_dm_topics(token, space_key) do
get_v2(token, "messages", %{"spaceKey" => space_key})
end
@doc """
Returns messages of a topic.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/get-messages)
"""
@spec get_messages(token, String.t) :: {:ok, map}|{:error, map}
def get_messages(token, topic_id) do
get(token, "topics/#{topic_id}")
end
@doc """
Post a message to a topic.
### options
- `:replyTo`
- `:showLinkMeta`
- `:fileKeys`
- `:talkIds`
- `:attachmentFileUrls`
- `:attachmentFileNames`
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/post-message)
"""
@spec post_message(token, binary, binary, Keyword.t) :: {:ok, map}|{:error, map}
def post_message(token, topic_id, message, options \\ []) do
params = message_options(options) |> Keyword.merge([message: message])
post(token, "topics/#{topic_id}", params)
end
defp message_options(options) do
Enum.reduce(options, [], &convert_message_option/2)
end
defp convert_message_option(option, acc) do
case option do
{:fileKeys, keys} ->
acc ++ make_indexed_params("fileKeys", keys)
{:talkIds, ids} ->
acc ++ make_indexed_params("talkIds", ids)
{:attachmentFileUrls, urls} ->
acc ++ make_attachment_file_urls(urls)
{:attachmentFileNames, names} ->
acc ++ make_attachment_file_names(names)
_ ->
acc ++ [option]
end
end
defp make_attachment_file_urls(values) do
Enum.with_index(values)
|> Enum.map(fn {value, idx} -> {:"attachments[#{idx}].fileUrl", value} end)
end
defp make_attachment_file_names(values) do
Enum.with_index(values)
|> Enum.map(fn {value, idx} -> {:"attachments[#{idx}].fileName", value} end)
end
# Attachment
@doc """
Upload an attachment file.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/update-attachment)
"""
@spec upload_attachment(token, String.t, String.t) :: {:ok, map}|{:error, map}
def upload_attachment(token, topic_id, filepath) do
post_file(token, "topics/#{topic_id}/attachments", filepath)
end
@doc """
Download an attachment file.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/download-attachment)
"""
@spec download_attachment(token, String.t, String.t, String.t, String.t) :: {:ok, map}|{:error, map}
def download_attachment(token, topic_id, post_id, attachment_id, filename) do
get(token, "topics/#{topic_id}/posts/#{post_id}/attachments/#{attachment_id}/#{filename}")
end
# Topic
@doc """
Returns topic members.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/get-topic-members)
"""
@spec get_topic_members(token, String.t) :: {:ok, map}|{:error, map}
def get_topic_members(token, topic_id) do
get(token, "topics/#{topic_id}/members/status")
end
@doc """
Returns a topic message.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/get-message)
"""
@spec get_message(token, String.t, String.t) :: {:ok, map}|{:error, map}
def get_message(token, topic_id, post_id) do
get(token, "topics/#{topic_id}/posts/#{post_id}")
end
@doc """
Update a topic message.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/update-message)
"""
@spec update_message(token, String.t, String.t, String.t) :: {:ok, map}|{:error, map}
def update_message(token, topic_id, post_id, message) do
put(token, "topics/#{topic_id}/posts/#{post_id}", message: message)
end
@doc """
Delete a topic message.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/delete-message)
"""
@spec delete_message(token, String.t, String.t) :: {:ok, map}|{:error, map}
def delete_message(token, topic_id, post_id) do
delete(token, "topics/#{topic_id}/posts/#{post_id}")
end
@doc """
You can search through posted messages with this API.
[API Doc](https://developer.nulab.com/docs/typetalk/api/2/search-messages)
"""
def search_messages(token, q, space_key, options) do
params = message_options(options) |> Keyword.merge([q: q, spaceKey: space_key])
get_v2(token, "search/posts", params)
end
# Like
@doc """
Give a like to a message.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/like-message)
"""
@spec like_message(token, String.t, String.t) :: {:ok, map}|{:error, map}
def like_message(token, topic_id, post_id) do
post(token, "topics/#{topic_id}/posts/#{post_id}/like")
end
@doc """
Delete a like from a message.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/unlike-message)
"""
@spec unlike_message(token, String.t, String.t) :: {:ok, map}|{:error, map}
def unlike_message(token, topic_id, post_id) do
delete(token, "topics/#{topic_id}/posts/#{post_id}/like")
end
# Direct messages
@doc """
Get direct messages from an account.
[API Doc](https://developer.nulab.com/docs/typetalk/api/2/get-direct-messages)
"""
@spec get_direct_messages(token, String.t, String.t, Keyword.t) :: {:ok, map}|{:error, map}
def get_direct_messages(token, space_key, account_name, options \\ []) do
data = Keyword.merge([direction: "forward"], options)
account = URI.encode("@#{account_name}")
get_v2(token, "spaces/#{space_key}/messages/#{account}", data)
end
@doc """
Post a direct message.
[API Doc](https://developer.nulab.com/docs/typetalk/api/2/post-direct-message)
"""
@spec post_direct_message(token, String.t, String.t, String.t, Keyword.t) :: {:ok, map}|{:error, map}
def post_direct_message(token, space_key, account_name, message, options) do
data = options |> Keyword.merge([message: message])
post(token, "spaces/#{space_key}/messages/@#{account_name}", data)
end
# Notifications
@doc """
Get notification status.
[API Doc](https://developer.nulab.com/docs/typetalk/api/7/get-notification-status/)
"""
@spec get_notification_status(token) :: {:ok, map}|{:error, map}
def get_notification_status(token) do
get_v(7, token, "notifications/status")
end
@doc """
Mark notifications as read.
[API Doc](https://developer.nulab.com/docs/typetalk/api/3/open-notification)
"""
@spec mark_notifications_as_read(token, String.t) :: {:ok, map}|{:error, map}
def mark_notifications_as_read(token, space_key) do
put_v(3, token, "notifications", spaceKey: space_key)
end
# Mentions
@doc """
Returns mentions
[API Doc](https://developer.nulab.com/docs/typetalk/api/2/get-mentions)
"""
@spec get_mentions(token, String.t, Keyword.t) :: {:ok, map}|{:error, map}
def get_mentions(token, space_key, options \\ []) do
params = options |> Keyword.merge([spaceKey: space_key])
get_v2(token, "mentions", params)
end
@doc """
Mark a mention as read.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/save-read-mention)
"""
@spec mark_mention_as_read(token, String.t) :: {:ok, map}|{:error, map}
def mark_mention_as_read(token, mention_id) do
put(token, "mentions/#{mention_id}")
end
# Topics
@doc """
Mark all messages in a topic as read.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/save-read-topic)
"""
@spec mark_topic_as_read(token, String.t) :: {:ok, map}|{:error, map}
def mark_topic_as_read(token, topic_id) do
put_q(token, "bookmarks", topicId: topic_id)
end
@doc """
Mark all messages in a topic as read.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/save-read-topic)
"""
@spec mark_topic_as_read(token, String.t, String.t) :: {:ok, map}|{:error, map}
def mark_topic_as_read(token, topic_id, post_id) do
put_q(token, "bookmarks", topicId: topic_id, postId: post_id)
end
@doc """
Create a new topic.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/create-topic)
"""
@spec create_topic(token, String.t, String.t, Keyword.t) :: {:ok, map}|{:error, map}
def create_topic(token, name, space_key, options \\ []) do
params = Enum.into(options, [name: name, spaceKey: space_key])
post(token, "topics", params)
end
@update_topic_options MapSet.new([:description])
@doc """
Update a topic name.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/update-topic)
"""
@spec update_topic(token, String.t, String.t, Keyword.t) :: {:ok, map}|{:error, map}
def update_topic(token, topic_id, name, options \\ []) do
data = options
|> Enum.filter(fn({k,_v}) -> MapSet.member?(@update_topic_options, k) end)
|> Keyword.merge([name: name])
put(token, "topics/#{topic_id}", data)
end
@doc """
Delete a topic.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/delete-topic)
"""
@spec delete_topic(token, String.t) :: {:ok, map}|{:error, map}
def delete_topic(token, topic_id) do
delete(token, "topics/#{topic_id}")
end
@doc """
Returns topic information.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/get-topic-details)
"""
@spec get_topic_details(token, String.t) :: {:ok, map}|{:error, map}
def get_topic_details(token, topic_id) do
get(token, "topics/#{topic_id}/details")
end
# No test
@doc """
Update topic members.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/update-topic-members)
"""
@spec update_topic_members(token, String.t, Keyword.t) :: {:ok, map}|{:error, map}
def update_topic_members(token, topic_id, params) do
# [:addAccountIds, :addGroupIds, :invitationEmails, :invitationRoles, :removeAccountIds, :cancelSpaceInvitation, :removeGroupIds]
post(token, "topics/#{topic_id}/members/update", params)
end
# Spaces
@doc """
Returns the space information.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/get-spaces)
"""
@spec get_spaces(token) :: {:ok, map}|{:error, map}
def get_spaces(token) do
get(token, "spaces")
end
@doc """
Returns space members.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/get-space-members)
"""
@spec get_space_members(token, String.t) :: {:ok, map}|{:error, map}
def get_space_members(token, space_key) do
get(token, "spaces/#{space_key}/members")
end
# Search accounts
@doc """
Searches friends.
Options
* `:offset`
* `:count`
[API Doc](https://developer.nulab.com/docs/typetalk/api/4/get-friends)
"""
@spec search_friends(token, String.t, Keyword.t) :: {:ok, map}|{:error, map}
def search_friends(token, space_key, q, options \\ []) do
params = %{
q: q,
spaceKey: space_key,
offset: Keyword.get(options, :offset, 0),
count: Keyword.get(options, :count, 30)
}
get_v(4, token, "search/friends", params)
end
# Talks
@doc """
Returns talks of a topic.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/get-talks)
"""
@spec get_talks(token, String.t) :: {:ok, map}|{:error, map}
def get_talks(token, topic_id) do
get(token, "topics/#{topic_id}/talks")
end
@doc """
Returns messages of a talk.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/get-talk-messages)
"""
@spec get_talk_messages(token, String.t, String.t) :: {:ok, map}|{:error, map}
def get_talk_messages(token, topic_id, talk_id) do
get(token, "topics/#{topic_id}/talks/#{talk_id}/posts")
end
@doc """
Creates a new talk.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/create-talk)
"""
@spec create_talk(token, String.t, String.t, [integer]) :: {:ok, map}|{:error, map}
def create_talk(token, topic_id, name, post_ids) do
data = Enum.with_index(post_ids)
|> Enum.reduce(%{"talkName" => name}, fn ({post_id, idx}, acc) -> Map.put(acc, "postIds[#{idx}]", post_id) end)
|> URI.encode_query()
post(token, "topics/#{topic_id}/talks", data)
end
@doc """
Changes a talk's name.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/update-talk)
"""
@spec update_talk(token, String.t, String.t, String.t) :: {:ok, map}|{:error, map}
def update_talk(token, topic_id, talk_id, name) do
put(token, "topics/#{topic_id}/talks/#{talk_id}", talkName: name)
end
@doc """
Deletes a talk.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/delete-talk)
"""
@spec delete_talk(token, String.t, String.t) :: {:ok, map}|{:error, map}
def delete_talk(token, topic_id, talk_id) do
delete(token, "topics/#{topic_id}/talks/#{talk_id}")
end
@doc """
Add messages to a talk.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/add-memssage-to-talk)
"""
@spec add_messages_to_talk(token, String.t, String.t, [integer]) :: {:ok, map}|{:error, map}
def add_messages_to_talk(token, topic_id, talk_id, post_ids) do
data = Enum.with_index(post_ids)
|> Enum.reduce(%{}, fn ({post_id, idx}, acc) -> Map.put(acc, "postIds[#{idx}]", post_id) end)
|> URI.encode_query()
post(token, "topics/#{topic_id}/talks/#{talk_id}/posts", data)
end
@doc """
Deletes messages from a talk.
[API Doc](https://developer.nulab.com/docs/typetalk/api/1/remove-memssage-from-talk)
"""
@spec delete_messages_from_talk(token, String.t, String.t, [integer]) :: {:ok, map}|{:error, map}
def delete_messages_from_talk(token, topic_id, talk_id, post_ids) do
data = [postIds: Enum.join(post_ids, ",")]
delete(token, "topics/#{topic_id}/talks/#{talk_id}/posts", data)
end
end