Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8059101
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 5, 20262026-06-05T09:33:57+00:00 2026-06-05T09:33:57+00:00

I am attempting to retrieve the most recent date that my users have logged

  • 0

I am attempting to retrieve the most recent date that my users have logged into any Google app service such as Gmail (or had this done for them via mobile device/imap/pop etc). I am an administrator of the domain on Google apps for Education and using the C# gdata-api.

I would like to recycle student usernames if they have been gone for longer than a year without signing into their gmail apps and require the last accessed date to accomplish this.

Please let me know if this is possible

Thank you.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-05T09:33:59+00:00Added an answer on June 5, 2026 at 9:33 am

    I used the gmail reporting API. I forget where I got this from but I stole it from somewhere. If you know where, please put a comment link.

     /// <summary>
        /// This contains the logic for constructing and submitting a report 
        /// request to the Google Apps reporting service and reading the response.
        ///
        /// The description of the web service protocol can be found at:
        ///
        /// http://code.google.com/apis/apps/reporting/google_apps_reporting_api.html
        /// 
        /// Example usage:
        /// Get the latest accounts report to standard output.
        ///   client.getReport("accounts", null, null);
        /// Get the accounts report for May 15, 2007 and save it to out.txt.
        ///   client.getReport("accounts", "2007-05-15", "out.txt");
        /// </summary>
        public class ReportsManager
        {
            /// <summary>
            /// URL to POST to obtain an authentication token
            /// </summary>
            private const string CLIENT_LOGIN_URL =
              "https://www.google.com/accounts/ClientLogin";
    
            /// <summary>
            /// URL to POST to retrive resports from the API 
            /// </summary>
            private const string REPORTING_URL =
              "https://www.google.com/hosted/services/v1.0/reports/ReportingData";
    
            /// <summary>
            /// Date format of the API
            /// </summary>
            private const string DATE_FORMAT = "yyyy-MM-dd";
    
            /// <summary>
            /// Hour of the day when the API data gets published
            /// </summary>
            private const int PUBLISH_HOUR_OF_DAY = 13; // Publish hour + 1 hour;
    
            /// <summary>
            /// Time diference to UTC
            /// </summary>
            private const int PUBLISH_TIME_DIFERENCE_TO_UTC = -8;
    
            /// <summary>
            /// Email command-line argument
            /// </summary>
            private const string EMAIL_ARG = "email";
    
            /// <summary>
            /// Password command-line argument
            /// </summary>
            private const string PASSWORD_ARG = "password";
    
            /// <summary>
            /// Domain command-line argument
            /// </summary>
            private const string DOMAIN_ARG = "domain";
    
            /// <summary>
            /// Report command-line argument
            /// </summary>
            private const string REPORT_ARG = "report";
    
            /// <summary>
            /// Date command-line argument
            /// </summary>
            private const string DATE_ARG = "date";
    
            /// <summary>
            /// Output File command-line argument
            /// </summary>
            private const string OUT_FILE_ARG = "out";
    
            /// <summary>
            /// Message for command-line usage
            /// </summary>
            private const string USAGE = "Usage:  " +
              "ReportingAPI --" + EMAIL_ARG + " <email> --" +
              PASSWORD_ARG + " <password> [ --" +
              DOMAIN_ARG + " <domain> ] --" +
              REPORT_ARG + " <report name> [ --" +
              DATE_ARG + " <YYYY-MM-DD> ] [ --" +
              OUT_FILE_ARG + " <file name> ]";
    
            /// <summary>
            /// List of command-line arguments
            /// </summary>
            private static string[] PROPERTY_NAMES = new String[] {EMAIL_ARG,
              PASSWORD_ARG, DOMAIN_ARG, REPORT_ARG, DATE_ARG, OUT_FILE_ARG};
    
            /// <summary>
            /// List of required command-line arguments
            /// </summary>
            private static string[] REQUIRED_PROPERTY_NAMES = new String[] {
              EMAIL_ARG, PASSWORD_ARG, REPORT_ARG};
    
            /// <summary>
            /// Google Apps Domain
            /// </summary>
            public string domain = null;
    
            /// <summary>
            /// Email address of an Administrator account
            /// </summary>
            public string email = null;
    
            /// <summary>
            /// Password of the Administrator account
            /// </summary>
            public string password = null;
    
            /// <summary>
            /// Identifies the type of account
            /// </summary>
            private string accountType = "HOSTED";
    
            /// <summary>
            /// Identifies the Google service
            /// </summary>
            private string service = "apps";
    
            /// <summary>
            /// Contains a token value that Google uses to authorize 
            /// access to the requested report data
            /// </summary>
            private string token = null;
    
            /// <summary>
            /// Default constructor
            /// </summary>
            public ReportsManager(string username, string password, string domain)
            {
                this.email = username + "@" + domain;
                this.password = password;
                this.domain = domain;
            }
    
            /// <summary>
            /// Retrieves the Authentication Token
            /// </summary>
            /// <returns>Returns the authentication token.</returns>
            public string GetToken()
            {
                return this.token;
            }
    
            /// <summary>
            /// Logs in the user and initializes the Token
            /// </summary>
            public void ClientLogin()
            {
                string token = null;
                UTF8Encoding encoding = new UTF8Encoding();
                string postData = "Email=" + System.Web.HttpUtility.UrlEncode(this.email) +
                  "&Passwd=" + System.Web.HttpUtility.UrlEncode(this.password) +
                  "&accountType=" + System.Web.HttpUtility.UrlEncode(this.accountType) +
                  "&service=" + System.Web.HttpUtility.UrlEncode(this.service);
                byte[] data = encoding.GetBytes(postData);
                HttpWebRequest request =
                  (HttpWebRequest)WebRequest.Create(CLIENT_LOGIN_URL);
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = data.Length;
                Stream inputStream = request.GetRequestStream();
                inputStream.Write(data, 0, data.Length);
                inputStream.Close();
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                string responseStr = (new StreamReader(
                  response.GetResponseStream())).ReadToEnd();
                char[] tokenizer = { '\r', '\n' };
                string[] parts = responseStr.Split(tokenizer);
                foreach (string part in parts)
                {
                    if (part.StartsWith("SID="))
                    {
                        token = part.Substring(4);
                        break;
                    }
                }
                this.token = token;
            }
    
            /// <summary>
            /// Creates a XML request for the Report
            /// </summary>
            /// <param name="reportName">The name of the Report: activity, 
            ///   disk_space, email_clients, quota_limit_accounts, 
            ///   summary, suspended_account</param>
            /// <param name="date">Date of the Report</param>
            /// <returns>Thx XML request as a string</returns>
            public string createRequestXML(string reportName, string date)
            {
                if (this.domain == null)
                {
                    this.domain = getAdminEmailDomain();
                }
                string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
                xml += "<rest xmlns=\"google:accounts:rest:protocol\"";
                xml += " xmlns:xsi=\"";
                xml += "http://www.w3.org/2001/XMLSchema-instance\">";
                xml += "<type>Report</type>";
                xml += "<token>" + this.GetToken() + "</token>";
                xml += "<domain>" + this.domain + "</domain>";
                xml += "<date>" + date + "</date>";
                xml += "<reportType>daily</reportType>";
                xml += "<reportName>" + reportName + "</reportName>";
                xml += "</rest>";
                return xml;
            }
    
            /// <summary>
            /// Get the domain of the admin's email address.
            /// </summary>
            /// <returns>the domain, otherwise returns null</returns>
            public string getAdminEmailDomain()
            {
                if (this.email != null)
                {
                    int atIndex = this.email.IndexOf('@');
                    if (atIndex > 0 && atIndex + 1 < this.email.Length)
                    {
                        return this.email.Substring(atIndex + 1);
                    }
                }
                else
                {
                    throw new ArgumentNullException("Invalid Email");
                }
                return null;
            }
    
            public enum ReportType
            {
                accounts,
                activity,
                disk_space,
                email_clients,
                quota_limit_accounts,
                summary,
                suspended_account
            }
    
            /// <summary>
            /// Get the reports by reportName for a Date, and writes the report
            /// at filename         /// or to the console if filename is null.
            /// </summary>
            /// <param name="reportName">The name of the Report: activity, 
            ///   disk_space, email_clients, quota_limit_accounts,summary,
            ///   suspended_account</param>
            /// <param name="date">Date of the Report, 
            ///   null date gets latest date available</param>
            private Dictionary<string, ArrayList> getReport(string reportName, string date)
            {
                if (date == null)
                {
                    date = getLatestReportDate().ToString(DATE_FORMAT);
                }
                else
                {
                    try
                    {
                        date = System.Convert.ToDateTime(date).ToString
                          (DATE_FORMAT);
                    }
                    catch
                    {
                        throw new ArgumentException("Invalid Date");
                    }
                }
                string xml = createRequestXML(reportName, date);
                HttpWebRequest request =
                  (HttpWebRequest)WebRequest.Create(REPORTING_URL);
                request.Method = "POST";
                UTF8Encoding encoding = new UTF8Encoding();
                byte[] postBuffer = encoding.GetBytes(xml);
                request.ContentLength = postBuffer.Length;
                request.ContentType = "application/x-www-form-urlencoded";
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(postBuffer, 0, postBuffer.Length);
                requestStream.Close();
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                StreamReader reader = new StreamReader(
                  response.GetResponseStream());
                String firstLine = null;
                String lineBuffer = String.Empty;
                if (reader.Peek() >= 0)
                {
                    firstLine = reader.ReadLine();
                    checkError(firstLine, reader);
                }
    
                Dictionary<string, ArrayList> csv = new Dictionary<string, ArrayList>();
                string[] headers = null;
                if (firstLine != null)
                {
                    headers = firstLine.Split(',');
                    foreach (string header in headers)
                    {
                        csv.Add(header, new ArrayList());
                    }
                }
                if (headers != null)
                {
                    while ((lineBuffer = reader.ReadLine()) != null)
                    {
                        string[] dataLine = lineBuffer.Split(',');
                        for (int i = 0; i < csv.Keys.Count; i++)
                        {
                            csv[headers[i]].Add(dataLine[i]);
                        }
                    }
                }
                reader.Close();
                return csv;
            }
    
            /// <summary>
            /// Get the reports by reportName for a Date, and writes the report 
            /// at filename or to the console if filename is null.
            /// </summary>
            /// <param name="reportName">The name of the Report: activity, 
            ///   disk_space, email_clients, quota_limit_accounts,summary,
            ///   suspended_account</param>
            /// <param name="date">
            ///   Date of the Report, null date gets latest date available</param>
            public Dictionary<string, ArrayList> getReport(ReportType reportType, DateTime date)
            {
                string reportName = Enum.GetName(typeof(ReportType), reportType);
                return this.getReport(reportName, date.ToString(DATE_FORMAT));
            }
    
            /// <summary>
            /// Checks for errors on the Http Response, errors are on XML format.
            /// When the response is xml throws an Exception with the xml text.
            /// </summary>
            /// <param name="firstLine">
            ///   First line of the StreamReader from the Http Response</param>
            /// <param name="reader">StreamReader from the Http Response</param>
            private void checkError(string firstLine, StreamReader reader)
            {
                if (firstLine.Trim().StartsWith("<?xml"))
                {
                    String xmlText = firstLine;
                    while (reader.Peek() >= 0)
                    {
                        xmlText += reader.ReadLine();
                    }
                    throw new Exception(xmlText);
                }
            }
    
            /// <summary>
            /// Get latest available report date, 
            /// based on report service time zone.
            /// Reports for the current date are available after 12:00 PST8PDT 
            /// the following day.
            /// </summary>
            /// <returns>Lastest date available</returns>
            public DateTime getLatestReportDate()
            {
                if (DateTime.UtcNow.AddHours(PUBLISH_TIME_DIFERENCE_TO_UTC).Hour
                  < PUBLISH_HOUR_OF_DAY)
                {
                    return DateTime.Now.AddDays(-2);
                }
                else
                {
                    return DateTime.Now.AddDays(-1);
                }
            }
    
            /// <summary>
            /// Gets the properties from the command-line arguments.
            /// </summary>
            /// <param name="args">command-line arguments</param>
            /// <returns>Properties Hashtable</returns>
            private static Hashtable getProperties(string[] args)
            {
                Hashtable properties = new Hashtable();
                for (int i = 0; i < args.Length; i++)
                {
                    bool found = false;
                    for (int j = 0; j < PROPERTY_NAMES.Length; j++)
                    {
                        if (args[i].Equals("--" + PROPERTY_NAMES[j]))
                        {
                            found = true;
                            if (i + 1 < args.Length)
                            {
                                properties.Add(PROPERTY_NAMES[j], args[i + 1]);
                                i++;
                                break;
                            }
                            else
                            {
                                throw new ArgumentException("Missing value for " +
                                  "command-line parameter " + args[i]);
                            }
                        }
                    }
                    if (!found)
                    {
                        throw new ArgumentException(
                          "Unrecognized parameter " + args[i]);
                    }
                }
                for (int i = 0; i < REQUIRED_PROPERTY_NAMES.Length; i++)
                {
                    if (properties[REQUIRED_PROPERTY_NAMES[i]] == null)
                    {
                        throw new ArgumentException("Missing value for " +
                          "command-line parameter " + REQUIRED_PROPERTY_NAMES[i]);
                    }
                }
                return properties;
            }
        }
    

    To use it:

    ReportsManager reports = new ReportsManager("*", "*", "*");
                reports.ClientLogin();
                Dictionary<string, ArrayList> accountReport = reports.getReport(ReportsManager.ReportType.accounts, DateTime.Today);
                int count = accountReport["account_name"].Count;
                Hashtable usersLastLoggedIn = new Hashtable();
                for (int i = 0; i < count; i++)
                {
                    DateTime lastLogged = DateTime.Parse(accountReport["last_login_time"][i].ToString());
                    DateTime lastWebMail = DateTime.Parse(accountReport["last_web_mail_time"][i].ToString());
                    DateTime lastPop = DateTime.Parse(accountReport["last_pop_time"][i].ToString());
                    if (lastWebMail > lastLogged) { lastLogged = lastWebMail; }
                    if (lastPop > lastLogged) { lastLogged = lastPop; }
                    usersLastLoggedIn.Add(accountReport["account_name"][i].ToString().Replace('@' + ConfigurationManager.AppSettings["domain"], string.Empty), lastLogged);
                }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have an sql statement as below attempting to retrieve the most recent entries
In Python, I'm attempting to retrieve the date/time that is exactly 30 days (30*24hrs)
Attempting to use XStream's JavaBeanConverter and running into an issue. Most likely I'm missng
I'm attempting to retrieve a url parameter within a CometActor to validate that the
I am attempting to retrieve the google email address when making an OAuth2.0 call
I have a Silverlight application that needs to retrieve some data from my database.
I have an ASP.NET C# website and I am attempting to retrieve the inner
I have been able to retrieve values into my form.The values are inserted into
I am attempting to write a script that can retrieve the HTML from my
I have an app that is running fine in the iPhone simulator by way

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.