{"id":15107994,"url":"https://github.com/virtyaluk/intouch","last_synced_at":"2025-07-24T14:34:09.595Z","repository":{"id":66296132,"uuid":"52570005","full_name":"virtyaluk/InTouch","owner":"virtyaluk","description":":busts_in_silhouette: InTouch - is a programming SDK build around vk.com API exposing most of the social platform features including messaging, news feed fetching, communities, and media management.","archived":false,"fork":false,"pushed_at":"2020-04-11T06:09:50.000Z","size":1089,"stargazers_count":34,"open_issues_count":3,"forks_count":12,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-07-20T10:09:10.302Z","etag":null,"topics":["api","c-sharp","dotnet","intouch","netframework","netstandard","vk","vk-api","vkontakte","windows-uwp","wrapper","xamarin"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/virtyaluk.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-02-26T01:39:04.000Z","updated_at":"2024-11-15T13:30:12.000Z","dependencies_parsed_at":"2023-06-03T03:30:24.811Z","dependency_job_id":null,"html_url":"https://github.com/virtyaluk/InTouch","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/virtyaluk/InTouch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virtyaluk%2FInTouch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virtyaluk%2FInTouch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virtyaluk%2FInTouch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virtyaluk%2FInTouch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/virtyaluk","download_url":"https://codeload.github.com/virtyaluk/InTouch/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virtyaluk%2FInTouch/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266856164,"owners_count":23995640,"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","status":"online","status_checked_at":"2025-07-24T02:00:09.469Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["api","c-sharp","dotnet","intouch","netframework","netstandard","vk","vk-api","vkontakte","windows-uwp","wrapper","xamarin"],"created_at":"2024-09-25T21:43:39.216Z","updated_at":"2025-07-24T14:34:09.572Z","avatar_url":"https://github.com/virtyaluk.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\u003cimg width=\"256\" src=\"media/it-logo.png\" alt=\"InTouch logo\" style=\"clear: right;\"\u003e\u003cbr/\u003e\u003c/h1\u003e\n\n[![Build status](https://ci.appveyor.com/api/projects/status/m3lbiphdft6bn059?svg=true)](https://ci.appveyor.com/project/virtyaluk/intouch) [![NuGet](https://img.shields.io/nuget/v/ModernDev.InTouch.svg?maxAge=7200)](https://www.nuget.org/packages/ModernDev.InTouch/) [![Join the chat at https://gitter.im/virtyaluk/InTouch](https://badges.gitter.im/virtyaluk/InTouch.svg)](https://gitter.im/virtyaluk/InTouch?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\n\n**InTouch** - is a C# wrapper for [vk.com](https://vk.com/) API.\n\nBe sure to check out official VK's **[:link:Quick start](https://new.vk.com/dev/main)** guide before you dive into **InTouch**.\n\nCompatible with version **5.63** of **[:link:VK API](https://new.vk.com/dev/versions)**.\n\n[:calendar: Changelog](CHANGELOG.md) \u0026nbsp; [:ru: Документация на русском.](README.ru.md)\n\n\n## :dvd: NuGet\n\n```bash\nPM\u003e Install-Package ModernDev.InTouch\n```\n\n## :clipboard: Usage\n\n```csharp\nvar clientId = 12345; // API client Id\nvar clientSecret = \"super_secret\"; // API client secret\nvar client = new InTouch(clientId, clientSecret);\n\n// Authorization works only in Windows (and WinPhone) Store Apps\n// otherwise you'll need to set received \"access_token\" manually\n// using SetSessionData method.\nawait client.Authorize();\n\n// Gets a list of a user's friends.\nvar friends = await client.Friends.Get();\n\nif (friends.IsError == false)\n{\n    ShowFriendsList(friends.Data.Items.Where(friend =\u003e friend.Online));\n}\n\nclient.Dispose();\n```\n\nor even simpler:\n\n```csharp\nusing (var client = new InTouch(12345, \"super_secret\"))\n{\n    await client.Authorize();\n\n    var friends = await client.Friends.Get();\n    // ...\n}\n```\n\n## :mortar_board: API Reference\n\nAfter you [:link:register](https://vk.com/editapp?act=create) an app, you'll get a unique **`ClientID`** and **`ClientSecret`**. These needed to perform user [:link:authorization](https://new.vk.com/dev/authentication) and to call several methods from [:link:Auth category](https://new.vk.com/dev/auth.signup). You may avoid using **`ClientID`** and **`ClientSecret`** if you do not intend to use *authorization* or methods from *Auth category*.\n\nYou may use one of following constructors to produce a new instance of `InTouch` class.\n\n```csharp\nnew InTouch(int clientId, string clientSecret, bool throwExceptionOnResponseError = false,\n    bool includeRawResponse = false);\n```\n\n```csharp\nnew InTouch(bool throwExceptionOnResponseError = false, bool includeRawResponse = false)\n```\n\n##### Values:\n\n - **`clientId`**: Your application ID.\n\n - **`clientSecret`**: Your application secret.\n - **`throwExceptionOnResponseError`**: *Default:* `false`. Whether the raw response string should be included in request response object.\n - **`includeRawResponse `**: *Default:* `false`. Whether the raw response string should be included in request response object.\n\nYou can also set client data after creating an instance of class just by using **`SetApplicationSettings`** class method.\n\n```csharp\nvoid SetApplicationSettings(int clientId, string clientSecret);\n```\n\n**:information_source: Note**: The current API session will be reset each time you change client data using **`SetApplicationSettings`** method.\n\n### Authorization\n\nIn order to call most API methods, your application require user authorization.\n\nAuthorization may be performed using the **`Authorize`** method, which is available for *Windows Store Apps*. Otherwise, you need to implement your own authorization logic based on steps described in the [:link:official documentation](https://new.vk.com/dev/auth_mobile) and then set received data on *client* using the **`SetSessionData`** method.\n\n**In case of Windows Store Apps**, you need to await the **`Authorize`** method which starts the *authentication operation* and shows *auth dialog* to the user. In case of success, auth data will be set to the client automatically, no need to take additional actions.\n\n```csharp\nasync Task Authorize(AuthorizationSettings authSettings = null, bool silentMode = false);\n```\n\n##### Values:\n - **`silentMode`**: *Default:* `false`. Tells the web authentication broker to not render any UI.\n - **`authSettings`**: *Default:* `null`.  Authorization settings.\n\nWhere **`authSettings`** is an instance of class **`AuthorizationSettings`** which describes the next data structure:\n\n```csharp\nclass AuthorizationSettings {\n    // Authorization window appearance.\n    AuthorizationDisplayTypes Display = AuthorizationDisplayTypes.Mobile,\n\n    // Requested application access permissions.\n    AccessPermissions Scope = AccessPermissions.None,\n\n    // Whether the authorization dialog must revoke previously accessed application permissions.\n    bool Revoke,\n\n    // URL where access_token will be passed to.\n    Uri RedirectUri = new Uri(\"https://oauth.vk.com/blank.html\"),\n\n    // Whether the app supports single sign-on (SSO).\n    bool SSOEnabled,\n}\n```\n\n**:information_source: Note**. VK API doesn't yet support **[SSO](https://en.wikipedia.org/wiki/Single_sign-on)**. There is a feature request submitted by me though. So auth dialog will be displayed each time the **`Authorize`** method would called.\n\nLet's say we need to get access to user's *friends* and *private messages* through authorization on devices with large screen. In this case, we'll pass the next object as the first argument in **`Authorize`** method:\n\n```csharp\nawait client.Authorize(new AuthorizationSettings {\n    Display = AuthorizationDisplayTypes.Page,\n    Scope = AccessPermissions.Friends | AccessPermissions.Messages\n});\n```\n\n**In the case of custom authorization**, after the authorization completes you'll need to pass auth data to the **`SetSessionData`** method which takes 3 arguments.\n\n```csharp\nvoid SetSessionData(string accessToken, int userId, int sessionDuration = 20*60*60);\n```\n\n##### Values:\n - **`accessToken`**: Access key for API calls.\n - **`userId`**: The authorized user ID.\n - **`sessionDuration`**: `accessToken` lifetime specified in seconds so the *client* can notify that the token was expired through the **`AccessTokenExpired`** event.\n\nAfter successful authorization, you can make API requests. There're a couple of methods not requiring authorization, though.\n\n#### Community Token\n\nA community token allows working with API on behalf of a group, event or public page. It can be used to answer the community messages.\n\n**InTouch** offers **`GetClientCredentialsFlow`** method to get community token:\n\n```csharp\nasync Task\u003cClientCredentialsFlowStatus\u003e GetClientCredentialsFlow(int? clientId = null, string clientSecret = null);\n```\n\nIn case of omitting *`clientId`* and *`clientSecret`* arguments, **InTouch** would try to use *`ClientId`* and *`ClientSecret`* properties on main class instance.\n\nIn case you already have *community token*, you can set it on main class instance manually using **`SetServiceToken`** method:\n\n```csharp\nvoid SetServiceToken(string serviceToken)\n```\n\nand later access using *`ServiceToken`* property.\n\n### API Requests\n\nAll the methods are grouped by corresponding categories as they were presented in the [:link:official documentation](https://new.vk.com/dev/methods). So, for example, if you want to return a list of posts on a user's wall using [:link:wall.get](https://new.vk.com/dev/wall.get) method, you need to call **Get** method of **Wall** object on the main instance of **InTouch** class. Like so:\n\n```csharp\nawait client.Wall.Get(new WallGetParams {\n    Count = 10,\n    Extended = true\n});\n```\n\n:information_source: Oh, by the way, **InTouch** brings all the advantages of [:link:async programming](https://msdn.microsoft.com/en-us/library/hh191443.aspx). Which means there are only a couple of *non-async* methods and all the rest are *async*. So you need to **`await`** them.\n\n#### Parameters transmissiton in API\n\nMost of the methods have its own *parameters* that are described in the **docs**. If a method (like [:link:this one](https://new.vk.com/dev/wall.get)) takes more than **6** arguments then these arguments will be combined into the **one object**. Here's what that means.\n\nThe **wall.get** method takes next parameters: *owner_id*, *domain*, *offset*, *count*, *filter*, *extended*, *fields*.\n\nBut **InTouch** version of this method takes only **one** argument which is an instance of **`WallGetParams`** class and has the next structure:\n\n```csharp\nclass WallGetParams {\n    // User or community id.\n    int OwnerId,\n\n    // User or community screen name.\n    string Domain,\n\n    // True – returns only page owner's posts.\n    bool OwnersOnly = false,\n\n    // Count of posts to return.\n    int Count = 20,\n\n    // Results offset.\n    int Offset = 0,\n\n    // Show extended post info.\n    bool Extended = false,\n\n    // The list of additional fields for the profiles and groups that need to be returned.\n    List\u003cobject\u003e Fields = null,\n\n    // Filter to apply.\n    PostFilterTypes Filter = PostFilterTypes.All\n}\n```\n\nAnd the [:link:wall.getById](https://new.vk.com/dev/wall.getById) method have short arguments list and thus has the next signature:\n\n```csharp\nasync Task\u003cResponse\u003cItemsList\u003cPost\u003e\u003e\u003e GetById(List\u003cstring\u003e posts, bool extended = false,\n    int copyHistoryDepth = 2, List\u003cobject\u003e fields = null);\n```\n\n:information_source: Keep in mind, **InTouch** would throw an exception if not all **required** parameters filled with data. *Optional* parameters may be omitted.\n\nEach method has its own set of supported parameters but there are some common ones:\n\n - **DataLanguage** - determines the language for the data to be displayed on. For example country and city names. If you use a non-cyrillic language, cyrillic symbols will be transtiterated automatically.\n\n```csharp\nclient.DataLanguage = Langs.English;\n```\n\n - **AlowHttpsLinks** - allows to get https links for photos and other media. False – methods return http links.\n\n```csharp\nclient.AlowHttpsLinks = true;\n```\n\n - **TestMode** - allows to send requests from a native app without switching it on for all users.\n\n```csharp\nclient.TestMode = false;\n```\n\n#### Response object\n\nCalling to the API will always result in **`Response`** object which describes the next data structure:\n\n```csharp\nclass Response\u003cT\u003e {\n    // Response error (if any).\n    ResponseError Error,\n\n    // Response data (if any).\n    T Data,\n\n    // Whether the request response is error.\n    bool IsError =\u003e Error != null,\n\n    // Raw JSON response.\n    string Raw\n}\n```\n\nSo, for example, retrieving friends list using [:link:friends.get](https://new.vk.com/dev/friends.get) method will result in **`Response\u003cItemsList\u003cUser\u003e\u003e`**, where **Data** property would be of type **`ItemsList\u003cUser\u003e`**.\n\nIf API request resulted in *error* then the **Error** property would contain the error object describing the error code and the error message:\n\n```csharp\nclass ResponseError: EventArgs {\n    // Error code.\n    int Code,\n\n    // Error text.\n    string Message,\n\n    // Captcha identifier.\n    string CaptchaSId,\n\n    // A link to an image that will be shown to a user.\n    string CaptchaImg,\n\n    // Request parameters.\n    Dictionary\u003cstring, string\u003e RequestParams\n}\n```\n\nThere are few *options* using which you can control how **InTouch** handles response errors.\n\n```csharp\n// If set to true, then an exception will be thrown in case of response error,\n// instead of passing an error object to the Response object.\nclient.ThrowExceptionOnResponseError = true;\n\n// If set to true, then Response.Raw will be filled with raw JSON response string.\nclient.IncludeRawResponse  = true;\n\ntry {\n    var audios = await client.Audios.Get(count: 10);\n\n    OwnWayToAnalyzeRawResp(audios.Raw);\n    FillAudiosList(audios.Data);\n} catch (InTouchResponseErrorException ex) {\n    MessageBox.Show(ex.ResponseError.Message);\n}\n```\n\n#### Handling Authorization\\Captcha errors.\n\nWhenever API call gets **authorization failed** error or **captcha needed** error, **`AuthorizationFailed`** or **`CaptchaNeeded`** event will be fired accordingly. So there's no need to check response error on these two, you can simply subscribe to custom events and use custom logic whenever it's needed.\n\n```csharp\nclient.AuthorizationFailed += OnAuthorizationFailed;\n\nclient.CaptchaNeeded += (s, error) =\u003e ShowCaptchaBox(error.CaptchaImg, error.CaptchaSId);\n```\n\nMoreover, there is an utility method that helps you to resend previously failed request with *captcha code*:\n\n```csharp\nasync Task\u003cResponse\u003cT\u003e\u003e SendCaptcha\u003cT\u003e(string captchaKey, ResponseError lastResponseError);\n```\n\nThere is also an utility method called **`TrySendRequestAgain`** which is designed to resend previously failed request:\n\n```csharp\nasync Task\u003cResponse\u003cT\u003e\u003e TrySendRequestAgain\u003cT\u003e();\n```\n\n**:information_source: Note**: Keep in mind that custom events will occur only and only when the **`ThrowExceptionOnResponseError`** is set to `false`, which is the default value.\n\n#### Limits and recommendations\n\n\u003e There can be maximum 3 requests to API methods per second from a client. \n\u003e\n\u003e Maximum amount of server requests depends on the app's users amount. \nIf an app has less than 10 000 users, 5 requests per second, up to 100 000 – 8 requests, up to 1 000 000 – 20 requests, 1 000 000+ – 35 requests. \n\u003e\n\u003e If one of this limits is exceeded, the server will return following error: 'Too many requests per second'. \n\u003e\n\u003e If your app's logic implies many requests in a row, check the execute method. \n\u003e\n\u003e Except the frequency limits there are quantitative limits on calling the methods of the \u003e same type. By obvious reasons we don't provide the exact limits info. \n\u003e\n\u003e On excess of a quantitative limit access to a particular method will require captcha (see captcha_error). After that it may be temporarily limited (in this case the server doesn't answer on particular method's requests but easily processes any other requests).\n\n### Other\n\n#### Custom API request\n\nYou may want to get full control on what you send through the request. **InTouch** exposes **`Request`** method to send VK API requests. All the **InTouch** API methods are build on top of the one. The signature is next:\n\n```csharp\nasync Task\u003cResponse\u003cT\u003e\u003e Request\u003cT\u003e(string methodName, Dictionary\u003cstring, string\u003e methodParams = null,\n    bool isOpenMethod = false, string path = null);\n```\n\n##### Values:\n - **`methodName`** - The name of the method to call.\n - **`methodParams`** - Request parameters.\n - **`isOpenMethod`** - Indicates whether the method can be called without an `accessToken`.\n - **`path`** - Object's path to select the token from.\n\nThe next example shows how to get a list of user's friends using the **`Request`** method:\n\n```csharp\nvar friends = await client.Request\u003cItemsList\u003cUser\u003e\u003e(\"friends.get\", new Dictionary\u003cstring, string\u003e {\n    {\"user_id\", \"16815310\"},\n    {\"count\", \"10\"},\n    {\"order\", \"name\"}\n});\n```\n\n#### Uploading Files\n\n**InTouch** supports [:link:uploading files](https://new.vk.com/dev/upload_files) through API.\n\nNext example demonstrates how to upload document to user's page.\n\n```csharp\nbyte[] docFile = GetMyFile(\"cats.gif\");\n\nvar uploadedDocs = await client.Docs.UploadDoc(docFile, \"cats.gif\", title: \"my funny cat\");\n\nShowUploadedDoc(uploadedDocs.Data[0]);\n```\n\nor how to update user's profile photo:\n\n```csharp\nbyte[] newPhoto = GetMyFile(\"photo.jpg\");\n\nawait client.Photos.UploadOwnerPhoto(newPhoto, \"profile.jpg\");\n```\n\n## :green_book: Platform Support\n\n**InTouch** is compiled for *.NET 4.5*, *Portable Class Library* (Profile 111) and *.NET Standard 1.1*:\n - .NET 4.5\n - .NET Standard 1.1\n - ASP.NET Core 1.0\n - Windows 8+\n - Windows Phone 8.1+\n - Xamarin.Android\n - Xamarin.iOS\n - Xamarin.iOS (Classic)\n\n## :green_book: License\n\n[Licensed under the GPLv3 license.](https://github.com/virtyaluk/InTouch/blob/master/LICENSE)\n\nCopyright (c) 2017 Bohdan Shtepan\n\n---\n\n\u003e [modern-dev.com](http://modern-dev.com) \u0026nbsp;\u0026middot;\u0026nbsp;\n\u003e GitHub [@virtyaluk](https://github.com/virtyaluk) \u0026nbsp;\u0026middot;\u0026nbsp;\n\u003e Twitter [@virtyaluk](https://twitter.com/virtyaluk)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvirtyaluk%2Fintouch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvirtyaluk%2Fintouch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvirtyaluk%2Fintouch/lists"}