API හරහා PowerShell වෙතින් Google පරිශීලකයන් නිර්මාණය කිරීම

හෙලෝ!

G Suite පරිශීලකයන් හැසිරවීමට Google API සමඟ PowerShell අන්තර්ක්‍රියා ක්‍රියාත්මක කිරීම මෙම ලිපියෙන් විස්තර කෙරේ.

අපි ආයතනය පුරා අභ්‍යන්තර සහ වලාකුළු සේවා කිහිපයක් භාවිත කරමු. බොහෝ දුරට, ඒවායේ අවසරය Google හෝ Active Directory වෙත පැමිණේ, ඒ අතර අපට අනුරුවක් පවත්වා ගත නොහැක; ඒ අනුව, නව සේවකයෙකු පිටව ගිය විට, ඔබ මෙම පද්ධති දෙකෙහි ගිණුමක් සාදා/සක්‍රීය කළ යුතුය. ක්‍රියාවලිය ස්වයංක්‍රීය කිරීම සඳහා, තොරතුරු රැස්කර සේවා දෙකටම යවන ස්ක්‍රිප්ට් එකක් ලිවීමට අපි තීරණය කළෙමු.

අවසරය

අවශ්‍යතා සකස් කිරීමේදී, අවසරය සඳහා සැබෑ මානව පරිපාලකයින් භාවිතා කිරීමට අපි තීරණය කළෙමු; මෙය අහම්බෙන් හෝ හිතාමතා දැවැන්ත වෙනස්කම් සිදු වූ විට ක්‍රියාවන් විශ්ලේෂණය කිරීම සරල කරයි.

Google APIs OAuth 2.0 ප්‍රොටෝකෝලය සත්‍යාපනය සහ අවසරය සඳහා භාවිතා කරයි. භාවිත අවස්ථා සහ වඩාත් සවිස්තරාත්මක විස්තර මෙහි සොයා ගත හැක: Google API වෙත ප්‍රවේශ වීමට OAuth 2.0 භාවිතා කිරීම.

මම ඩෙස්ක්ටොප් යෙදුම්වල අවසරය සඳහා භාවිතා කරන ස්ක්‍රිප්ට් තෝරා ගත්තෙමි. සේවා ගිණුමක් භාවිතා කිරීමට විකල්පයක් ද ඇත, පරිශීලකයාගෙන් අනවශ්ය චලනයන් අවශ්ය නොවේ.

පහත පින්තූරය Google පිටුවෙන් තෝරාගත් දර්ශනයේ ක්‍රමානුකූල විස්තරයකි.

API හරහා PowerShell වෙතින් Google පරිශීලකයන් නිර්මාණය කිරීම

  1. පළමුව, අපි GET පරාමිති සඳහන් කරමින් Google ගිණුම් සත්‍යාපන පිටුවට පරිශීලකයා යවමු:
    • යෙදුම් හැඳුනුම්පත
    • යෙදුමට ප්‍රවේශය අවශ්‍ය ප්‍රදේශ
    • ක්රියා පටිපාටිය සම්පූර්ණ කිරීමෙන් පසු පරිශීලකයා යළි හරවා යවනු ලබන ලිපිනය
    • අපි ටෝකනය යාවත්කාලීන කරන ආකාරය
    • ආරක්ෂණ කේතය
    • සත්යාපන කේත සම්ප්රේෂණ ආකෘතිය

  2. අවසරය සම්පූර්ණ කිරීමෙන් පසුව, පරිශීලකයා GET පරාමිති මගින් සම්මත කරන ලද දෝෂයක් හෝ අවසර කේතයක් සමඟින් පළමු ඉල්ලීමෙහි සඳහන් පිටුවට හරවා යවනු ලැබේ.
  3. යෙදුමට (ස්ක්‍රිප්ට්) මෙම පරාමිති ලබා ගැනීමට අවශ්‍ය වන අතර, කේතය ලැබුණේ නම්, ටෝකන ලබා ගැනීමට පහත ඉල්ලීම කරන්න
  4. ඉල්ලීම නිවැරදි නම්, Google API ආපසු ලබා දෙයි:
    • අපට ඉල්ලීම් කළ හැකි ප්‍රවේශ ටෝකනය
    • මෙම ටෝකනයේ වලංගු කාලය
    • ප්‍රවේශ ටෝකනය නැවුම් කිරීමට අවශ්‍ය ටෝකනය නැවුම් කරන්න.

