public async Task TestTeamsResultException()
        {
            try
            {
                var teams = TeamsAPI.CreateVersion1Client("this token does not exist");

                var result = await teams.GetMeAsync();

                var me = result.GetData();
            }
            catch (TeamsResultException sre)
            {
                Assert.AreEqual(System.Net.HttpStatusCode.Unauthorized, sre.HttpStatusCode);
                Assert.AreEqual("The request requires a valid access token set in the Authorization request header.", sre.Message);
                Assert.IsNotNull(sre.TrackingId);
            }

            try
            {
                var result = await teams.CreateMessageAsync("this space id does not exist", "hello");

                var m = result.GetData();
            }
            catch (TeamsResultException sre)
            {
                Assert.AreEqual(System.Net.HttpStatusCode.NotFound, sre.HttpStatusCode);
                //Assert.AreEqual("The requested resource could not be found.(ErrorCode:1)", sre.Message);
                Assert.IsTrue(sre.Message.StartsWith("The requested resource could not be found."));
                Assert.IsNotNull(sre.TrackingId);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WebexClientWrapper"/> class.
        /// Creates a Webex Client Wrapper. See <see cref="WebexAdapterOptions"/> for a full definition of the allowed parameters.
        /// </summary>
        /// <param name="config">An object containing API credentials, a webhook verification token and other options.</param>
        public WebexClientWrapper(WebexAdapterOptions config)
        {
            _config = config ?? throw new ArgumentNullException(nameof(config));

            if (string.IsNullOrWhiteSpace(_config.AccessToken))
            {
                throw new ArgumentException(nameof(config.AccessToken));
            }

            if (_config.PublicAddress == null)
            {
                throw new ArgumentException(nameof(config.PublicAddress));
            }

            _api = TeamsAPI.CreateVersion1Client(_config.AccessToken);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="WebexClientWrapper"/> class.
        /// Creates a Webex Client Wrapper. See <see cref="WebexAdapterOptions"/> for a full definition of the allowed parameters.
        /// </summary>
        /// <param name="options">An object containing API credentials, a webhook verification token and other options.</param>
        public WebexClientWrapper(WebexAdapterOptions options)
        {
            Options = options ?? throw new ArgumentNullException(nameof(options));

            if (string.IsNullOrWhiteSpace(Options.WebexAccessToken))
            {
                throw new ArgumentException(nameof(options.WebexAccessToken));
            }

            if (Options.WebexPublicAddress == null)
            {
                throw new ArgumentException(nameof(options.WebexPublicAddress));
            }

            _api = TeamsAPI.CreateVersion1Client(Options.WebexAccessToken);
        }
Beispiel #4
0
        public static async Task Init(TestContext testContext)
        {
            byte[] encryptedInfo;
            byte[] entropy;

            Person me = null;

            try
            {
                string userDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);

                var dirInfo = new DirectoryInfo(String.Format("{0}{1}.thrzn41{1}unittest{1}teams", userDir, Path.DirectorySeparatorChar));

                using (var stream = new FileStream(String.Format("{0}{1}teamsinfo.dat", dirInfo.FullName, Path.DirectorySeparatorChar), FileMode.Open, FileAccess.Read, FileShare.Read))
                    using (var memory = new MemoryStream())
                    {
                        stream.CopyTo(memory);

                        encryptedInfo = memory.ToArray();
                    }

                using (var stream = new FileStream(String.Format("{0}{1}infoentropy.dat", dirInfo.FullName, Path.DirectorySeparatorChar), FileMode.Open, FileAccess.Read, FileShare.Read))
                    using (var memory = new MemoryStream())
                    {
                        stream.CopyTo(memory);

                        entropy = memory.ToArray();
                    }

                var info = TeamsObject.FromJsonString <TeamsInfo>(LocalProtectedString.FromEncryptedData(encryptedInfo, entropy).DecryptToString());

                teams = TeamsAPI.CreateVersion1Client(info.APIToken);

                var rMe = await teams.GetMeAsync();

                if (rMe.IsSuccessStatus)
                {
                    me = rMe.Data;
                }
            }
            catch (DirectoryNotFoundException) { }
            catch (FileNotFoundException) { }


            checkTeamsAPIClient(me);
        }
        /// <summary>
        /// Entry point.
        /// </summary>
        /// <param name="args">args of this app.</param>
        /// <returns>Task for async.</returns>
        static async Task MainAsync(string[] args)
        {
            /* ********************************************************
             * NOTE: THIS IS ONLY A SAMPLE.
             * I will put most codes in this Main() on purpose.
             * So, you will be able to understand the sample
             * after you read it from top to bottom.
             * You do not need to care about 'SampleUtil' in this code.
             * The 'SampleUtil' does something tedious.
             * Only you need to do to understand the sample
             * is reading this code in Main() from top to bottom.
             * *********************************************************/

            SampleUtil.ShowTitle("[S0010] Setup for samples", "Encrypt Bot token and find or create a space for the samples.");


            //////////////////////////////////
            // Read bot token from you.
            Console.WriteLine("Please copy and paste Bot token you want to use in the samples.");
            Console.WriteLine("And then, press enter key.");
            Console.Write("Bot token here> ");

            string token = Console.ReadLine();

            if (!String.IsNullOrEmpty(token))
            {
                //////////////////////////////////
                // Encrypt the token.
                var encryptedToken = LocalProtectedString.FromString(token);


                //////////////////////////////////
                // Check if the token is for bot.
                var teams = TeamsAPI.CreateVersion1Client(encryptedToken);

                var rMe = await teams.GetMeFromCacheAsync();

                if (rMe.IsSuccessStatus)
                {
                    var me = rMe.Data;

                    Console.WriteLine("-------");
                    Console.WriteLine("Name: {0}", me.DisplayName);
                    Console.WriteLine("Type: {0}", me.TypeName);
                    Console.WriteLine("-------");

                    if (me.Type != PersonType.Bot)
                    {
                        Console.WriteLine("The person is not Bot.");
                        Console.WriteLine("For most samples, the Bot account is strongly recommended.");

                        if (!SampleUtil.WaitKeyPress("Press 'y' if you want to proceed with 'Non'-bot account. Press other key to cancel.", 'y'))
                        {
                            SampleUtil.ShowMessage("Setup canceled.");
                            return;
                        }
                    }


                    //////////////////////////////////
                    // Export encrypted token data.
                    var    dir  = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));
                    string path = dir.CreateSubdirectory(".thrzn41").CreateSubdirectory("WebexTeamsAPIClientSamples").CreateSubdirectory("V1Samples").FullName;

                    using (var fs = new FileStream(String.Format("{0}{1}token.dat", path, Path.DirectorySeparatorChar), FileMode.Create, FileAccess.Write, FileShare.Read))
                    {
                        await fs.WriteAsync(encryptedToken.EncryptedData, 0, encryptedToken.EncryptedData.Length);
                    }

                    using (var fs = new FileStream(String.Format("{0}{1}entropy.dat", path, Path.DirectorySeparatorChar), FileMode.Create, FileAccess.Write, FileShare.Read))
                    {
                        await fs.WriteAsync(encryptedToken.Entropy, 0, encryptedToken.Entropy.Length);
                    }

                    Console.WriteLine("Encrypted token was exported: Path = {0}", path);


                    //////////////////////////////////////////////////////////
                    // Read Webex Teams account to add to the sample space.
                    Console.WriteLine();
                    Console.WriteLine("This app will create or find the space for the sample, and then add your Webex Teams account to the space.");
                    Console.WriteLine("Please enter your Webex Teams account(email address style).");
                    Console.Write("Enter Webex Teams account> ");

                    string teamsAccount = Console.ReadLine();

                    if (!String.IsNullOrEmpty(teamsAccount))
                    {
                        Console.WriteLine();
                        Console.WriteLine("Please confirm the Webex Teams account carefully.");
                        Console.WriteLine("This account will be added to the space for the sample.");
                        Console.WriteLine();
                        Console.WriteLine("Entered account: {0}", teamsAccount);

                        if (!SampleUtil.WaitKeyPress("Press 'y' if your Webex Teams account is correct. Press other key to cancel.", 'y'))
                        {
                            SampleUtil.ShowMessage("Setup canceled.");
                            return;
                        }

                        //////////////////////////////////
                        // Try to find the sample space.
                        Space spaceForSample = null;

                        var e = (await teams.ListSpacesAsync()).GetListResultEnumerator();

                        while (await e.MoveNextAsync())
                        {
                            var rSpaces = e.CurrentResult;

                            if (rSpaces.IsSuccessStatus && rSpaces.Data.HasItems)
                            {
                                var spaces = rSpaces.Data;

                                foreach (var item in spaces.Items)
                                {
                                    if (item.Title.EndsWith("#WebexTeamsAPIClientV1SamplesSpace"))
                                    {
                                        spaceForSample = item;
                                        break;
                                    }
                                }
                            }

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


                        //////////////////////////////////////////////////////////
                        // Create a new sample space when no sample space found.
                        if (spaceForSample == null)
                        {
                            var rSpace = await teams.CreateSpaceAsync("Webex Teams API Client Samples #WebexTeamsAPIClientV1SamplesSpace");

                            if (rSpace.IsSuccessStatus)
                            {
                                spaceForSample = rSpace.Data;
                            }
                        }

                        if (spaceForSample != null)
                        {
                            ////////////////////////////////////////////////////////
                            // Try to add Webex Teams account to the sample space.
                            var rSpaceMembership = await teams.CreateSpaceMembershipAsync(spaceForSample, teamsAccount);

                            if (rSpaceMembership.IsSuccessStatus || rSpaceMembership.HttpStatusCode == System.Net.HttpStatusCode.Conflict)
                            {
                                SampleUtil.ShowMessage("{0} was added to Space for the samples", teamsAccount);
                            }
                            else
                            {
                                SampleUtil.ShowMessage("Failed to add {0} to Space for the samples: Error = {1}", teamsAccount, rSpaceMembership.HttpStatusCode);
                            }

                            Console.WriteLine("-------");
                            Console.WriteLine("Space: {0}", spaceForSample.Title);
                            Console.WriteLine("-------");
                        }
                        else
                        {
                            SampleUtil.ShowMessage("Failed to find or create Space for the samples.");
                            return;
                        }


                        SampleUtil.ShowMessage("Setup for the samples has completed.");
                    }
                    else
                    {
                        SampleUtil.ShowMessage("Webex Teams account is null or empty.");
                        return;
                    }
                }
                else
                {
                    SampleUtil.ShowMessage("Failed to get person info from Webex Teams API service: Error = {0}", rMe.HttpStatusCode);
                    return;
                }
            }
            else
            {
                SampleUtil.ShowMessage("Token is null or empty.");
                return;
            }
        }
        public static async Task Init(TestContext testContext)
        {
            byte[] encryptedInfo;
            byte[] entropy;

            Person me = null;

            try
            {
                string userDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);

                var dirInfo = new DirectoryInfo(String.Format("{0}{1}.thrzn41{1}unittest{1}teams", userDir, Path.DirectorySeparatorChar));

                using (var stream = new FileStream(String.Format("{0}{1}teamsintegration.dat", dirInfo.FullName, Path.DirectorySeparatorChar), FileMode.Open, FileAccess.Read, FileShare.Read))
                    using (var memory = new MemoryStream())
                    {
                        stream.CopyTo(memory);

                        encryptedInfo = memory.ToArray();
                    }

                using (var stream = new FileStream(String.Format("{0}{1}integrationentropy.dat", dirInfo.FullName, Path.DirectorySeparatorChar), FileMode.Open, FileAccess.Read, FileShare.Read))
                    using (var memory = new MemoryStream())
                    {
                        stream.CopyTo(memory);

                        entropy = memory.ToArray();
                    }

                var token = TeamsObject.FromJsonString <TeamsIntegrationInfo>(LocalProtectedString.FromEncryptedData(encryptedInfo, entropy).DecryptToString());

                teams = TeamsAPI.CreateVersion1Client(token.TokenInfo, new TeamsRetryOnErrorHandler(4, TimeSpan.FromSeconds(15.0f)));

                var rMe = await teams.GetMeAsync();

                if (rMe.IsSuccessStatus)
                {
                    me = rMe.Data;

                    var e = (await teams.ListSpacesAsync(type: SpaceType.Group, sortBy: SpaceSortBy.Created, max: 50)).GetListResultEnumerator();

                    while (await e.MoveNextAsync())
                    {
                        var r = e.CurrentResult;

                        if (r.IsSuccessStatus && r.Data.HasItems)
                        {
                            foreach (var item in r.Data.Items)
                            {
                                if (item.Title.Contains(UNIT_TEST_SPACE_TAG))
                                {
                                    unitTestSpace = item;
                                    break;
                                }
                            }
                        }

                        if (unitTestSpace != null)
                        {
                            break;
                        }
                    }
                }
            }
            catch (DirectoryNotFoundException) { }
            catch (FileNotFoundException) { }

            checkTeamsAPIClient(me);
            checkUnitTestSpace();
        }
