Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't add user photo #194

Closed
markgerlach opened this issue Dec 20, 2015 · 3 comments
Closed

Can't add user photo #194

markgerlach opened this issue Dec 20, 2015 · 3 comments
Assignees
Milestone

Comments

@markgerlach
Copy link

I can't seem to add a user photo. I get the user, and then I run this code:

// Find the file we're looking for
string targetFile = @"EmpPhoto.jpg";

ZenFile file = new ZenFile();
file.ContentType = "image/jpeg";
file.FileData = File.ReadAllBytes(targetFile);
file.FileName = "EmpPhoto.jpg";
var uploadedFile = api.Attachments.UploadAttachment(file);
string url = uploadedFile.Attachments[0].ContentUrl;

Photo ph = new Photo();
ph.Id = uploadedFile.Attachments[0].Id;
ph.ContentType = uploadedFile.Attachments[0].ContentType;
ph.ContentUrl = url;
ph.Size = (int)new FileInfo(targetFile).Length;
ph.Name = "EmpPhoto.jpg";

// Create a thumbnail
Thumbnail nail = new Thumbnail();
nail.ContentType = ph.ContentType;
nail.ContentUrl = ph.ContentUrl;
nail.Size = ph.Size;
nail.Id = ph.Id;

user.RemotePhotoUrl = ph.ContentUrl;
user.Photo = ph;

IndividualUserResponse userResponse = api.Users.UpdateUser(user);

The user object has the photo on my side, but the response user doesn't have a photo set. What am I doing wrong? BTW - the photo is up on the site - I can browse to the URL.

Thanks,
Mark

@mhmacleod
Copy link

I'd like to second this - I'm trying to sync user details from Active Directory to Zendesk and this is the last bit I can't finish.

@markgerlach
Copy link
Author

Well, until we can get a response, I wrote the following bit of code today that seems to work. Drop me a line if you have any questions. Create a class with just this in it and then call the method as a static instance:

public class UserPhoto
    {
        protected static string GetPasswordOrTokenAuthHeader()
        {
            // Email contains my email address, Token contains that long string Zendesk gave me
            return GetAuthHeader(ZendeskHelper.EMail + "/token", ZendeskHelper.Token);
        }

        protected static string GetAuthHeader(string userName, string password)
        {
            string auth = Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", userName, password)));
            return string.Format("Basic {0}", auth);
        }

        /// <summary>
        /// Set the user's photo to the attached file
        /// </summary>
        /// <param name="id">The ID of the user</param>
        /// <param name="filePath">The file to set.  If left blank, the photo will be removed</param>
        /// <returns>True if successful - otherwise false</returns>
        public static bool SetUserPhoto(long id, string filePath)
        {
            bool rtv = true;

            try
            {
                /// ZendeskHelper.URL = "https://{yoursite}.zendesk.com/api/v2"
                var requestUrl = ZendeskHelper.URL + string.Format("/users/{0}.json", id);
                HttpWebRequest req = WebRequest.Create(requestUrl) as HttpWebRequest;
                string boundaryString = "FEF3F395A90B452BB8BFDC878DDBD152";
                req.ContentType = "multipart/form-data; boundary=" + boundaryString;

                req.Headers["Authorization"] = GetPasswordOrTokenAuthHeader();
                req.PreAuthenticate = true;

                req.Method = "PUT";
                req.Accept = "application/json, application/xml, text/json, text/x-json, text/javascript, text/xml";

                // Use a MemoryStream to form the post data request,
                // so that we can get the content-length attribute.
                MemoryStream postDataStream = new MemoryStream();
                StreamWriter postDataWriter = new StreamWriter(postDataStream);

                // Include the file in the post data
                postDataWriter.Write("\r\n--" + boundaryString + "\r\n");
                if (!String.IsNullOrEmpty(filePath))
                {
                    FileInfo info = new FileInfo(filePath);     // Get some info on the file
                    postDataWriter.Write("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n"
                                            + "Content-Type: image/jpeg\r\n\r\n",
                                            "user[photo][uploaded_data]",
                                            info.Name);

                    postDataWriter.Flush();

                    // Read the file
                    FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                    byte[] buffer = new byte[1024];
                    int bytesRead = 0;
                    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        postDataStream.Write(buffer, 0, bytesRead);
                    }
                    fileStream.Close();
                }
                else
                {
                    postDataWriter.Write("Content-Disposition: form-data; name=\"{0}\"; \r\n\r\n" 
                                            + "",
                                            "user[photo][uploaded_data]");
                }
                postDataWriter.Write("\r\n--" + boundaryString + "--\r\n");
                postDataWriter.Flush();

                // Set the http request body content length
                req.ContentLength = postDataStream.Length;

                // Dump the post data from the memory stream to the request stream
                Stream s = req.GetRequestStream();

                postDataStream.WriteTo(s);

                postDataStream.Close();

                var res = req.GetResponse();
                var response = res as HttpWebResponse;
                string responseFromServer = string.Empty;
                using (var responseStream = response.GetResponseStream())
                {
                    using (var reader = new StreamReader(responseStream))
                    {
                        responseFromServer = reader.ReadToEnd();
                    }
                }

                if (!String.IsNullOrEmpty(responseFromServer))
                {
                    rtv = ((String.IsNullOrEmpty(filePath) &&
                        responseFromServer.ToLower().Contains("\"photo\":null")) ||
                        (!String.IsNullOrEmpty(filePath) &&
                        !responseFromServer.ToLower().Contains("\"photo\":null")));
                }
            }
            catch (Exception ex)
            {
                rtv = false;
                throw ex;
            }

            return rtv;
        }
    }

    internal static class StringExtensions
    {
        internal static bool IsNullOrWhiteSpace(this string value)
        {

            // this is needed because .net 3.5 and older don't have 
            // string.IsNullOrWhiteSpace
            if (value == null) return true;

            for (int i = 0; i < value.Length; i++)
            {
                if (!char.IsWhiteSpace(value[i])) return false;
            }

            return true;
        }
    }

You can call it like this to put the photo in. The user is the User object you got back from the API.

UserPhoto.SetUserPhoto(user.Id.Value, targetFile);

Or like this to blank out the photo:

UserPhoto.SetUserPhoto(user.Id.Value, string.Empty);

@mhmacleod
Copy link

mhmacleod commented Jan 13, 2016

Hey, that’s great! I’ve done a brief read through and it’s just what I need, will apply this ASAP.

Thanks so much for your help!

@mozts2005 mozts2005 added this to the 4.0.0 milestone Jan 15, 2016
@mozts2005 mozts2005 self-assigned this Jan 15, 2016
@mozts2005 mozts2005 modified the milestones: 4.0.0, 3.5.0 Feb 17, 2016
mozts2005 added a commit that referenced this issue Jul 17, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants