com.tenmiles.helpstack.gears.HSDeskGear.java Source code

Java tutorial

Introduction

Here is the source code for com.tenmiles.helpstack.gears.HSDeskGear.java

Source

//  HSDeskGear
//
//Copyright (c) 2014 HelpStack (http://helpstack.io)
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.

package com.tenmiles.helpstack.gears;

import android.net.Uri;
import android.util.Base64;

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.tenmiles.helpstack.logic.HSGear;
import com.tenmiles.helpstack.logic.OnFetchedArraySuccessListener;
import com.tenmiles.helpstack.logic.OnFetchedSuccessListener;
import com.tenmiles.helpstack.logic.OnNewTicketFetchedSuccessListener;
import com.tenmiles.helpstack.model.HSKBItem;
import com.tenmiles.helpstack.model.HSTicket;
import com.tenmiles.helpstack.model.HSTicketUpdate;
import com.tenmiles.helpstack.model.HSUploadAttachment;
import com.tenmiles.helpstack.model.HSUser;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

import static com.tenmiles.helpstack.model.HSUser.createNewUserWithDetails;

public class HSDeskGear extends HSGear {

    private String instanceUrl;
    private String to_help_email;
    private String staff_login_email;
    private String staff_login_password;

    public HSDeskGear(String instanceUrl, String to_help_email, String staff_login_email,
            String staff_login_password) {
        if (!instanceUrl.endsWith("/")) {
            instanceUrl = instanceUrl.concat("/");
        }

        this.instanceUrl = instanceUrl;
        this.to_help_email = to_help_email;
        this.staff_login_email = staff_login_email;
        this.staff_login_password = staff_login_password;
    }

    @Override
    public void fetchKBArticle(String cancelTag, HSKBItem section, RequestQueue queue,
            OnFetchedArraySuccessListener successListener, Response.ErrorListener errorListener) {

        if (section == null) {
            //
            String url = getApiUrl().concat("topics");

            DeskJsonObjectRequest request = new DeskJsonObjectRequest(cancelTag, url,
                    new DeskArrayBaseListener<JSONObject>(successListener, errorListener) {

                        @Override
                        public void onResponse(JSONObject sectionsArray) {
                            try {
                                JSONArray allSectionsArray = sectionsArray.getJSONObject("_embedded")
                                        .getJSONArray("entries");
                                HSKBItem[] array = readSectionsFromEntries(allSectionsArray);
                                successListener.onSuccess(array);
                            } catch (JSONException e) {
                                e.printStackTrace();
                                errorListener.onErrorResponse(
                                        new VolleyError("Parsing failed when getting sections from data"));
                            }
                        }
                    }, errorListener);

            addRequestAndStartQueue(queue, request);

        } else {
            // Fetch articles under that section.

            DeskJsonObjectRequest request = new DeskJsonObjectRequest(cancelTag, section.getId(), null,
                    new DeskArrayBaseListener<JSONObject>(successListener, errorListener) {

                        @Override
                        public void onResponse(JSONObject sectionsObject) {
                            HSKBItem[] array;
                            try {
                                array = retrieveArticlesFromSection(sectionsObject);
                                successListener.onSuccess(array);
                            } catch (JSONException e) {
                                e.printStackTrace();
                                errorListener.onErrorResponse(
                                        new VolleyError("Error when fetching articles in section"));
                            }
                        }
                    }, errorListener);

            addRequestAndStartQueue(queue, request);

        }
    }

    @Override
    public void registerNewUser(final String cancelTag, final String firstName, final String lastname,
            final String emailAddress, final RequestQueue queue, OnFetchedSuccessListener successListener,
            Response.ErrorListener errorListener) {

        HSUser user = createNewUserWithDetails(firstName, lastname, emailAddress);

        DeskJsonObjectRequest request = new DeskJsonObjectRequest(cancelTag,
                getApiUrl().concat("customers/search?email=").concat(user.getEmail()),
                new CreateNewUserSuccessListener(user, successListener, errorListener) {

                    @Override
                    public void onResponse(JSONObject responseObject) {

                        int totalEntries = 0;
                        try {
                            totalEntries = responseObject.getInt("total_entries");
                        } catch (JSONException e) {
                            e.printStackTrace();
                            errorListener
                                    .onErrorResponse(new VolleyError("Parsing error when getting Total Entries"));
                        }

                        if (totalEntries >= 1) {
                            try {

                                JSONObject validUserDetail = null;

                                JSONArray couldBeValidUsersArray = responseObject.getJSONObject("_embedded")
                                        .getJSONArray("entries");
                                int couldBeValidUsersArrayLength = couldBeValidUsersArray.length();

                                for (int i = 0; i < couldBeValidUsersArrayLength; i++) {
                                    JSONObject couldBeValidUserDetail = couldBeValidUsersArray.getJSONObject(i);
                                    JSONArray emailsArray = couldBeValidUserDetail.getJSONArray("emails");

                                    int emailsArrayLength = emailsArray.length();
                                    for (int j = 0; j < emailsArrayLength; j++) {
                                        JSONObject emailDetails = couldBeValidUsersArray.getJSONObject(j);

                                        if (emailDetails.getString("value").equals(user.getEmail())) {
                                            validUserDetail = couldBeValidUserDetail;
                                            break;
                                        }
                                    }

                                    if (validUserDetail != null) {
                                        break;
                                    }
                                }

                                if (validUserDetail != null) {

                                    String firstName = validUserDetail.getString("first_name");
                                    String lastName = validUserDetail.getString("last_name");
                                    String email = validUserDetail.getJSONArray("emails").getJSONObject(0)
                                            .getString("value");
                                    String userLink = validUserDetail.getJSONObject("_links").getJSONObject("self")
                                            .getString("href");

                                    HSUser validUser = createNewUserWithDetails(firstName, lastName, email,
                                            userLink);
                                    successListener.onSuccess(validUser);
                                } else {
                                    errorListener.onErrorResponse(
                                            new VolleyError("Error when getting details of users"));
                                }

                            } catch (JSONException e) {
                                e.printStackTrace();
                                errorListener.onErrorResponse(
                                        new VolleyError("Error when getting single user from multiple users"));
                            }
                        } else {
                            //not found in search.
                            //create a new user and send it as valid user.

                            JSONObject emailContents = new JSONObject();
                            JSONArray emails = new JSONArray();
                            final JSONObject params = new JSONObject();

                            try {
                                emailContents.put("type", "home");
                                emailContents.put("value", user.getEmail());
                                emails.put(emailContents);

                                params.put("first_name", user.getFirstName());
                                params.put("last_name", user.getLastName());
                                params.put("emails", emails);

                                DeskJsonObjectRequest request = new DeskJsonObjectRequest(cancelTag,
                                        getApiUrl().concat("customers"), params,
                                        new CreateNewUserSuccessListener(user, successListener, errorListener) {

                                            @Override
                                            public void onResponse(JSONObject responseObject) {

                                                String firstName;
                                                String lastName;
                                                String apiHref;
                                                HSUser validatedUser = null;

                                                JSONArray emailsArray;

                                                try {
                                                    firstName = responseObject.getString("first_name");
                                                    lastName = responseObject.getString("last_name");
                                                    apiHref = responseObject.getJSONObject("_links")
                                                            .getJSONObject("self").getString("href");

                                                    emailsArray = responseObject.getJSONArray("emails");

                                                    int eventsArrayLength = emailsArray.length();
                                                    for (int i = 0; i < eventsArrayLength; i++) {
                                                        JSONObject emailObject = emailsArray.getJSONObject(i);
                                                        if (emailObject.getString("type").equals("home")) {
                                                            validatedUser = createNewUserWithDetails(firstName,
                                                                    lastName, emailObject.getString("value"),
                                                                    apiHref);
                                                        }
                                                    }

                                                    successListener.onSuccess(validatedUser);
                                                } catch (JSONException e) {
                                                    e.printStackTrace();
                                                    errorListener.onErrorResponse(new VolleyError(
                                                            "Error when creating new user with details"));
                                                }
                                            }
                                        }, errorListener);

                                addRequestAndStartQueue(queue, request);

                            } catch (JSONException e) {
                                e.printStackTrace();
                                errorListener.onErrorResponse(
                                        new VolleyError("Error when setting customer details as parameters"));
                            }
                        }
                    }
                }, errorListener);

        addRequestAndStartQueue(queue, request);
    }

