Skip to content
This repository has been archived by the owner on May 14, 2021. It is now read-only.

Quick Start

KoalaBear84 edited this page Oct 18, 2019 · 13 revisions

You can get the settings for Telegram here

All the code below are examples only

Init connection and authenticate

using OpenTl.ClientApi;
using OpenTl.ClientApi.MtProto.Exceptions;
using OpenTl.Schema;

var settings = new FactorySettings
    {
        AppHash = // e.g 456a6654ad8f52c54bc4542505884cad
        AppId = // e.g 12345
        ServerAddress = // e.g 149.154.167.50
        ServerPublicKey = // e.g -----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAwVACPi9w23mF3tBk...
        ServerPort = // e.g 443
        SessionTag = "session", // by defaut
        Properties = new ApplicationProperties
                        {
                            AppVersion = "1.0.0", // You can leave as in the example
                            DeviceModel = "PC", // You can leave as in the example
                            LangCode = "en", // You can leave as in the example
                            LangPack = "tdesktop", // You can leave as in the example
                            SystemLangCode = "en", // You can leave as in the example
                            SystemVersion = "Win 10 Pro" // You can leave as in the example
                        }
    };

// Create the client
var clientApi = await ClientFactory.BuildClientAsync(settings).ConfigureAwait(false);

// If the user is not authenticated
if (!clientApi.AuthService.CurrentUserId.HasValue){
    // Auth
    var phone = "+7555555555"; // User phone number with plus
    var sentCode = await clientApi.AuthService.SendCodeAsync(phone).ConfigureAwait(false);

    var code = "1234321" // Sent code

    TUser user;
    try
    {
        user = await clientApi.AuthService.SignInAsync(phone, sentCode, code).ConfigureAwait(false);
    }
    // If the user has a cloud password
    catch (CloudPasswordNeededException)
    {
        var passwordStr = "qweasd" // User cloud password
        user = await clientApi.AuthService.CheckCloudPasswordAsync(passwordStr).ConfigureAwait(false);
    }
    // If the phone code is invalid
    catch (PhoneCodeInvalidException ex)
    {
    }
}

Register new user

TUser user;
try
{
    user = await clientApi.AuthService.SignInAsync(phoneNumber, sentCode, PhoneCode).ConfigureAwait(false);
}
catch (PhoneNumberUnoccupiedException)
{
    user = await clientApi.AuthService.SignUpAsync(phoneNumber, sentCode, PhoneCode, "Test", "Test") .ConfigureAwait(false);
}

Send the message

// Send message to myself
await clientApi.MessagesService.SendMessageAsync(new TInputPeerSelf(), "Hello").ConfigureAwait(false);

// Send message to user. User must be added to contacts. See ContactsService.ImportContactsAsync
TUser toUser = null; // Must be set
var inputUser = new TInputPeerUser
                {
                    UserId = toUser.Id,
                    AccessHash = toUser.AccessHash
                }
await clientApi.MessagesService.SendMessageAsync(inputUser, "Hello").ConfigureAwait(false);

Recive message (auto-updates)

The additional logic from the developer is not required. Updates come at once. If you miss an update, it will no longer come

await clientApi.UpdatesService.AutoReceiveUpdates += update =>
{
    // Handle updates
     switch (update)
        {
            case TUpdates updates:
                break;
            case TUpdatesCombined updatesCombined:
                break;
            case TUpdateShort updateShort:
                break;
            case TUpdateShortChatMessage updateShortChatMessage:
                break;
            case TUpdateShortMessage updateShortMessage:
                break;
            case TUpdateShortSentMessage updateShortSentMessage:
                break;
            case TUpdatesTooLong updatesTooLong:
                break;
        }
};

Recive message (manual updates)

clientApi.UpdatesService.StartReceiveUpdates(TimeSpan.FromSeconds(1));
// Send message to myself
await clientApi.UpdatesService.ManualReceiveUpdates += diff =>
{
    // Handle updates
     switch (diff)
            {
                case TDifference difference:
                    break;
                case TDifferenceSlice differenceSlice:
                    break;
                case TDifferenceTooLong differenceTooLong:
                    break;
            }
};

Receive updates by states (manually)

It does not depend on whether there is a connection or not. The application can be turned off. The developer implements the logic of updating the status and requesting updates himself.

// Get the current state
var currentState = await clientApi.UpdatesService.GetCurrentStateAsync().ConfigureAwait(false);

// ...
// Any time after
// ...

// Get the difference from the state
var differenceFromState = await client.UpdatesService.GetUpdatesFromState(currentState).ConfigureAwait(false);

TDifference difference = differenceFromState as TDifference;

foreach(var update in difference.OtherUpdates) {
    // Handle IUpdate
}

foreach(var message in difference.NewMessages) {
    // Handle IMessage
}

Downloading a file

if (message.Media is TMessageMediaPhoto messageMediaPhoto)
{
	if (messageMediaPhoto.Photo is TPhoto photo)
	{
		TPhotoSize photosize = photo.Sizes.OfType<TPhotoSize>().OrderByDescending(m => m.Size).FirstOrDefault();

		// Be sure to do this in a seperate task, else it will wait indefinately because you cannot process messages and sending requests at the same thread
		Task.Run(() =>
		{
			byte[] fileBytes = clientApi.FileService.DownloadFullFileAsync(new TInputFileLocation
			{
				FileReference = (photosize.Location as TFileLocation).FileReference,
				VolumeId = photosize.Location.VolumeId,
				LocalId = photosize.Location.LocalId,
				Secret = photosize.Location.Secret
			}, CancellationToken.None).Result;

			File.WriteAllBytes("File.jpg", fileBytes);
		});
	}
}

Sending a file

IInputFile inputFile;

using (FileStream fileStream = File.Open(signalFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
	inputFile = clientApi.FileService.UploadFileAsync(signalFile, fileStream).Result;
}

var result = clientApi.MessagesService.SendMediaAsync(new TInputPeerChannel { ChannelId = TheChannelId, AccessHash = TheAccessHashOfChannel }, new TInputMediaUploadedPhoto { File = inputFile }, "A caption if wanted or empty string").Result;

Use a SOCKS5 Proxy

When Telegram is blocked you can use a SOCKS5 proxy.

You can add the following method to create a Socks5ProxyConfig to fill in the ProxyConfig variable of the FactorySettings object.

public static Socks5ProxyConfig ProxyCreate(string ip, int port, string user = null, string pass = null)
{
	Socks5ProxyConfig proxyConfig = null;

	if (!string.IsNullOrEmpty(ip))
	{
		proxyConfig = new Socks5ProxyConfig
		{
			Endpoint = new IPEndPoint(IPAddress.Parse(ip), port),
			Password = string.IsNullOrEmpty(pass) ? null : pass,
			Username = string.IsNullOrEmpty(user) ? null : user,
		};
	}

	return proxyConfig;
}

And then use it like this:

var settings = new FactorySettings
{
...
	ServerAddress = serverAddress, //e.g 149.154.167.50
	ServerPublicKey = rsaPublicKey, // e.g -----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAwVACPi9w23mF3tBk...
	ServerPort = serverPort,
	ProxyConfig = ProxyCreate("1.2.3.4", 1234),
...
};