පළමුව ඔබ Google API කොන්සෝලය වෙත යා යුතුය: අක්තපත්‍ර - Google API කොන්සෝලය, අපේක්ෂිත යෙදුම තෝරන්න සහ අක්තපත්‍ර කොටසේ සේවාදායක OAuth හඳුනාගැනීමක් සාදන්න. එහිදී (හෝ පසුව, සාදන ලද හඳුනාගැනීමේ ගුණාංගවල) ඔබ යළි හරවා යැවීමට අවසර දී ඇති ලිපිනයන් සඳහන් කළ යුතුය. අපගේ නඩුවේදී, මේවා විවිධ වරායන් සහිත දේශීය සත්කාරක ඇතුළත් කිරීම් කිහිපයක් වනු ඇත (පහත බලන්න).

ස්ක්‍රිප්ට් ඇල්ගොරිතම කියවීම වඩාත් පහසු කිරීම සඳහා, ඔබට ප්‍රවේශය ආපසු ලබා දෙන සහ යෙදුම සඳහා ටෝකන නැවුම් කරන වෙනම කාර්යයකින් පළමු පියවර පෙන්විය හැක:

$client_secret = 'Our Client Secret'
$client_id = 'Our Client ID'
function Get-GoogleAuthToken {
  if (-not [System.Net.HttpListener]::IsSupported) {
    "HttpListener is not supported."
    exit 1
  }
  $codeverifier = -join ((65..90) + (97..122) + (48..57) + 45 + 46 + 95 + 126 |Get-Random -Count 60| % {[char]$_})
  $hasher = new-object System.Security.Cryptography.SHA256Managed
  $hashByteArray = $hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($codeverifier))
  $base64 = ((([System.Convert]::ToBase64String($hashByteArray)).replace('=','')).replace('+','-')).replace('/','_')
  $ports = @(10600,15084,39700,42847,65387,32079)
  $port = $ports[(get-random -Minimum 0 -maximum 5)]
  Write-Host "Start browser..."
  Start-Process "https://accounts.google.com/o/oauth2/v2/auth?code_challenge_method=S256&code_challenge=$base64&access_type=offline&client_id=$client_id&redirect_uri=http://localhost:$port&response_type=code&scope=https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/admin.directory.group"
  $listener = New-Object System.Net.HttpListener
  $listener.Prefixes.Add("http://localhost:"+$port+'/')
  try {$listener.Start()} catch {
    "Unable to start listener."
    exit 1
  }
  while (($code -eq $null)) {
    $context = $listener.GetContext()
    Write-Host "Connection accepted" -f 'mag'
    $url = $context.Request.RawUrl
    $code = $url.split('?')[1].split('=')[1].split('&')[0]
    if ($url.split('?')[1].split('=')[0] -eq 'error') {
      Write-Host "Error!"$code -f 'red'
      $buffer = [System.Text.Encoding]::UTF8.GetBytes("Error!"+$code)
      $context.Response.ContentLength64 = $buffer.Length
      $context.Response.OutputStream.Write($buffer, 0, $buffer.Length)
      $context.Response.OutputStream.Close()
      $listener.Stop()
      exit 1
    }
    $buffer = [System.Text.Encoding]::UTF8.GetBytes("Now you can close this browser tab.")
    $context.Response.ContentLength64 = $buffer.Length
    $context.Response.OutputStream.Write($buffer, 0, $buffer.Length)
    $context.Response.OutputStream.Close()
    $listener.Stop()
  }
  Return Invoke-RestMethod -Method Post -Uri "https://www.googleapis.com/oauth2/v4/token" -Body @{
    code = $code
    client_id = $client_id
    client_secret = $client_secret
    redirect_uri = 'http://localhost:'+$port
    grant_type = 'authorization_code'
    code_verifier   = $codeverifier
  }
  $code = $null