    @Override
    public void createNewTicket(final String cancelTag, HSUser user, String message, String body,
            final HSUploadAttachment[] attachments, final RequestQueue queue,
            OnNewTicketFetchedSuccessListener successListener, Response.ErrorListener errorListener) {

        JSONObject ticketJson = null;
        try {
            ticketJson = retrieveTicketProperties(user, body, message);
        } catch (JSONException e) {
            e.printStackTrace();
            errorListener.onErrorResponse(new VolleyError("Error when getting ticket properties"));
            return;
        }

        DeskJsonObjectRequest request = new DeskJsonObjectRequest(cancelTag, getApiUrl().concat("cases"),
                ticketJson, new CreateNewTicketSuccessListener(user, successListener, errorListener) {

                    @Override
                    public void onResponse(JSONObject response) {

                        try {
                            String subject = response.getString("subject");
                            String caseIdHref = response.getJSONObject("_links").getJSONObject("self")
                                    .getString("href");
                            String caseId = retrieveSectionId(caseIdHref);

                            final HSTicket ticket = HSTicket.createATicket(caseId, subject, caseIdHref);
                            // If there are attachment to be uploaded, upload attachment

                            if (attachments != null && attachments.length > 0) {
                                HSUploadAttachment attachmentObject = attachments[0]; // We are handling the number of attachments in constructor

                                uploadAttachmentToServer(cancelTag, caseIdHref, attachmentObject, queue,
                                        new Response.Listener<JSONObject>() {
                                            @Override
                                            public void onResponse(JSONObject jsonObject) {
                                                successListener.onSuccess(user, ticket);
                                            }
                                        }, errorListener);

                            } else {
                                successListener.onSuccess(this.user, ticket);
                            }

                        } catch (JSONException e) {
                            e.printStackTrace();
                            errorListener.onErrorResponse(new VolleyError("Parsing failed when creating a ticket"));
                        }
                    }
                }, errorListener);

        addRequestAndStartQueue(queue, request); // For ticket creation
    }

    @Override
    public void fetchAllUpdateOnTicket(final String cancelTag, final HSTicket ticket, final HSUser user,
            final RequestQueue queue, final OnFetchedArraySuccessListener successListener,
            Response.ErrorListener errorListener) {

        final String apiHref = getApiHref(ticket);

        String url = instanceUrl.concat(apiHref).concat("/message");
        String userId = user.getUserId();
        DeskJsonObjectRequest request = new DeskJsonObjectRequest(cancelTag, url,
                new DeskArrayBaseListener<JSONObject>(successListener, errorListener) {

                    @Override
                    public void onResponse(JSONObject responseObject) {
                        try {

                            String content = responseObject.getString("body");
                            String from = responseObject.getString("from");

                            final Date update_time = parseTime(responseObject.getString("updated_at"));

                            HSTicketUpdate originalMessage = HSTicketUpdate.createUpdateByUser(ticket.getTicketId(),
                                    from, content, update_time, null);

                            final ArrayList<HSTicketUpdate> ticketUpdates = new ArrayList<HSTicketUpdate>();
                            ticketUpdates.add(originalMessage);

                            String repliesUrl = instanceUrl.concat(apiHref).concat("/replies");

                            DeskJsonObjectRequest repliesRequest = new DeskJsonObjectRequest(cancelTag, repliesUrl,
                                    null, new DeskArrayBaseListener<JSONObject>(successListener, errorListener) {

                                        @Override
                                        public void onResponse(JSONObject repliesObject) {
                                            String from = null;
                                            String content = null;
                                            boolean isUpdateTypeUserReply;
                                            Date updated_time;

                                            try {
                                                JSONArray entriesArray = repliesObject.getJSONObject("_embedded")
                                                        .getJSONArray("entries");

                                                int eventsArrayLength = entriesArray.length();
                                                for (int i = 0; i < eventsArrayLength; i++) {
                                                    JSONObject replyObject = entriesArray.getJSONObject(i);

                                                    if (!replyObject.isNull("from")) {
                                                        from = replyObject.getString("from");
                                                    }

                                                    content = replyObject.getString("body");

                                                    if (replyObject.getString("direction").equals("out")) {
                                                        isUpdateTypeUserReply = false;
                                                    } else {
                                                        isUpdateTypeUserReply = true;
                                                    }

                                                    updated_time = parseTime(replyObject.getString("updated_at"));

                                                    HSTicketUpdate replyForTicket;
                                                    if (isUpdateTypeUserReply) {
                                                        replyForTicket = HSTicketUpdate.createUpdateByUser(
                                                                ticket.getTicketId(), from, content, updated_time,
                                                                null);
                                                    } else {
                                                        replyForTicket = HSTicketUpdate.createUpdateByStaff(
                                                                ticket.getTicketId(), from, content, updated_time,
                                                                null);
                                                    }

                                                    ticketUpdates.add(replyForTicket);
                                                }

                                                HSTicketUpdate[] array = new HSTicketUpdate[0];
                                                array = ticketUpdates.toArray(array);
                                                successListener.onSuccess(array);

                                            } catch (JSONException e) {
                                                e.printStackTrace();
                                                errorListener.onErrorResponse(new VolleyError(
                                                        "Parsing failed when fetching all replies for a ticket"));
                                            }

                                        }
                                    }, errorListener);

                            addRequestAndStartQueue(queue, repliesRequest);

                        } catch (JSONException e) {
                            e.printStackTrace();
                            errorListener.onErrorResponse(
                                    new VolleyError("Parsing failed when fetching all updates for a ticket"));
                        }
                    }
                }, errorListener);

        addRequestAndStartQueue(queue, request);
    }

