Sample code for C# csharp with Zoom API / Zoom SDK

This is a sample code page for C# csharp. It shows the common code sample when interacting with Zoom Webhook, Zoom Meeting SDK Auth Signature, Zoom OAuth and Zoom REST API.

Github Link

github source code

Live Demo

Webhook
Get access token from S2S OAuth
Redirect URL for OAuth
Refresh Token for OAuth
Call API
Meeting SDK

application adding url

Code Samples

Tab 1 Content



using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
public static class webhook
{
    public static Task GetWebhook(HttpContext context)
    {
        return Task.Run(() =>
        {
            // Handle GET request logic here
            context.Response.WriteAsync("GET request received.");
        });
    }

    public static Task PostWebhook(HttpContext context)
    {
        return Task.Run(async () =>
        {
            // Get the request content as a string asynchronously
            string requestBody = await new StreamReader(context.Request.Body).ReadToEndAsync();

            try
            {
                JObject jsonObject = JObject.Parse(requestBody);
                JObject payload = (JObject)jsonObject["payload"];
                string plainToken = payload["plainToken"].ToString();
                string encryptedToken = GetHash(plainToken, "");

                var response = new
                {
                    plainToken,
                    encryptedToken
                };
                context.Response.ContentType = "application/json";

                // Write the JSON response
                await context.Response.WriteAsync(JsonConvert.SerializeObject(response));

            }
            catch (Exception ex)
            {
                await context.Response.WriteAsync("Error: " + ex.ToString());
            }

        });
    }

    static string GetHash(string text, string key)
    {
        using (HMACSHA256 sha256 = new HMACSHA256(Encoding.UTF8.GetBytes(key)))
        {
            byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(text));
            return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
        }
    }
}



Tab 2 Content


using Newtonsoft.Json;
using System.Text;
using System.Text.Json;



    public class s2soauth
    {

        public static Task S2SOauth(HttpContext context)
        {
            return Task.Run(async () =>
            {

                string s2s_oauth_client_id = Environment.GetEnvironmentVariable("S2S_OAUTH_CLIENT_ID"); 
                string s2s_oauth_client_secret = Environment.GetEnvironmentVariable("S2S_OAUTH_CLIENT_SECRET"); 
                string s2s_oauth_account_id = Environment.GetEnvironmentVariable("S2S_OAUTH_ACCOUNT_ID");


                // Access the environment variables
                var clientId = s2s_oauth_client_id;
                var clientSecret = s2s_oauth_client_secret;
                var accountId = s2s_oauth_account_id;
                var oauthUrl = $"https://zoom.us/oauth/token?grant_type=account_credentials&account_id={accountId}";

                try
                {
                    // Create the Basic Authentication header
                    var authHeader = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{clientId}:{clientSecret}"));

                    // Initialize HttpClient
                    using var client = new HttpClient();

                    // Create request message
                    var request = new HttpRequestMessage(HttpMethod.Post, oauthUrl);
                    request.Headers.Add("Authorization", $"Basic {authHeader}");

                    // Send request and get response
                    var response = await client.SendAsync(request);

                    // Check if the request was successful (status code 200)
                    if (response.IsSuccessStatusCode)
                    {
                        // Parse the JSON response to get the access token
                        var jsonResponse = await response.Content.ReadAsStringAsync();
                        var accessToken = JsonDocument.Parse(jsonResponse).RootElement.GetProperty("access_token").GetString();

                        // Set the "Content-Type" header to "application/json"
                        await context.Response.WriteAsync(JsonConvert.SerializeObject(accessToken));
                      
                    }
                    else
                    {
                        await context.Response.WriteAsync($"OAuth Request Failed with Status Code: {response.StatusCode}");
                      
                    }
                }
                catch (Exception e)
                {
                    await context.Response.WriteAsync($"An error occurred: {e.Message}");
                   
                }


            });
        }

   
    }



    
    

Tab 3 Content



using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
public static class redirectforoauth
{
 