අපි OAuth සේවාලාභී හඳුනාගැනීමේ ගුණාංගවලින් ලබාගත් සේවාලාභී ID සහ සේවාලාභී රහස සැකසූ අතර, කේත සත්‍යාපනය යනු වෙන් නොකළ අක්ෂරවලින් අහඹු ලෙස ජනනය කළ යුතු අක්ෂර 43 සිට 128 දක්වා වූ තන්තුවකි: [AZ] / [az] / [0-9 ] / "-" / "." / "_" / "~".

එවිට මෙම කේතය නැවත සම්ප්රේෂණය වේ. එය පරිශීලක අවසරයෙන් පසු යළි-යොමුවීමක් ලෙස ප්‍රතිචාර දැක්වීමක් ප්‍රහාරකයෙකුට බාධා කළ හැකි අවදානම ඉවත් කරයි.
ඔබට දැනට පවතින ඉල්ලීමේ පැහැදිලි පාඨයකින් කේත සත්‍යාපනයක් යැවිය හැක (එය අර්ථ විරහිත කරයි - මෙය සුදුසු වන්නේ SHA256 සඳහා සහය නොදක්වන පද්ධති සඳහා පමණි), හෝ SHA256 ඇල්ගොරිතම භාවිතයෙන් හැෂ් නිර්මාණය කිරීමෙන්, එය BASE64Url හි කේතනය කළ යුතුය (වෙනස් Base64 සිට වගු අක්ෂර දෙකකින්) සහ අක්ෂර රේඛා අවසානය ඉවත් කිරීම: =.

මීළඟට, අවසර දීමෙන් පසු ප්‍රතිචාරයක් ලබා ගැනීම සඳහා අපි දේශීය යන්ත්‍රයේ http වෙත සවන් දීම ආරම්භ කළ යුතු අතර, එය යළි-යොමුවීමක් ලෙස ආපසු ලබා දෙනු ඇත.

පරිපාලන කාර්යයන් විශේෂ සේවාදායකයක් මත සිදු කරනු ලැබේ, පරිපාලකයින් කිහිප දෙනෙකු එකවර ස්ක්‍රිප්ට් ධාවනය කිරීමේ හැකියාව අපට බැහැර කළ නොහැක, එබැවින් එය වත්මන් පරිශීලකයා සඳහා අහඹු ලෙස වරායක් තෝරා ගනු ඇත, නමුත් මම පූර්ව නිශ්චිත වරායන් සඳහන් කළ නිසා ඒවා API කොන්සෝලය තුළ විශ්වාසදායක ලෙස එකතු කළ යුතුය.

access_type=නොබැඳි බ්‍රවුසරය සමඟ පරිශීලක අන්තර්ක්‍රියාකාරිත්වයකින් තොරව යෙදුමට කල් ඉකුත් වූ ටෝකනයක් තනිවම යාවත්කාලීන කළ හැකි බවයි,
response_type=කේතය කේතය ආපසු ලබා දෙන ආකාරය පිළිබඳ ආකෘතිය සකසයි (පරිශීලකයා බ්‍රවුසරයෙන් කේතය පිටපත් කළ විට පැරණි අවසර ක්‍රමයට යොමු කිරීම),
විෂය පථය ප්රවේශයේ විෂය පථය සහ වර්ගය පෙන්නුම් කරයි. ඒවා හිස්තැන් හෝ %20 (URL කේතීකරණයට අනුව) මගින් වෙන් කළ යුතුය. වර්ග සහිත ප්‍රවේශ ප්‍රදේශ ලැයිස්තුවක් මෙහි දැකිය හැක: OAuth 2.0 Google API සඳහා විෂය පථයන්.