    @Override
    public void addReplyOnATicket(final String cancelTag, final String message,
            final HSUploadAttachment[] attachments, final HSTicket ticket, final HSUser user,
            final RequestQueue queue, final OnFetchedSuccessListener successListener,
            Response.ErrorListener errorListener) {

        JSONObject replyJson = null;
        try {
            replyJson = createUserReply(message, to_help_email);
        } catch (JSONException e) {
            e.printStackTrace();
            errorListener.onErrorResponse(new VolleyError("Error when creating user reply"));
        }

        DeskJsonObjectRequest request = new DeskJsonObjectRequest(cancelTag,
                instanceUrl.concat(getApiHref(ticket)).concat("/replies"), replyJson,
                new DeskBaseListener<JSONObject>(successListener, errorListener) {

                    @Override
                    public void onResponse(JSONObject responseObject) {

                        String content = null;
                        String userName = null;
                        Date update_time = null;

                        try {
                            if (!responseObject.isNull("from")) {
                                userName = responseObject.getString("from");
                            }

                            if (!responseObject.isNull("body")) {
                                content = responseObject.getString("body");
                            }

                            if (!responseObject.isNull("updated_at")) {
                                update_time = parseTime(responseObject.getString("updated_at"));
                            }

                            final HSTicketUpdate userReply = HSTicketUpdate.createUpdateByUser(ticket.getTicketId(),
                                    userName, content, update_time, null);

                            if (attachments != null && attachments.length > 0) {
                                HSUploadAttachment attachmentObject = attachments[0]; // We are handling the number of attachments in constructor

                                uploadAttachmentToServer(cancelTag, ticket.getApiHref(), attachmentObject, queue,
                                        new Response.Listener<JSONObject>() {
                                            @Override
                                            public void onResponse(JSONObject jsonObject) {
                                                successListener.onSuccess(userReply);
                                            }
                                        }, errorListener);

                            } else {
                                successListener.onSuccess(userReply);
                            }

                        } catch (JSONException e) {
                            e.printStackTrace();
                            errorListener.onErrorResponse(new VolleyError("Error when parsing replies"));
                        }
                    }
                }, errorListener);

        addRequestAndStartQueue(queue, request);
    }

    private String getApiUrl() {
        return this.instanceUrl.concat("api/v2/");
    }

    private String getApiHref(HSTicket ticket) {
        String apiHref = ticket.getApiHref();
        if (apiHref.startsWith("/")) {
            apiHref = apiHref.substring(1);
        }
        return apiHref;
    }

    private void addRequestAndStartQueue(RequestQueue queue, DeskJsonObjectRequest request) {
        queue.add(request);
        queue.start();
    }

