Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Net;
- using System.IO;
- namespace MyApplication
- {
- /// <summary>
- /// This class is a simple authentication/ticket submission program for ZenDesk.
- /// </summary>
- class ZenRequest
- {
- /// <summary>
- /// AppConfigFileSettings is class that reads/updates the App.Config file for
- /// simple transport of data. You should use more secure means to pass user sessions,
- /// this was necessary in my desktop app for GPO purposes.
- /// </summary>
- AppConfigFileSettings reg = new AppConfigFileSettings();
- /// <summary>
- /// ZenRequest is our constructor, and for security purposes, we do not allow null at
- /// build time.
- /// </summary>
- /// <param name="userName">Agent or Admin with all ticket access</param>
- /// <param name="password">In cleartext. This is a lament's example-- please secure your code!</param>
- /// <param name="debug">Are you using the sandbox URL, or the production?</param>
- public ZenRequest(String userName, String password, Boolean debug)
- {
- if (debug == true)
- {
- zenURL = "<sandbox_url>"; // Replace this string with the URL of your sandbox to test the app.
- }
- else if (debug == false)
- {
- zenURL = "<production_url>"; // Replace this string with the URL of your production helpdesk.
- }
- zenUserName = userName;
- zenPassword = password;
- }
- /// <summary>
- /// ZenAuth is a general authentication call for your application. This is essentially your
- /// "application login", and should be executed once before any commands are posted against the
- /// ZenDesk API to speed up the initial call.
- ///
- /// Remember, your user account must have "all ticket" access for this to work. This is the best
- /// method I've found for authenticating a user against ZenDesk.
- /// </summary>
- /// <returns>
- /// On a successful connection, return the ZenDesk Status code. You must handle the status
- /// outside of this class.
- ///
- /// Note: It is possible to get a Status response that does NOT authenticate you, make sure you stay
- /// current with the ZenDesk REST API.
- /// </returns>
- public string ZenAuth()
- {
- WebClient zenWeb = zenClient(); // See zenClient below for further description.
- // The next two lines formulate a GET request using the URL we specified at object creation
- // as well as the "users.xml" file we use for simple authentication.
- String zenFile = "users.xml";
- String zenRequest = zenURL + zenFile;
- // This gracefully executes a GET request, and will degrade without an application crash.
- try
- {
- zenWeb.DownloadData(zenRequest); // Start the GET request.
- return zenWeb.ResponseHeaders["Status"]; // Returns your status code. You want to be
- // Checking for a 200 OK.
- }
- catch (Exception e)
- {
- return "Error"; // Self explanatory. Handle your error properly.
- }
- }
- /// <summary>
- /// This method performs two functions: the first is to create a new ticket, using an XML-structured POST.
- /// The second function is to return the ticket number for application usage.
- /// </summary>
- /// <param name="userName">This is the email you will be creating a ticket for.</param>
- /// <param name="displayName">How do you want to display the name in ZenDesk?</param>
- /// <returns>Status Code for action.</returns>
- public String ZenSubmit(String userName, String displayName)
- {
- WebClient zenWeb = zenClient(); // See zenClient below for more information.
- // The following lines structure a POST request against tickets.xml. I've also accounted
- // for an additional custom ticket field you may have in your helpdesk.
- String zenFile = "tickets.xml";
- String zenRequest = zenURL + zenFile;
- String customTicketField = "";
- // Remember, "reg" is reading from my app.config-- I strongly recommend using another
- // method to store your user session.
- if (reg.ReturnAppSettings("userName") == "<specificUser1>") // Check for specific user
- // Enter user specific custom field.
- {
- customTicketField = @"<ticket-field-entry>
- <ticket-field-id>[ID for custom ticket field.]</ticket-field-id>
- <value>[tag for custom ticket field]</value>
- </ticket-field-entry>";
- }
- else if (reg.ReturnAppSettings("userName") == "<specificUser2>") // See above.
- {
- customTicketField = @"<ticket-field-entry>
- <ticket-field-id>[ID for custom ticket field.]</ticket-field-id>
- <value>[tag for custom ticket field]</value>
- </ticket-field-entry>";
- }
- else
- {
- customTicketField = ""; // Do not enter custom field.
- }
- // The String Literal below constructs the XML needed for a successful POST, based on the
- // fields we've already populated above.
- String createTicketXML = @"<ticket>
- <subject>[Ticket Subject]</subject>
- <description>[Body of ticket]</description>
- <requester-name>" + displayName + @"</requester-name>
- <requester-email>" + userName + @"</requester-email>
- <set-tags>[tag to set, if any]</set-tags>
- <ticket-field-entries type=""array"">
- " + customTicketField + @"
- </ticket-field-entries>
- </ticket>";
- zenWeb.UploadString(zenRequest, createTicketXML); // Execute the POST request, and hopefully create ticket.
- // If the ticket is created successfully, return the ticket number.
- // Check the REST API frequently in case the location of the ticket changes.
- if (zenWeb.ResponseHeaders["Status"] == "201 Created")
- {
- zenTicketURL = zenWeb.ResponseHeaders["Location"]; // Returns the ticket location in XML.
- // The ticket number is extracted by removing the URL we are using, followed by the tickets/ URI,
- // and finally by stripping ".xml" from the remaining string. Again, all of these locations are
- // documented in the REST API for ZenDesk.
- int URLcount = CountChars(zenURL + "tickets/");
- String returnVar = zenTicketURL;
- returnVar = returnVar.Remove(0, URLcount);
- char[] xmlChar = { '.', 'x', 'm', 'l' };
- returnVar = returnVar.TrimEnd(xmlChar);
- return returnVar;
- }
- else
- {
- return "FAIL"; // Ticket creation unsuccessful.
- }
- }
- /// <summary>
- /// This is just an accessory method to get the last ticket created, should you ever need to.
- /// </summary>
- /// <returns>XML return of last ticket created.</returns>
- public String getTicket() {
- return zenTicketURL;
- }
- /// <summary>
- /// This method is the most important one in the entire class. Instead of creating a WebClient for every single
- /// action I had to take, I opted instead to set the basics up in zenClient, which can then be object referenced
- /// with every new call, and extended. This also promises proper garbage collection from the program, disposing of
- /// queries after they have been executed.
- /// </summary>
- /// <returns>Default settings for all WebClients</returns>
- private WebClient zenClient()
- {
- WebClient zenPrimaryClient = new WebClient(); // WebClient will provide transport for GET/POST commands.
- zenPrimaryClient.Credentials = new System.Net.NetworkCredential(zenUserName, zenPassword); // Secures UserName and Password for usage.
- zenPrimaryClient.Headers.Add("Content-Type", "application/xml"); // Set your MIME type.
- zenPrimaryClient.BaseAddress = zenURL; // Set the Base URL for all commands.
- return zenPrimaryClient; // Return all settings.
- }
- /// <summary>
- /// Generic method to count all characters in a string, and account for all spaces.
- /// Recommended for usage with URLs.
- /// </summary>
- /// <param name="value">URL to check</param>
- /// <returns>Characters in String/URL</returns>
- static int CountChars(string value)
- {
- int result = 0;
- bool lastWasSpace = false;
- foreach (char c in value)
- {
- if (char.IsWhiteSpace(c))
- {
- if (lastWasSpace == false)
- {
- result++;
- }
- lastWasSpace = true;
- }
- else
- {
- result++;
- lastWasSpace = false;
- }
- }
- return result;
- }
- #region Declarations
- private String zenTicketURL;
- private String zenUserName;
- private String zenPassword;
- private String zenURL;
- #endregion
- }
- }
Add Comment
Please, Sign In to add comment