    public static Task RedirectForOauth(HttpContext context)
    {
        return Task.Run(async () =>
        {

          
            String AppClientID = Environment.GetEnvironmentVariable("OAUTH_CLIENT_ID"); ;
            String AppClientSecret = Environment.GetEnvironmentVariable("OAUTH_CLIENT_SECRET"); ;
            String redirectURL = "https://csharp.asdc.cc/redirectforoauth";

            var authorizationToken = context.Request.Query["code"].ToString();

            try
            {
                using (HttpClient _httpClient = new HttpClient())
                {
                    var url = "https://zoom.us/oauth/token";

                    using var client = new HttpClient();

                    // Encode the client ID and client secret
                    var credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{AppClientID}:{AppClientSecret}"));
                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);


                    var content = new FormUrlEncodedContent(new Dictionary
                {
                    { "grant_type", "authorization_code" },
                    { "redirect_uri", redirectURL },
                    { "code", authorizationToken }
                });

                    var response = await client.PostAsync(url, content);


                    if (response.IsSuccessStatusCode)
                    {
                        var responseContent = await response.Content.ReadAsStringAsync();
                        await context.Response.WriteAsync(JsonConvert.SerializeObject(responseContent));

                    }
                    else
                    {
                        // Handle error response
                        await context.Response.WriteAsync(JsonConvert.SerializeObject(response.StatusCode));

                    }
                }
            }
            catch (HttpRequestException ex)
            {
                // Handle HTTP request exceptions
                Console.WriteLine($"HTTP Request Exception: {ex.Message}");
                //throw new Exception($"HTTP Request Exception: {ex.Message}");
            }
            catch (System.Text.Json.JsonException ex)
            {
                // Handle JSON parsing exceptions
                Console.WriteLine($"JSON Parsing Exception: {ex.Message}");
                throw new Exception($"JSON Parsing Exception: {ex.Message}");
            }
            catch (Exception ex)
            {
                // Handle other exceptions
                Console.WriteLine($"Exception occurred: {ex.Message}");
                throw new Exception($"Exception occurred: {ex.Message}");
            }
        });
    }

    internal static RequestDelegate RedirectForOauth(string? oAUTH_CLIENT_ID, string? oAUTH_CLIENT_SECRET)
    {
        throw new NotImplementedException();
    }
}





Tab 4 Content


            
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
public static class meetingsdk
{

    public static Task MeetingSDK(HttpContext context)
    {
        return Task.Run(async () =>
        {

            string MSDK_CLIENT_ID = Environment.GetEnvironmentVariable("MSDK_CLIENT_ID");
            string MSDK_CLIENT_SECRET = Environment.GetEnvironmentVariable("MSDK_CLIENT_SECRET");


            var authorizationToken = context.Request.Query["code"].ToString();
            
            var currentDateOffset = DateTimeOffset.UtcNow;
            var epochTime = (int)currentDateOffset.ToUnixTimeSeconds();

            var epochTime48HoursLater = epochTime + 172800; // 172800 seconds = 2 days
            DateTime epochDateTimeExpiry = DateTimeOffset.FromUnixTimeSeconds(epochTime48HoursLater).UtcDateTime;

            var sdkSecret = MSDK_CLIENT_SECRET;
            var appKey = MSDK_CLIENT_ID;
            var data = new Dictionary
        {
            { "appKey", appKey },
            { "iat", epochTime },
            { "exp", epochTime48HoursLater },
            { "tokenExp", epochTime48HoursLater },
            { "mn", 9898533313 },
            { "role", 1 }
        };
            var meetingSdkKey = GenerateSignature(data, sdkSecret, epochDateTimeExpiry);


            await context.Response.WriteAsync(JsonConvert.SerializeObject(meetingSdkKey));
        });

        static string GenerateSignature(Dictionary data, string secret, DateTime epochDateTimeExpiry)
        {
            var claims = data.Select(kv => new Claim(kv.Key, kv.Value.ToString()));
            var identity = new ClaimsIdentity(claims, "Custom");
            //var handler = new JwtSecurityTokenHandler();
            //var securityToken = handler.CreateToken(new SecurityTokenDescriptor
            //{
            //    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)), SecurityAlgorithms.HmacSha256),
            //    Subject = identity,
            //    Expires = epochDateTimeExpiry, 
            //    NotBefore= null
            //});
            //return handler.WriteToken(securityToken);
            // Create JWT token without setting the "nbf" claim
            var securityToken = new JwtSecurityToken(
                claims: identity.Claims,
                expires: epochDateTimeExpiry,
                signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)), SecurityAlgorithms.HmacSha256),
                notBefore: null  // Exclude the "nbf" claim
            );

            var handler = new JwtSecurityTokenHandler();
            return handler.WriteToken(securityToken);
        }

    }
}

        
        