    private void uploadAttachmentToServer(String cancelTag, String caseId, HSUploadAttachment attachmentObject,
            RequestQueue queue, Response.Listener<JSONObject> successListener, Response.ErrorListener errorListener)
            throws JSONException {

        Uri.Builder builder = new Uri.Builder();
        builder.encodedPath(instanceUrl);
        builder.appendEncodedPath(caseId.substring(1));
        builder.appendEncodedPath("attachments");

        String attachmentUrl = builder.build().toString();

        String attachmentFileName = attachmentObject.getAttachment().getFileName() == null ? "picture"
                : attachmentObject.getAttachment().getFileName();
        String attachmentMimeType = attachmentObject.getAttachment().getMime_type();
        try {
            JSONObject attachmentPostObject = new JSONObject();

            InputStream input = attachmentObject.generateInputStreamToUpload();
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[512];
            try {
                int n = 0;
                while (-1 != (n = input.read(buffer))) {
                    output.write(buffer, 0, n);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            attachmentPostObject.put("content", Base64.encodeToString(output.toByteArray(), Base64.DEFAULT));

            attachmentPostObject.put("content_type", attachmentMimeType);
            attachmentPostObject.put("file_name", attachmentFileName);

            DeskJsonObjectRequest attachmentRequest = new DeskJsonObjectRequest(cancelTag, attachmentUrl,
                    attachmentPostObject, successListener, errorListener);

            addRequestAndStartQueue(queue, attachmentRequest); // For Attachments
        } catch (FileNotFoundException e) {
            errorListener.onErrorResponse(new VolleyError("File not found"));
            e.printStackTrace();
        }
    }

    private String retrieveSectionId(String href) throws JSONException {
        // href will be of the form: /api/v2/topic/<section id>
        // <section id> will therefore be the text after the last /
        return href.substring(href.lastIndexOf("/") + 1);
    }

    private HSKBItem[] retrieveArticlesFromSection(JSONObject sectionObject) throws JSONException {
        ArrayList<HSKBItem> kbArticleArray = new ArrayList<HSKBItem>();

        JSONArray articleArray = sectionObject.getJSONObject("_embedded").getJSONArray("entries");

        for (int j = 0; j < articleArray.length(); j++) {
            JSONObject arrayObject = articleArray.getJSONObject(j);
            if (arrayObject.getBoolean("in_support_center")) {
                HSKBItem item = HSKBItem.createForArticle(null, arrayObject.getString("subject").trim(),
                        arrayObject.getString("body"));
                kbArticleArray.add(item);
            }
        }

        HSKBItem[] array = new HSKBItem[0];
        array = kbArticleArray.toArray(array);
        return array;
    }

    private HSKBItem[] readSectionsFromEntries(JSONArray sectionsArray) throws JSONException {
        ArrayList<HSKBItem> kbSectionArray = new ArrayList<HSKBItem>();

        int count = sectionsArray.length();
        for (int i = 0; i < count; i++) {
            JSONObject sectionObject = sectionsArray.getJSONObject(i);
            if (sectionObject != null && sectionObject.getBoolean("in_support_center")) {
                String href = sectionObject.getJSONObject("_links").getJSONObject("articles").getString("href");
                href = instanceUrl.concat(href.substring(1));
                HSKBItem item = HSKBItem.createForSection(href, sectionObject.getString("name"));
                kbSectionArray.add(item);
            }
        }

        HSKBItem[] array = new HSKBItem[0];
        array = kbSectionArray.toArray(array);
        return array;
    }

    private JSONObject retrieveTicketProperties(HSUser user, String body, String message) throws JSONException {

        JSONObject messageFields = new JSONObject();
        JSONObject customerLinks = new JSONObject();
        JSONObject customerParameter = new JSONObject();
        JSONObject params = new JSONObject();

        messageFields.put("direction", "in");
        messageFields.put("from", user.getEmail());
        messageFields.put("to", to_help_email);
        messageFields.put("subject", message);
        messageFields.put("body", body);

        customerLinks.put("href", user.getApiHref());
        customerLinks.put("class", "customer");

        customerParameter.put("customer", customerLinks);

        params.put("type", "email");
        params.put("subject", message);
        params.put("_links", customerParameter);
        params.put("message", messageFields);

        return params;
    }

    private JSONObject createUserReply(String message, String email) throws JSONException {
        JSONObject userReply = new JSONObject();

        userReply.put("direction", "in");
        userReply.put("body", message);
        userReply.put("to", email);

        return userReply;
    }

    protected static Date parseTime(String dateString) {
        Date givenTimeDate = null;
        try {
            givenTimeDate = parseUTCString(dateString, "yyyy-MM-dd'T'HH:mm:ss'Z'");
        } catch (ParseException e) {
            try {
                givenTimeDate = parseUTCString(dateString, "yyyy-MM-dd");
            } catch (ParseException e1) {
                try {
                    givenTimeDate = parseUTCString(dateString, "yyyy-MM-dd HH:mm:ss.SSSSZ");
                } catch (ParseException e2) {
                    e2.printStackTrace();
                }
            }
        }
        return givenTimeDate;
    }

    private static Date parseUTCString(String timeStr, String pattern) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.getDefault());
        format.setTimeZone(TimeZone.getTimeZone("UTC"));
        return format.parse(timeStr);
    }