අවසර කේතය ලැබීමෙන් පසු, යෙදුම බ්‍රවුසරයට සමීප පණිවිඩයක් ලබා දෙනු ඇත, වරායට සවන් දීම නවත්වා ටෝකනය ලබා ගැනීමට POST ඉල්ලීමක් යවනු ඇත. අපි එහි කලින් සඳහන් කළ හැඳුනුම්පත සහ කොන්සෝල API වෙතින් රහස්, පරිශීලකයා හරවා යවනු ලබන ලිපිනය සහ ප්‍රොටෝකෝල පිරිවිතරයන්ට අනුකූලව grant_type කරන්නෙමු.

ප්‍රතිචාරයක් වශයෙන්, අපට ප්‍රවේශ ටෝකනයක්, එහි වලංගු කාල සීමාව තත්පර කිහිපයකින් සහ Refresh ටෝකනයක් ලැබෙනු ඇත, එමඟින් අපට ප්‍රවේශ ටෝකනය යාවත්කාලීන කළ හැකිය.

යෙදුම දිගු ආයු කාලයක් සහිත ආරක්ෂිත ස්ථානයක ටෝකන ගබඩා කළ යුතුය, එබැවින් අපි ලැබුණු ප්‍රවේශය අවලංගු කරන තෙක්, යෙදුම නැවුම් ටෝකනය ආපසු ලබා නොදේ. අවසානයේදී, මම ටෝකනය අවලංගු කිරීමට ඉල්ලීමක් එකතු කළෙමි; අයදුම්පත සාර්ථකව සම්පූර්ණ නොකළේ නම් සහ නැවුම් ටෝකනය ආපසු ලබා නොදුන්නේ නම්, එය නැවත ක්‍රියා පටිපාටිය ආරම්භ කරනු ඇත (ටර්මිනලයේ දේශීයව ටෝකන ගබඩා කිරීම අනාරක්ෂිත යැයි අපි සැලකුවෙමු. ගුප්ත ලේඛන සමඟ දේවල් සංකීර්ණ කිරීමට හෝ බ්‍රවුසරය නිතර විවෘත කිරීමට අවශ්‍ය නැත).

do {
  $token_result = Get-GoogleAuthToken
  $token = $token_result.access_token
  if ($token_result.refresh_token -eq $null) {
    Write-Host ("Session is not destroyed. Revoking token...")
    Invoke-WebRequest -Uri ("https://accounts.google.com/o/oauth2/revoke?token="+$token)
  }
} while ($token_result.refresh_token -eq $null)
$refresh_token = $token_result.refresh_token
$minute = ([int]("{0:mm}" -f ([timespan]::fromseconds($token_result.expires_in))))+((Get-date).Minute)-2
if ($minute -lt 0) {$minute += 60}
elseif ($minute -gt 59) {$minute -=60}
$token_expire = @{
  hour = ([int]("{0:hh}" -f ([timespan]::fromseconds($token_result.expires_in))))+((Get-date).Hour)
  minute = $minute
}

ඔබ දැනටමත් දැක ඇති පරිදි, ටෝකනයක් අවලංගු කරන විට, Invoke-WebRequest භාවිතා වේ. Invoke-RestMethod මෙන් නොව, එය ලැබුණු දත්ත භාවිතා කළ හැකි ආකෘතියකින් ආපසු ලබා නොදෙන අතර ඉල්ලීමේ තත්ත්වය පෙන්වයි.

ඊළඟට, පිවිසුම් + විද්‍යුත් තැපෑලක් උත්පාදනය කරමින් පරිශීලකයාගේ පළමු සහ අවසාන නම ඇතුළත් කිරීමට ස්ක්‍රිප්ට් ඔබෙන් අසයි.