Tab 5 Content


            
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
public static class oauthrefreshtoken
{

    public static Task OauthRefreshToken(HttpContext context)
    {
        return Task.Run(async () =>
        {


            var oauthClientId = Environment.GetEnvironmentVariable("OAUTH_CLIENT_ID");
            var oauthClientSecret = Environment.GetEnvironmentVariable("OAUTH_CLIENT_SECRET");
            var refreshToken = context.Request.Query["code"].ToString();

            var url = "https://zoom.us/oauth/token";

            var credentials = $"{oauthClientId}:{oauthClientSecret}";
            var credentialsEncoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials));

            var data = new Dictionary
            {
                { "grant_type", "refresh_token" },
                { "refresh_token", refreshToken }
            };

            var content = new FormUrlEncodedContent(data);

            using var client = new HttpClient();
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", credentialsEncoded);

        

            var response = await client.PostAsync(url, content);

            if (response.IsSuccessStatusCode)
            {
                var jsonResponse = await response.Content.ReadAsStringAsync();

                var accessToken = JsonDocument.Parse(jsonResponse).RootElement.GetProperty("access_token").GetString();

                // Set the "Content-Type" header to "application/json"
                await context.Response.WriteAsync(JsonConvert.SerializeObject(accessToken));
            }
            else
            {
                await context.Response.WriteAsync($" Request Failed with Status Code: {response.StatusCode}");

            }
        });
    }

}



Tab 6 Content


using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
public class callapi
{
    public static Task CallAPI(HttpContext context)
    {
        return Task.Run(async () =>
        {
            // Fetch access_token from query string
            var access_token = context.Request.Query["access_token"];

            // Meeting data
            var meeting_data = new
            {
                topic = "hello world",
                type = 2,
                start_time = "2023-10-01T10:00:00Z",
                duration = 120,
                password = "12345678",
                agenda = "40 mins limit demonstration",
                pre_schedule = false,
                timezone = "Asia/Singapore",
                default_password = false
            };

            // Zoom API endpoint
            var api_url = "https://api.zoom.us/v2/users/me/meetings";

            // Headers for the request
            var headers = new
            {
                Authorization = $"Bearer {access_token}",
                Content_Type = "application/json",
                Accept = "application/json"
            };

            // Send POST request to create meeting
            using var client = new HttpClient();
            using var request = new HttpRequestMessage(HttpMethod.Post, api_url);
            request.Content = new StringContent(JsonSerializer.Serialize(meeting_data), Encoding.UTF8, "application/json");

            foreach (var header in headers.GetType().GetProperties())
            {
                request.Headers.Add(header.Name, header.GetValue(headers).ToString());
            }

            var response = await client.SendAsync(request);

            // Return response
            await context.Response.WriteAsync("Meeting Details: " + await response.Content.ReadAsStringAsync());
        });


    }
}


 

Tab 7 Content

        
                S2S_OAUTH_CLIENT_ID='xxxxxxxxxx'
                S2S_OAUTH_CLIENT_SECRET='xxxxxxxxxx'
                S2S_OAUTH_ACCOUNT_ID='xxxxxxxxxx'
                OAUTH_SECRET_TOKEN='xxxxxxxxxx'
                OAUTH_CLIENT_ID='xxxxxxxxxx'
                OAUTH_CLIENT_SECRET='xxxxxxxxxx'
                MSDK_CLIENT_SECRET='xxxxxxxxxx'
                MSDK_CLIENT_ID='xxxxxxxxxx'

        
        

Tab 8 Content