{"id":13764397,"url":"https://github.com/darrenparkinson/SparkDotNet","last_synced_at":"2025-05-10T19:31:02.770Z","repository":{"id":13298216,"uuid":"74142799","full_name":"darrenparkinson/SparkDotNet","owner":"darrenparkinson","description":"An unofficial dotnet library for consuming RESTful APIs for Cisco Spark. Please visit Cisco at http://developer.ciscospark.com/.","archived":false,"fork":false,"pushed_at":"2022-06-22T15:23:16.000Z","size":200,"stargazers_count":12,"open_issues_count":4,"forks_count":14,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-11T12:06:29.729Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/darrenparkinson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-18T15:39:30.000Z","updated_at":"2024-08-29T19:10:09.000Z","dependencies_parsed_at":"2022-09-20T17:21:14.874Z","dependency_job_id":null,"html_url":"https://github.com/darrenparkinson/SparkDotNet","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darrenparkinson%2FSparkDotNet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darrenparkinson%2FSparkDotNet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darrenparkinson%2FSparkDotNet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darrenparkinson%2FSparkDotNet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/darrenparkinson","download_url":"https://codeload.github.com/darrenparkinson/SparkDotNet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253470693,"owners_count":21913715,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T16:00:19.966Z","updated_at":"2025-05-10T19:31:02.421Z","avatar_url":"https://github.com/darrenparkinson.png","language":"C#","funding_links":[],"categories":["Client SDKs"],"sub_categories":["REST API clients"],"readme":"# SparkDotNet\n\nAn unofficial dotnet library for consuming RESTful APIs for Cisco Spark. Please visit Cisco at https://developer.webex.com/.\n\n```{.cs}\nusing SparkDotNet;\n\nvar token = System.Environment.GetEnvironmentVariable(\"SPARK_TOKEN\");\nvar spark = new Spark(token);\nvar rooms = await spark.GetRoomsAsync(max: 10);\nforeach (var room in rooms)\n{\n    WriteLine(room);\n}\n```\n\n# Installation\n\n## Prerequisites\n\nThis library requires .NET 4.5, .NET 4.6.1 or .NET Standard 1.6.\n\nIt can be used across multiple platforms using .NET Core and you will therefore require the appropriate components based on your choice of environment.\n\n* [.NET Core for Windows and Visual Studio](https://www.microsoft.com/net/core#windowsvs2015)\n* [.NET Core for Windows Command Line](https://www.microsoft.com/net/core#windowscmd)\n* [.NET Core for Mac](https://www.microsoft.com/net/core#macos)\n* [.NET Core for Linux](https://www.microsoft.com/net/core#linuxredhat)\n\nYou can also use Visual Studio 2015 and .NET 4.6.1 or .Net 4.5.\n\nThe following assumes you have an existing project to which you wish to add the library.\n\n### .NET Core\n\n1. Edit your `\u003capplication\u003e.csproj` file to include `SparkDotNet` as a dependency.  \n\n2. Run `dotnet restore`.\n\n3. There is no step 3.\n\nThe following shows an example application.csproj file:\n\n```{.csproj}\n\u003cProject Sdk=\"Microsoft.NET.Sdk\"\u003e\n  \u003cPropertyGroup\u003e\n    \u003cOutputType\u003eExe\u003c/OutputType\u003e\n    \u003cTargetFramework\u003enetcoreapp1.1\u003c/TargetFramework\u003e\n  \u003c/PropertyGroup\u003e\n  \u003cItemGroup\u003e\n    \u003cPackageReference Include=\"SparkDotNet\" Version=\"1.2.0\" /\u003e\n  \u003c/ItemGroup\u003e\n\u003c/Project\u003e\n```\n\nFor previous versions of dotnet core, the following shows an example project.json file:\n\n```{.json}\n{\n  \"version\": \"1.0.0-*\",\n  \"buildOptions\": {\n    \"debugType\": \"portable\",\n    \"emitEntryPoint\": true\n  },\n  \"dependencies\": {\n      \"SparkDotNet\": \"1.0.4\"\n  },\n  \"frameworks\": {\n    \"netcoreapp1.0\": {\n      \"dependencies\": {\n        \"Microsoft.NETCore.App\": {\n          \"type\": \"platform\",\n          \"version\": \"1.0.1\"\n        }\n      },\n      \"imports\": \"dnxcore50\"\n    }\n  }\n}\n```\n\n\n\n### Windows Visual Studio\n\n1. Open Tools -\u003e NuGet Package Manager -\u003e Package Manager Console\n\n2. Run `Install-Package SparkDotNet`\n\n3. There is no step 3.\n\n\n# Using the library\n\n1. Create a new project \n\n\u003e `dotnet new console`\n\n2. Include the `SparkDotNet` dependency  \n\n\u003e `dotnet add package SparkDotNet`  \n\u003e `dotnet restore`\n\n3. Edit `Program.cs` to resemble the following:\n\n```{.cs}\nusing static System.Console;\nusing SparkDotNet;\nusing System.Threading.Tasks;\n\nnamespace ConsoleApplication\n{\n    public class Program\n    {\n        public static void Main(string[] args)\n        {\n            RunAsync().Wait();\n        }\n\n        static async Task RunAsync()\n        {\n            var token = System.Environment.GetEnvironmentVariable(\"SPARK_TOKEN\");\n            var spark = new Spark(token);\n\n            try\n            {\n                var orgs = await spark.GetOrganizationsAsync();\n                foreach (var org in orgs)\n                {\n                    WriteLine(org);\n                }\n\n                WriteLine(await spark.GetMeAsync());\n            }\n            catch (SparkException ex)\n            {\n                WriteLine(ex.Message);\n            }\n        }\n    }\n}\n\n```\n4. Run the Program\n\n\u003e `set SPARK_TOKEN=\u003cyour token here`  \n\u003e `dotnet run`\n\n# Reference\n\nThere are 33 endpoints covered by this library. Please refer to the Cisco documentation for details of their use:\n\n* [Admin Audit Events](https://developer.webex.com/docs/api/v1/admin-audit-events)\n* [Attachment Actions](https://developer.webex.com/docs/api/v1/attachment-actions)\n* [Call Controls](https://developer.webex.com/docs/api/v1/call-controls)\n* [Devices](https://developer.webex.com/docs/api/v1/devices)\n* [Events](https://developer.webex.com/docs/api/v1/events)\n* [Hybrid Clusters](https://developer.webex.com/docs/api/v1/hybrid-clusters)\n* [Hybrid Connectors](https://developer.webex.com/docs/api/v1/hybrid-connectors)\n* [Licenses](https://developer.webex.com/docs/api/v1/licenses)\n* [Locations](https://developer.webex.com/docs/api/v1/locations)\n* [Meeting Invitees](https://developer.webex.com/docs/api/v1/meeting-invitees)\n* [Meeting Participants](https://developer.webex.com/docs/api/v1/meeting-participants)\n* [Meeting Preferences](https://developer.webex.com/docs/api/v1/meeting-preferences)\n* [Meeting Qualities](https://developer.webex.com/docs/api/v1/meeting-qualities)\n* [Meetings](https://developer.webex.com/docs/api/v1/meetings)\n* [Memberships](https://developer.webex.com/docs/api/v1/memberships)\n* [Messages](https://developer.webex.com/docs/api/v1/messages)\n* [Organizations (including XSI)](https://developer.webex.com/docs/api/v1/organizations)\n* [People](https://developer.webex.com/docs/api/v1/people)\n* [Places](https://developer.webex.com/docs/api/v1/places)\n* [Recordings](https://developer.webex.com/docs/api/v1/recordings)\n* [Report Templates](https://developer.webex.com/docs/api/v1/report-templates)\n* [Reports](https://developer.webex.com/docs/api/v1/reports)\n* [Resource Group Membership](https://developer.webex.com/docs/api/v1/resource-group-memberships)\n* [Resource Groups](https://developer.webex.com/docs/api/v1/resource-groups)\n* [Roles](https://developer.webex.com/docs/api/v1/roles)\n* [Rooms Tabs](https://developer.webex.com/docs/api/v1/room-tabs)\n* [Rooms](https://developer.webex.com/docs/api/v1/rooms)\n* [Space Classifications](https://developer.webex.com/docs/api/v1/space-classifications)\n* [Team Mebership](https://developer.webex.com/docs/api/v1/team-memberships)\n* [Teams](https://developer.webex.com/docs/api/v1/teams)\n* [Webhooks](https://developer.webex.com/docs/api/v1/webhooks)\n* [Workspaces](https://developer.webex.com/docs/api/v1/workspaces)\n* [xAPI](https://developer.webex.com/docs/api/v1/xapi)\n\nMost endpoints have a corresponding method in the Spark class mapping to `Get`, `Create`, `Update` and `Delete` based on the HTTP method used, `GET`, `POST`, `PUT` and `DELETE` respectively.  As an example, using the People endpoint, these map as follows:\n\n| Cisco Endpoint | HTTP Method | Spark Class Method |\n| -------------- |:-----------:|:-------------------|\n| [List People](https://developer.webex.com/docs/api/v1/people/list-people)| GET |  GetPeopleAsync() | \n| [Create a Person](https://developer.webex.com/docs/api/v1/people/create-a-person)| POST | CreatePersonAsync() | \n| [Get Person Details](https://developer.webex.com/docs/api/v1/people/get-person-details)| GET | GetPersonAsync() | \n| [Update a Person](https://developer.webex.com/docs/api/v1/people/update-a-person)   | PUT | UpdatePersonAsync() | \n| [Delete a Person](https://developer.webex.com/docs/api/v1/people/delete-a-person)| DELETE | DeletePersonAsync() |\n| [Get My Own Details](https://developer.webex.com/docs/api/v1/people/get-my-own-details)| GET | GetMeAsync() |\n\nWhere parameters are optional, they are also optional in the class methods.  These are variables that have default values specified. As usual, you must specify any required variables in the correct order before specifying any optional variables.\n\nAs an example, the `max` parameter is typically optional and as such you do not need to specify it.  If you wish to specify it, you can use the named argument syntax as shown below:\n\n```\nspark.GetRoomsAsync(max: 400);\n```\n\nWhere a parameter requires a string array, these can be specified as follows:\n\n```\nspark.UpdatePersonAsync(id,new string[] {\"someone@example.com\"},orgId, new string[] {role}, name);\n```\n\nMost methods return an object of the type you are retrieving or updating.  Methods where you expect multiple objects are returned as a List\u003c\u003e of that object.  The exception to this is when deleting an object where the returned value is a boolean indicating the success of the operation.\n\n# Files\n\nAs of version 1.2.0, when posting files in messages using `CreateMessageAsync()` you now have the option of sending local files.\n\nYou could already send files available publicly using the existing `files` object:\n\n`var message = await spark.CreateMessageAsync(roomId, text:\"Here is the logo you wanted.\", files:new string[] {\"https://developer.cisco.com/images/mobility/Spark.png\"} );`\n\nTo upload a local file, you simple replace the URI with a local filename:\n\n`var message = await spark.CreateMessageAsync(roomId, text:\"Here is the logo you wanted.\", files:new string[] {\"Spark.png\"} );`\n\nThis example assumes the `Spark.png` file is in the same location you are running the application. \n\nNote that you can only send a single file at a time using this method, even though the parameter accepts a string array.\n\n\n# Pagination\n\nAn initial version of pagination has been added to provide support for Cisco Spark API as outlined on [the Cisco Spark Developer Portal](https://developer.webex.com/docs/api/basics#pagination).  \n\nFor backwards compatibility, this has been added as a separate method (`GetItemsWithLinksAsync`) which you must use over and above those specific to each resource if you specifically want to use pagination.  \n\nThis method returns a new `PaginationResult` class which contains the `Items` of the type you requested and `Links` to any additional resources for `First`, `Prev` and `Next`.\n\nThe following provides an example of returning `Person` items with pagination:\n\n```{.cs}\nvar result = await spark.GetItemsWithLinksAsync\u003cSparkDotNet.Person\u003e(\"/v1/people?max=3\");\nforeach (var person in result.Items)\n{\n    WriteLine(person);\n}\nif (!string.IsNullOrEmpty(result.Links.Next))\n{\n    var result2 = await spark.GetItemsWithLinksAsync\u003cSparkDotNet.Person\u003e(result.Links.Next);\n    foreach (var person in result2.Items)\n    {\n        WriteLine(person);\n    }\n}\n```\n\n# Exceptions\n\nAs of version 1.1.0, all calls to the Cisco Spark platform will throw a `SparkException` if an unexpected result is received. \n\nTo avoid runtime errors, wrap calls to Cisco Spark in a `try-catch` statement:\n\n```{.cs}\ntry\n{\n    WriteLine(await spark.GetMeAsync());    \n}\ncatch (SparkException ex)\n{\n    WriteLine(ex.Message)\n}\n```\n\n`SparkException` provides the following properties:\n\n* `Message` (`string`)\n* `StatusCode` : (`int`)\n* `Headers` : (`System.Net.Http.Headers.HttpResponseHeaders`)\n\nThe `Headers` property is useful since this will provide the Cisco `Trackingid` for troubleshooting purposes.\n\n```{.cs}\nusing System.Linq;\n\ntry\n{\n    WriteLine(await spark.GetMeAsync());    \n}\ncatch (SparkException ex)\n{\n    WriteLine(ex.Headers.GetValues(\"Trackingid\").FirstOrDefault());\n}\n```\n\n# Adaptive Cards\n\nAs of version 1.2.6, support has been added for the attachments option when creating messages.  This enables the use of Adaptive Cards as per the [Cisco Documentation](https://developer.webex.com/docs/api/guides/cards).\n\nThe simplest way to use this feature is to use the [Microsoft Adaptive Cards package](https://docs.microsoft.com/en-us/adaptive-cards/sdk/authoring-cards/net):\n\n```{.sh-session}\ndotnet add package AdaptiveCards\n```\n\nThen in your code:\n\n```{.cs}\nAdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion(1, 0));\ncard.Body.Add(new AdaptiveTextBlock()\n{\n    Text = \"Hello\",\n    Size = AdaptiveTextSize.ExtraLarge\n});\n\ncard.Body.Add(new AdaptiveImage()\n{\n    Url = new Uri(\"http://adaptivecards.io/content/cats/1.png\")\n});\n\nstring json = card.ToJson();\nvar webexTeamsAttachment = \"{\\\"contentType\\\": \\\"application/vnd.microsoft.card.adaptive\\\",\\\"content\\\":\" + json + \"}\";\n\nvar res = await spark.CreateMessageAsync(roomId: RoomID, text: \"Test Message\", attachments: webexTeamsAttachment);\n```\n\nThe content is expected to be JSON as a string.\n\n# Attachment Actions\n\nAs of version 1.2.7, support has been added (with thanks to @mayankmaxsharma) for the Attachment Actions endpoint in order to retrieve attachment action details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarrenparkinson%2FSparkDotNet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdarrenparkinson%2FSparkDotNet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarrenparkinson%2FSparkDotNet/lists"}