    private abstract class DeskArrayBaseListener<T> implements Response.Listener<T> {

        protected OnFetchedArraySuccessListener successListener;
        protected Response.ErrorListener errorListener;

        public DeskArrayBaseListener(OnFetchedArraySuccessListener successListener,
                Response.ErrorListener errorListener) {
            this.successListener = successListener;
            this.errorListener = errorListener;
        }

    }

    private abstract class DeskBaseListener<T> implements Response.Listener<T> {

        protected OnFetchedSuccessListener successListener;
        protected Response.ErrorListener errorListener;

        public DeskBaseListener(OnFetchedSuccessListener successListener, Response.ErrorListener errorListener) {
            this.successListener = successListener;
            this.errorListener = errorListener;
        }

    }

    private class DeskJsonObjectRequest extends JsonObjectRequest {

        protected static final int TIMEOUT_MS = 0;

        /** Default number of retries for image requests */
        protected static final int MAX_RETRIES = 0;

        /** Default backoff multiplier for image requests */
        protected static final float BACKOFF_MULT = 0f;

        HashMap<String, String> headers = new HashMap<String, String>();

        // Post
        public DeskJsonObjectRequest(String cancelTag, String url, JSONObject ticketJson,
                Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {
            super(url, ticketJson, listener, errorListener);
            addRequestParameters(cancelTag);
        }

        // Get
        public DeskJsonObjectRequest(String cancelTag, String url, Response.Listener<JSONObject> listener,
                Response.ErrorListener errorListener) {
            super(url, null, listener, errorListener);
            addRequestParameters(cancelTag);
        }

        private void addRequestParameters(String cancelTag) {
            this.setTag(cancelTag);
            this.addCredential(staff_login_email, staff_login_password);
            this.setRetryPolicy(new DefaultRetryPolicy(DeskJsonObjectRequest.TIMEOUT_MS,
                    DeskJsonObjectRequest.MAX_RETRIES, DeskJsonObjectRequest.BACKOFF_MULT));
        }

        public void addCredential(String name, String password) {
            String credentials = name.concat(":").concat(password);
            String base64EncodedCredentials = Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
            headers.put("Authorization", "Basic ".concat(base64EncodedCredentials));
        }

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            return headers;
        }

    }

    private abstract class CreateNewTicketSuccessListener implements Response.Listener<JSONObject> {

        protected HSUser user;
        protected OnNewTicketFetchedSuccessListener successListener;
        protected Response.ErrorListener errorListener;

        public CreateNewTicketSuccessListener(HSUser user, OnNewTicketFetchedSuccessListener successListener,
                Response.ErrorListener errorListener) {
            this.user = user;
            this.successListener = successListener;
            this.errorListener = errorListener;
        }
    }

    private abstract class CreateNewUserSuccessListener implements Response.Listener<JSONObject> {

        protected HSUser user;
        protected OnFetchedSuccessListener successListener;
        protected Response.ErrorListener errorListener;

        public CreateNewUserSuccessListener(HSUser user, OnFetchedSuccessListener successListener,
                Response.ErrorListener errorListener) {
            this.user = user;
            this.successListener = successListener;
            this.errorListener = errorListener;
        }
    }
}