Beispiel #7
0
        /// <summary>
        /// Entry point.
        /// </summary>
        /// <param name="args">args of this app.</param>
        /// <returns>Task for async.</returns>
        static async Task MainAsync(string[] args)
        {
            /* ********************************************************
             * NOTE: THIS IS ONLY A SAMPLE.
             * I will put most codes in this Main() on purpose.
             * So, you will be able to understand the sample
             * after you read it from top to bottom.
             * You do not need to care about 'SampleUtil' in this code.
             * The 'SampleUtil' does something tedious.
             * Only you need to do to understand the sample
             * is reading this code in Main() from top to bottom.
             * *********************************************************/

            SampleUtil.ShowTitle("[S1030] Markdown Builder", "How to use markdown builder.");


            // Load encrypted token that is encrypted by 'S0010SetupSamples'.
            ProtectedString token = SampleUtil.LoadEncryptedToken();

            if (token != null)
            {
                ////////////////////////////////////////////////////////////////////////////
                // Create an instance for Webex Teams API.
                // As best practice, the instance should be re-used as long as possible.
                // For bots, the lifetime of the instance typically is almost the same as the lifetime of the app process.
                var teams = TeamsAPI.CreateVersion1Client(token);

                // Try to find Sample space.
                var space = await SampleUtil.FindSampleSpaceAsync(teams);


                if (space != null)
                {
                    ////////////////////////////////////////////////////////////////
                    // You can build markdown that can be used in Webex Teams API.
                    var md = new MarkdownBuilder();

                    // Bold
                    md.Append("Hello, Bold ").AppendBold("WebexTeams").Append("!!").AppendLine();

                    // Italic
                    md.Append("Hello, Italic ").AppendItalic("WebexTeams").Append("!!").AppendLine();

                    // Link
                    md.AppendParagraphSeparater();
                    md.AppendBlockQuote("Hi!").AppendLink("This is Link", new Uri("https://www.google.com/")).Append(".");

                    // Block Quote
                    md.AppendParagraphSeparater();
                    md.AppendBlockQuote("Hi! This is Block Quote.");

                    // Ordered List
                    md.AppendParagraphSeparater();
                    md.AppendBold("This is Ordered list:").AppendLine();
                    md.AppendOrderedList("list item 01");
                    md.AppendOrderedList("list item 02");
                    md.AppendOrderedList("list item 03");

                    // Unordered List
                    md.AppendParagraphSeparater();
                    md.AppendBold("This is Unordered list:").AppendLine();
                    md.AppendUnorderedList("list item 01");
                    md.AppendUnorderedList("list item 02");
                    md.AppendUnorderedList("list item 03");

                    // Inline Code.
                    md.AppendParagraphSeparater();
                    md.Append("The ").AppendInLineCode("print(\"Hello, World!!\")").Append(" is inline code.");

                    // Code Block.
                    md.AppendParagraphSeparater();
                    md.Append("This is Code Block:").AppendLine();
                    md.BeginCodeBlock()
                    .Append("#include <stdio.h>\n")
                    .Append("\n")
                    .Append("int main(void)\n")
                    .Append("{\n")
                    .Append("    printf(\"Hello, World!!\\n\");\n")
                    .Append("\n")
                    .Append("    return 0;\n")
                    .Append("}\n")
                    .EndCodeBlock();

                    var r = await teams.CreateMessageAsync(space, md.ToString());

                    if (r.IsSuccessStatus)
                    {
                        SampleUtil.ShowMessage("Succeeded to post a message: Id = {0}", r.Data.Id);
                    }
                    else
                    {
                        SampleUtil.ShowMessage("Failed to post a message: StatusCode = {0}", r.HttpStatusCode);
                    }



                    // Mentioned to All.
                    md.Clear();
                    md.Append("Hi ").AppendMentionToAll().Append(", this message is mentioned to all in the space.");

                    r = await teams.CreateMessageAsync(space, md.ToString());

                    if (r.IsSuccessStatus)
                    {
                        SampleUtil.ShowMessage("Succeeded to post a message: Id = {0}", r.Data.Id);
                    }
                    else
                    {
                        SampleUtil.ShowMessage("Failed to post a message: StatusCode = {0}", r.HttpStatusCode);
                    }
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Entry point.
        /// </summary>
        /// <param name="args">args of this app.</param>
        /// <returns>Task for async.</returns>
        static async Task MainAsync(string[] args)
        {
            /* ********************************************************
             * NOTE: THIS IS ONLY A SAMPLE.
             * I will put most codes in this Main() on purpose.
             * So, you will be able to understand the sample
             * after you read it from top to bottom.
             * You do not need to care about 'SampleUtil' in this code.
             * The 'SampleUtil' does something tedious.
             * Only you need to do to understand the sample
             * is reading this code in Main() from top to bottom.
             * *********************************************************/

            SampleUtil.ShowTitle("[S1020] Check if a request suceeded or not", "Sample to check if a request suceeded or not, or handle TeamsResultException.");


            // Load encrypted token that is encrypted by 'S0010SetupSamples'.
            ProtectedString token = SampleUtil.LoadEncryptedToken();

            if (token != null)
            {
                ////////////////////////////////////////////////////////////////////////////
                // Create an instance for Webex Teams API.
                // As best practice, the instance should be re-used as long as possible.
                // For bots, the lifetime of the instance typically is almost the same as the lifetime of the app process.
                var teams = TeamsAPI.CreateVersion1Client(token);

                // Try to find Sample space.
                var space = await SampleUtil.FindSampleSpaceAsync(teams);


                if (space != null)
                {
                    /////////////////////////////////////////////////////////////////////
                    // result.IsSuccessStatus indicates the request succeeded or not.
                    var r = await teams.CreateMessageAsync(space, "This message will be posted.");

                    if (r.IsSuccessStatus)
                    {
                        SampleUtil.ShowMessage("Succeeded to post a message: Id = {0}", r.Data.Id);
                    }
                    else
                    {
                        SampleUtil.ShowMessage("Failed to post a message: StatusCode = {0}, TrackingId = {1}", r.HttpStatusCode, r.TrackingId);
                    }


                    /////////////////////////////////////////////////////////////////////
                    // This request will not succeed because the space id is invalid.
                    r = await teams.CreateMessageAsync("invalid_space_id", "Bacause of invalid space id, this message will not be posted.");

                    if (r.IsSuccessStatus)
                    {
                        SampleUtil.ShowMessage("Succeeded to post a message: Id = {0}", r.Data.Id);
                    }
                    else
                    {
                        SampleUtil.ShowMessage("Failed to post a message: StatusCode = {0}, TrackingId = {1}", r.HttpStatusCode, r.TrackingId);
                    }


                    ////////////////////////////////////////////////////////////////////////
                    // result.GetData() throws TeamsResultException on error response.
                    // On the other hands, result.Data does not throw TeamsResultException.
                    try
                    {
                        r = await teams.CreateMessageAsync("invalid_space_id", "Bacause of invalid space id, this message will not be posted.");


                        /////////////////////////////////////////////////////
                        // This does not throw TeamsResultException.
                        // And empty id will be shown.
                        var message = r.Data;
                        SampleUtil.ShowMessage("Message id by r.Data.Id = {0}", message.Id);


                        /////////////////////////////////////////////////////
                        // This throws TeamsResultException.
                        // So, the id will not be shown.
                        message = r.GetData();
                        SampleUtil.ShowMessage("Message id by r.GetData().Id = {0}", message.Id);
                    }
                    catch (TeamsResultException tre)
                    {
                        SampleUtil.ShowMessage("{0}: StatusCode = {1}, TrackingId = {2}",
                                               tre.Message,
                                               tre.HttpStatusCode,
                                               tre.TrackingId);
                    }
                }
            }
        }
Beispiel #9
0
        private async void buttonCreate_Click(object sender, EventArgs e)
        {
            try
            {
                bool isSucceeded = false;

                this.textBoxClientId.Enabled     = false;
                this.textBoxClientSecret.Enabled = false;
                this.textBoxOAuthUrl.Enabled     = false;
                this.textBoxRedirectUri.Enabled  = false;

                this.buttonCreate.Enabled = false;

                var form = new AuthForm(new Uri(this.textBoxOAuthUrl.Text));

                var result = form.ShowDialog();

                if (result == DialogResult.OK)
                {
                    var oauth2 = TeamsAPI.CreateVersion1OAuth2Client(
                        this.textBoxClientSecret.Text,
                        this.textBoxClientId.Text,
                        new TeamsRetryOnErrorHandler(4, TimeSpan.FromSeconds(15.0f)));

                    var r = await oauth2.GetTokenInfoAsync(
                        form.Code,
                        this.textBoxRedirectUri.Text.Trim());

                    if (r.IsSuccessStatus)
                    {
                        var info = new TeamsIntegrationInfo();

                        info.ClientId     = this.textBoxClientId.Text;
                        info.ClientSecret = this.textBoxClientSecret.Text;
                        info.OAuthUrl     = this.textBoxOAuthUrl.Text;
                        info.RedirectUri  = this.textBoxRedirectUri.Text;

                        info.TokenInfo = r.Data;


                        DirectoryInfo exportDir = this.dirInfo.CreateSubdirectory(".thrzn41").CreateSubdirectory("unittest").CreateSubdirectory("teams");

                        var s = info.ToJsonString();

                        LocalProtectedString ps = LocalProtectedString.FromString(info.ToJsonString());

                        using (var fs = new FileStream(String.Format("{0}{1}teamsintegration.dat", exportDir.FullName, Path.DirectorySeparatorChar), FileMode.Create, FileAccess.Write, FileShare.None))
                        {
                            await fs.WriteAsync(ps.EncryptedData, 0, ps.EncryptedData.Length);
                        }

                        using (var fs = new FileStream(String.Format("{0}{1}integrationentropy.dat", exportDir.FullName, Path.DirectorySeparatorChar), FileMode.Create, FileAccess.Write, FileShare.None))
                        {
                            await fs.WriteAsync(ps.Entropy, 0, ps.Entropy.Length);
                        }


                        isSucceeded = true;
                    }
                }

                MessageBox.Show((isSucceeded ? AppMessages.CreateSucceeded : AppMessages.CreateFailed));
            }
            finally
            {
                this.buttonCreate.Enabled = true;

                this.textBoxRedirectUri.Enabled  = true;
                this.textBoxOAuthUrl.Enabled     = true;
                this.textBoxClientSecret.Enabled = true;
                this.textBoxClientId.Enabled     = true;
            }
        }
        /// <summary>
        /// Entry point.
        /// </summary>
        /// <param name="args">args of this app.</param>
        /// <returns>Task for async.</returns>
        static async Task MainAsync(string[] args)
        {
            /* ********************************************************
             * NOTE: THIS IS ONLY A SAMPLE.
             * I will put most codes in this Main() on purpose.
             * So, you will be able to understand the sample
             * after you read it from top to bottom.
             * You do not need to care about 'SampleUtil' in this code.
             * The 'SampleUtil' does something tedious.
             * Only you need to do to understand the sample
             * is reading this code in Main() from top to bottom.
             * *********************************************************/

            SampleUtil.ShowTitle("[S1040] ListResult Enumerator(Pagination)", "Get first list result, and then get next list result...");


            // Load encrypted token that is encrypted by 'S0010SetupSamples'.
            ProtectedString token = SampleUtil.LoadEncryptedToken();

            if (token != null)
            {
                ////////////////////////////////////////////////////////////////////////////
                // Create an instance for Webex Teams API.
                // As best practice, the instance should be re-used as long as possible.
                // For bots, the lifetime of the instance typically is almost the same as the lifetime of the app process.
                var teams = TeamsAPI.CreateVersion1Client(token);


                /////////////////////////////////////////////////////
                // Create 4 temporary spaces for the sample.
                for (int i = 0; i < 4; i++)
                {
                    string title = String.Format("Sample Temporary Space-{0} #WebexTeamsAPIClientV1SamplesTemporary", i);


                    SampleUtil.ShowMessage("Create a Space: {0}", title);

                    var r = await teams.CreateSpaceAsync(title);

                    if (r.IsSuccessStatus)
                    {
                        SampleUtil.ShowMessage("Succeeded to create space.");
                    }
                    else
                    {
                        SampleUtil.ShowMessage("Failed to create space, StatusCode = {0}", r.HttpStatusCode);
                    }
                }


                /////////////////////////////////////////////////////
                // List spaces for each 2 spaces.
                // In this case, 'max: 2' parameter is set.
                var e = (await teams.ListSpacesAsync(
                             max: 2,
                             type: SpaceType.Group,
                             sortBy: SpaceSortBy.Created)
                         ).GetListResultEnumerator();

                // In this sample, give up iteration after getting 4 spaces.
                int count = 4;

                // Iterate list result.
                while (await e.MoveNextAsync())
                {
                    // Get current result.
                    var r = e.CurrentResult;

                    if (r.IsSuccessStatus && r.Data.HasItems)
                    {
                        SampleUtil.ShowMessage("Succeeded to get {0} spaces.", r.Data.ItemCount);

                        foreach (var space in r.Data.Items)
                        {
                            SampleUtil.ShowMessage("  Title: {0}", space.Title);
                            count--;
                        }
                    }

                    if (count <= 0)
                    {
                        break;
                    }
                }



                /////////////////////////////////////////////////////
                // Clean up the temporary created spaces.
                SampleUtil.ShowMessage("Cleaning up the temporary created spaces.");

                var temporarySpaces = new List <Space>();

                /////////////////////////////////////////////////////
                // Try to find all the temporary created spaces.
                e = (await teams.ListSpacesAsync(type: SpaceType.Group)).GetListResultEnumerator();

                while (await e.MoveNextAsync())
                {
                    var r = e.CurrentResult;

                    if (r.IsSuccessStatus && r.Data.HasItems)
                    {
                        foreach (var space in r.Data.Items)
                        {
                            if (space.Title.Contains("#WebexTeamsAPIClientV1SamplesTemporary"))
                            {
                                temporarySpaces.Add(space);
                            }
                        }
                    }
                }

                /////////////////////////////////////////////////////
                // Delete the temporary created spaces found.
                foreach (var space in temporarySpaces)
                {
                    SampleUtil.ShowMessage("Deleting {0}", space.Title);

                    var r = await teams.DeleteSpaceAsync(space);

                    if (r.IsSuccessStatus)
                    {
                        SampleUtil.ShowMessage("Succeeded to delete space.");
                    }
                    else
                    {
                        SampleUtil.ShowMessage("Failed to delete space, StatusCode = {0}", r.HttpStatusCode);
                    }
                }
            }
        }
        /// <summary>
        /// Entry point.
        /// </summary>
        /// <param name="args">args of this app.</param>
        /// <returns>Task for async.</returns>
        static async Task MainAsync(string[] args)
        {
            /* ********************************************************
             * NOTE: THIS IS ONLY A SAMPLE.
             * I will put most codes in this Main() on purpose.
             * So, you will be able to understand the sample
             * after you read it from top to bottom.
             * You do not need to care about 'SampleUtil' in this code.
             * The 'SampleUtil' does something tedious.
             * Only you need to do to understand the sample
             * is reading this code in Main() from top to bottom.
             * *********************************************************/

            SampleUtil.ShowTitle("[S1010] Post a message", "Post a message to Sample space.");


            // Load encrypted token that is encrypted by 'S0010SetupSamples'.
            ProtectedString token = SampleUtil.LoadEncryptedToken();

            if (token != null)
            {
                ////////////////////////////////////////////////////////////////////////////
                // Create an instance for Webex Teams API.
                // As best practice, the instance should be re-used as long as possible.
                // For bots, the lifetime of the instance typically is almost the same as the lifetime of the app process.
                var teams = TeamsAPI.CreateVersion1Client(token);

                // Try to find Sample space.
                var space = await SampleUtil.FindSampleSpaceAsync(teams);


                if (space != null)
                {
                    /////////////////////////////////////////////////////////////////
                    // By default, the API Client posts a message as markdown.
                    var r = await teams.CreateMessageAsync(space, "Hello, **Webex Teams**!!");

                    if (r.IsSuccessStatus)
                    {
                        SampleUtil.ShowMessage("Succeeded to post a message: Id = {0}", r.Data.Id);
                    }
                    else
                    {
                        SampleUtil.ShowMessage("Failed to post a message: StatusCode = {0}", r.HttpStatusCode);
                    }


                    /////////////////////////////////////////////////////////////////
                    // To post a message as normal text, use 'textType: MessageTextType.Text' parameter.
                    r = await teams.CreateMessageAsync(space, "Hello, **Webex Teams**!!", textType : MessageTextType.Text);

                    if (r.IsSuccessStatus)
                    {
                        SampleUtil.ShowMessage("Succeeded to post a message: Id = {0}", r.Data.Id);
                    }
                    else
                    {
                        SampleUtil.ShowMessage("Failed to post a message: StatusCode = {0}", r.HttpStatusCode);
                    }
                }
            }
        }