ඉල්ලීම්

මීළඟ ඉල්ලීම් වනුයේ - පළමුවෙන්ම, නව එකක් නිර්මාණය කිරීම හෝ වත්මන් එක සක්රිය කිරීම පිළිබඳ තීරණයක් ලබා ගැනීම සඳහා එකම පිවිසුම සහිත පරිශීලකයෙකු දැනටමත් සිටීද යන්න පරීක්ෂා කිරීම අවශ්ය වේ.

ස්විචය භාවිතා කරමින් තේරීමක් සමඟ එක් ශ්‍රිතයක ආකෘතියෙන් සියලුම ඉල්ලීම් ක්‍රියාත්මක කිරීමට මම තීරණය කළෙමි:

function GoogleQuery {
  param (
    $type,
    $query
  )
  switch ($type) {
    "SearchAccount" {
      Return Invoke-RestMethod -Method Get -Uri "https://www.googleapis.com/admin/directory/v1/users" -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body @{
        domain = 'rocketguys.com'
        query  = "email:$query"
      }
    }
    "UpdateAccount" {
      $body = @{
        name  = @{
          givenName = $query['givenName']
          familyName = $query['familyName']
        }
        suspended = 'false'
        password = $query['password']
        changePasswordAtNextLogin = 'true'
        phones = @(@{
          primary = 'true'
          value = $query['phone']
          type = "mobile"
        })
        orgUnitPath = $query['orgunit']
      }
      Return Invoke-RestMethod -Method Put -Uri ("https://www.googleapis.com/admin/directory/v1/users/"+$query['email']) -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body (ConvertTo-Json $body) -ContentType 'application/json; charset=utf-8'
    }
    
    "CreateAccount" {
      $body = @{
        primaryEmail = $query['email']
        name  = @{
          givenName = $query['givenName']
          familyName = $query['familyName']
        }
        suspended = 'false'
        password = $query['password']
        changePasswordAtNextLogin = 'true'
        phones = @(@{
          primary = 'true'
          value = $query['phone']
          type = "mobile"
        })
        orgUnitPath = $query['orgunit']
      }
      Return Invoke-RestMethod -Method Post -Uri "https://www.googleapis.com/admin/directory/v1/users" -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body (ConvertTo-Json $body) -ContentType 'application/json; charset=utf-8'
    }
    "AddMember" {
      $body = @{
        userKey = $query['email']
      }
      $ifrequest = Invoke-RestMethod -Method Get -Uri "https://www.googleapis.com/admin/directory/v1/groups" -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body $body
      $array = @()
      foreach ($group in $ifrequest.groups) {$array += $group.email}
      if ($array -notcontains $query['groupkey']) {
        $body = @{
          email = $query['email']
          role = "MEMBER"
        }
        Return Invoke-RestMethod -Method Post -Uri ("https://www.googleapis.com/admin/directory/v1/groups/"+$query['groupkey']+"/members") -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body (ConvertTo-Json $body) -ContentType 'application/json; charset=utf-8'
      } else {
        Return ($query['email']+" now is a member of "+$query['groupkey'])
      }
    }
  }
}

සෑම ඉල්ලීමකදීම, ඔබ ටෝකන වර්ගය සහ ප්‍රවේශ ටෝකනයම අඩංගු අවසර ශීර්ෂයක් එවිය යුතුය. දැනට, ටෝකන් වර්ගය සෑම විටම Bearer වේ. නිසා අපි ටෝකනය කල් ඉකුත් වී නැති බව පරීක්ෂා කර එය නිකුත් කළ මොහොතේ සිට පැයකට පසු එය යාවත්කාලීන කළ යුතුයි, මම ප්‍රවේශ ටෝකනයක් ආපසු ලබා දෙන වෙනත් කාර්යයක් සඳහා ඉල්ලීමක් සඳහන් කළෙමි. පළමු ප්‍රවේශ ටෝකනය ලැබෙන විට එම කේත කොටස ස්ක්‍රිප්ට් ආරම්භයේ ඇත:

function Get-GoogleToken {
  if (((Get-date).Hour -gt $token_expire.hour) -or (((Get-date).Hour -ge $token_expire.hour) -and ((Get-date).Minute -gt $token_expire.minute))) {
  Write-Host "Token Expired. Refreshing..."
    $request = (Invoke-RestMethod -Method Post -Uri "https://www.googleapis.com/oauth2/v4/token" -ContentType 'application/x-www-form-urlencoded' -Body @{
      client_id = $client_id
      client_secret = $client_secret
      refresh_token = $refresh_token
      grant_type = 'refresh_token'
    })
    $token = $request.access_token
    $minute = ([int]("{0:mm}" -f ([timespan]::fromseconds($request.expires_in))))+((Get-date).Minute)-2
    if ($minute -lt 0) {$minute += 60}
    elseif ($minute -gt 59) {$minute -=60}
    $script:token_expire = @{
      hour = ([int]("{0:hh}" -f ([timespan]::fromseconds($request.expires_in))))+((Get-date).Hour)
      minute = $minute
    }
  }
  return $token
}

පැවැත්ම සඳහා පිවිසුම පරීක්ෂා කිරීම:

function Check_Google {
  $query = (GoogleQuery 'SearchAccount' $username)
  if ($query.users -ne $null) {
    $user = $query.users[0]
    Write-Host $user.name.fullName' - '$user.PrimaryEmail' - suspended: '$user.Suspended
    $GAresult = $user
  }
  if ($GAresult) {
      $return = $GAresult
  } else {$return = 'gg'}
  return $return
}

විද්‍යුත් තැපෑල:$query ඉල්ලීම අන්වර්ථ ඇතුළුව, හරියටම එම විද්‍යුත් තැපෑල සහිත පරිශීලකයෙකු සෙවීමට API වෙතින් අසනු ඇත. ඔබට Wildcard ද භාවිතා කළ හැකිය: =, :, :{PREFIX}*.

දත්ත ලබා ගැනීම සඳහා, GET ඉල්ලීම් ක්‍රමය භාවිතා කරන්න, දත්ත ඇතුළු කිරීමට (ගිණුමක් නිර්මාණය කිරීම හෝ කණ්ඩායමකට සාමාජිකයෙකු එක් කිරීම) - POST, පවතින දත්ත යාවත්කාලීන කිරීමට - PUT, වාර්තාවක් මකා දැමීමට (උදාහරණයක් ලෙස, කණ්ඩායමක සාමාජිකයෙකු) - මකන්න.

ස්ක්‍රිප්ටය දුරකථන අංකයක් (අවලංගු නොකළ තන්තුවක්) සහ කලාපීය බෙදාහැරීමේ කණ්ඩායමකට ඇතුළත් කිරීම සඳහා ද අසනු ඇත. තෝරාගත් ක්‍රියාකාරී නාමාවලිය OU මත පදනම්ව පරිශීලකයාට තිබිය යුතු ආයතනික ඒකකය එය තීරණය කරන අතර මුරපදයක් සමඟ පැමිණේ:

do {
  $phone = Read-Host "Телефон в формате +7хххххххх"
} while (-not $phone)
do {
    $moscow = Read-Host "В Московский офис? (y/n) "
} while (-not (($moscow -eq 'y') -or ($moscow -eq 'n')))
$orgunit = '/'
if ($OU -like "*OU=Delivery,OU=Users,OU=ROOT,DC=rocket,DC=local") {
    Write-host "Будет создана в /Team delivery"
    $orgunit = "/Team delivery"
}
$Password =  -join ( 48..57 + 65..90 + 97..122 | Get-Random -Count 12 | % {[char]$_})+"*Ba"

