net.dv8tion.jda.entities.impl.PrivateChannelImpl.java Source code

Java tutorial

Introduction

Here is the source code for net.dv8tion.jda.entities.impl.PrivateChannelImpl.java

Source

/*
 *     Copyright 2015-2016 Austin Keener & Michael Ritter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.dv8tion.jda.entities.impl;

import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.mashape.unirest.request.body.MultipartBody;
import net.dv8tion.jda.JDA;
import net.dv8tion.jda.MessageBuilder;
import net.dv8tion.jda.MessageHistory;
import net.dv8tion.jda.Permission;
import net.dv8tion.jda.entities.Message;
import net.dv8tion.jda.entities.PrivateChannel;
import net.dv8tion.jda.entities.User;
import net.dv8tion.jda.exceptions.BlockedException;
import net.dv8tion.jda.exceptions.PermissionException;
import net.dv8tion.jda.exceptions.RateLimitedException;
import net.dv8tion.jda.handle.EntityBuilder;
import net.dv8tion.jda.requests.Requester;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;

public class PrivateChannelImpl implements PrivateChannel {
    public static final String RATE_LIMIT_IDENTIFIER = "GLOBAL_PRIV_CHANNEL_RATELIMIT";
    private final String id;
    private final User user;
    private final JDAImpl api;

    public PrivateChannelImpl(String id, User user, JDAImpl api) {
        this.id = id;
        this.user = user;
        this.api = api;
    }

    @Override
    public JDA getJDA() {
        return api;
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public User getUser() {
        return user;
    }

    @Override
    public Message sendMessage(String text) {
        return sendMessage(new MessageBuilder().appendString(text).build());
    }

    @Override
    public Message sendMessage(Message msg) {
        if (api.getMessageLimit(RATE_LIMIT_IDENTIFIER) != null) {
            throw new RateLimitedException(api.getMessageLimit(RATE_LIMIT_IDENTIFIER) - System.currentTimeMillis());
        }
        try {
            Requester.Response response = api.getRequester().post(
                    Requester.DISCORD_API_PREFIX + "channels/" + getId() + "/messages",
                    new JSONObject().put("content", msg.getRawContent()));
            if (response.isRateLimit()) {
                long retry_after = response.getObject().getLong("retry_after");
                api.setMessageTimeout(RATE_LIMIT_IDENTIFIER, retry_after);
                throw new RateLimitedException(retry_after);
            }
            if (!response.isOk()) {
                throw new BlockedException();
            }
            return new EntityBuilder(api).createMessage(response.getObject());
        } catch (JSONException ex) {
            JDAImpl.LOG.log(ex);
            //sending failed
            return null;
        }
    }

    @Override
    public void sendMessageAsync(String text, Consumer<Message> callback) {
        sendMessageAsync(new MessageBuilder().appendString(text).build(), callback);
    }

    @Override
    public void sendMessageAsync(Message msg, Consumer<Message> callback) {
        ((MessageImpl) msg).setChannelId(id);
        TextChannelImpl.AsyncMessageSender.getInstance(getJDA(), RATE_LIMIT_IDENTIFIER).enqueue(msg, false,
                callback);
    }

    @Override
    public Message sendFile(File file, Message message) {
        if (file == null || !file.exists() || !file.canRead())
            throw new IllegalArgumentException("Provided file is either null, doesn't exist or is not readable!");
        if (file.length() > 8 << 20) //8MB
            throw new IllegalArgumentException("File is to big! Max file-size is 8MB");

        JDAImpl api = (JDAImpl) getJDA();
        try {
            MultipartBody body = Unirest.post(Requester.DISCORD_API_PREFIX + "channels/" + getId() + "/messages")
                    .header("authorization", getJDA().getAuthToken()).header("user-agent", Requester.USER_AGENT)
                    .field("file", file);
            if (message != null)
                body.field("content", message.getRawContent()).field("tts", message.isTTS());

            String dbg = String.format(
                    "Requesting %s -> %s\n\tPayload: file: %s, message: %s, tts: %s\n\tResponse: ",
                    body.getHttpRequest().getHttpMethod().name(), body.getHttpRequest().getUrl(),
                    file.getAbsolutePath(), message == null ? "null" : message.getRawContent(),
                    message == null ? "N/A" : message.isTTS());
            HttpResponse<JsonNode> response = body.asJson();
            Requester.LOG.trace(dbg + body);

            try {
                int status = response.getStatus();

                if (status >= 200 && status < 300) {
                    return new EntityBuilder(api).createMessage(response.getBody().getObject());
                } else if (response.getStatus() == 429) {
                    long retryAfter = response.getBody().getObject().getLong("retry_after");
                    api.setMessageTimeout(RATE_LIMIT_IDENTIFIER, retryAfter);
                    throw new RateLimitedException(retryAfter);
                } else {
                    throw new RuntimeException(
                            "An unknown status code was returned when attempting to upload file. Status: " + status
                                    + " JSON: " + response.getBody().toString());
                }

            } catch (JSONException e) {
                Requester.LOG.fatal("Following json caused an exception: " + response.getBody().toString());
                Requester.LOG.log(e);
            }
        } catch (UnirestException e) {
            Requester.LOG.log(e);
        }
        return null;
    }

    @Override
    public void sendFileAsync(File file, Message message, Consumer<Message> callback) {
        Thread thread = new Thread(() -> {
            Message messageReturn;
            try {
                messageReturn = sendFile(file, message);
            } catch (RateLimitedException e) {
                JDAImpl.LOG.warn("Got ratelimited when trying to upload file. Providing null to callback.");
                messageReturn = null;
            }

            if (callback != null)
                callback.accept(messageReturn);
        });
        thread.setName("PrivateChannelImpl SendFileAsync Channel: " + id);
        thread.setDaemon(true);
        thread.start();
    }

    @Override
    public Message getMessageById(String messageId) {
        Requester.Response response = ((JDAImpl) getJDA()).getRequester()
                .get(Requester.DISCORD_API_PREFIX + "channels/" + id + "/messages/" + messageId);

        if (response.isOk())
            return new EntityBuilder((JDAImpl) getJDA()).createMessage(response.getObject());

        //Doesn't exist.
        return null;
    }

    @Override
    public boolean deleteMessageById(String messageId) {
        Requester.Response response = ((JDAImpl) getJDA()).getRequester()
                .delete(Requester.DISCORD_API_PREFIX + "channels/" + id + "/messages/" + messageId);

        if (response.isOk())
            return true;
        else if (response.code == 403)
            throw new PermissionException("Cannot delete another User's messages in a PrivateChannel.");

        //Doesn't exist. Either never existed, bad id, was deleted already, or not in this channel.
        return false;
    }

    @Override
    public MessageHistory getHistory() {
        return new MessageHistory(this);
    }

    @Override
    public void sendTyping() {
        api.getRequester().post(Requester.DISCORD_API_PREFIX + "channels/" + getId() + "/typing", new JSONObject());
    }

    @Override
    public boolean pinMessageById(String messageId) {
        Requester.Response response = ((JDAImpl) getJDA()).getRequester()
                .put(Requester.DISCORD_API_PREFIX + "/channels/" + id + "/pins/" + messageId, new JSONObject());
        if (response.isRateLimit())
            throw new RateLimitedException(response.getObject().getInt("retry_after"));
        return response.isOk();
    }

    @Override
    public boolean unpinMessageById(String messageId) {
        Requester.Response response = ((JDAImpl) getJDA()).getRequester()
                .delete(Requester.DISCORD_API_PREFIX + "/channels/" + id + "/pins/" + messageId);
        if (response.isRateLimit())
            throw new RateLimitedException(response.getObject().getInt("retry_after"));
        return response.isOk();
    }

    @Override
    public List<Message> getPinnedMessages() {
        List<Message> pinnedMessages = new LinkedList<>();
        Requester.Response response = ((JDAImpl) getJDA()).getRequester()
                .get(Requester.DISCORD_API_PREFIX + "/channels/" + id + "/pins");
        if (response.isOk()) {
            JSONArray pins = response.getArray();
            for (int i = 0; i < pins.length(); i++) {
                pinnedMessages.add(new EntityBuilder((JDAImpl) getJDA()).createMessage(pins.getJSONObject(i)));
            }
            return Collections.unmodifiableList(pinnedMessages);
        } else if (response.isRateLimit())
            throw new RateLimitedException(response.getObject().getInt("retry_after"));
        else
            throw new RuntimeException(
                    "An unknown error occured attempting to get pinned messages. Ask devs for help.\n" + response);
    }

    @Override
    public void close() {
        api.getRequester().delete(Requester.DISCORD_API_PREFIX + "channels/" + getId());
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof PrivateChannel))
            return false;
        PrivateChannel oPChannel = (PrivateChannel) o;
        return this == oPChannel || this.getId().equals(oPChannel.getId());
    }

    @Override
    public int hashCode() {
        return getId().hashCode();
    }

    @Override
    public String toString() {
        return "PC:" + getUser().getUsername() + '(' + getId() + ')';
    }
}