ඉන්පසු ඔහු ගිණුම හැසිරවීමට පටන් ගනී:

$query = @{
  email = $email
  givenName = $firstname
  familyName = $lastname
  password = $password
  phone = $phone
  orgunit = $orgunit
}
if ($GMailExist) {
  Write-Host "Запускаем изменение аккаунта" -f mag
  (GoogleQuery 'UpdateAccount' $query) | fl
  write-host "Не забудь проверить группы у включенного $Username в Google."
} else {
  Write-Host "Запускаем создание аккаунта" -f mag
  (GoogleQuery 'CreateAccount' $query) | fl
}
if ($moscow -eq "y"){
  write-host "Добавляем в группу moscowoffice"
  $query = @{
    groupkey = '[email protected]'
    email = $email
  }
  (GoogleQuery 'AddMember' $query) | fl
}

ගිණුමක් යාවත්කාලීන කිරීම සහ නිර්මාණය කිරීම සඳහා වන කාර්යයන් සමාන වාක්‍ය ඛණ්ඩයක් ඇත; සියලුම අමතර ක්ෂේත්‍ර අවශ්‍ය නොවේ; දුරකථන අංක සහිත කොටසේ, ඔබ අංකය සහ එහි වර්ගය සමඟ එක් වාර්තාවක් දක්වා අඩංගු විය හැකි අරාවක් සඳහන් කළ යුතුය.

කණ්ඩායමකට පරිශීලකයෙකු එක් කිරීමේදී දෝෂයක් නොලැබීම සඳහා, පරිශීලකයාගෙන්ම කණ්ඩායම් සාමාජිකයින්ගේ ලැයිස්තුවක් හෝ සංයුතියක් ලබා ගැනීමෙන් ඔහු දැනටමත් මෙම කණ්ඩායමේ සාමාජිකයෙකු දැයි පරීක්ෂා කළ හැකිය.

නිශ්චිත පරිශීලකයෙකුගේ කණ්ඩායම් සාමාජිකත්වය විමසීම පුනරාවර්තන නොවන අතර සෘජු සාමාජිකත්වය පමණක් පෙන්වනු ඇත. පරිශීලකයා සාමාජිකයෙකු වන ළමා කණ්ඩායමක් දැනටමත් ඇති මාපිය කණ්ඩායමක පරිශීලකයෙකු ඇතුළත් කිරීම සාර්ථක වනු ඇත.

නිගමනය

ඉතිරිව ඇත්තේ නව ගිණුම සඳහා පරිශීලකයාට මුරපදය යැවීමයි. අපි මෙය SMS මගින් සිදු කරන අතර, උපදෙස් සමඟ සාමාන්‍ය තොරතුරු යවා පුද්ගලික විද්‍යුත් තැපෑලකට පුරනය වන්න, එය දුරකථන අංකයක් සමඟ බඳවා ගැනීමේ දෙපාර්තමේන්තුව විසින් සපයනු ලැබේ. විකල්පයක් ලෙස, ඔබට මුදල් ඉතිරි කර ඔබගේ මුරපදය රහස් විදුලි පණිවුඩ කතාබස් වෙත යැවිය හැකිය, එය දෙවන සාධකය ලෙසද සැලකිය හැකිය (MacBooks ව්යතිරේකයක් වනු ඇත).

අවසානය දක්වා කියවූ ඔබට ස්තුතියි. ලිපි ලිවීමේ විලාසය වැඩිදියුණු කිරීම සඳහා යෝජනා දැකීමට මම සතුටු වන අතර පිටපත් ලිවීමේදී අඩු දෝෂයක් අල්ලා ගැනීමට ඔබට ප්‍රාර්ථනා කරමි =)

තේමාත්මකව ප්‍රයෝජනවත් විය හැකි හෝ ප්‍රශ්න වලට සරලව පිළිතුරු දිය හැකි සබැඳි ලැයිස්තුව:

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න