728x90
728x170
▶ KakaoAPIHelper.cs
using System.Windows.Forms;
using Newtonsoft.Json.Linq;
using RestSharp;
namespace TestProject
{
/// <summary>
/// 카카오 API 헬퍼
/// </summary>
public class KakaoAPIHelper
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 애플리케이션 ID - ApplicationID
/// <summary>
/// 애플리케이션 ID
/// </summary>
public string ApplicationID { get; protected set; }
#endregion
#region REST API 키 - RESTAPIKey
/// <summary>
/// REST API 키
/// </summary>
public string RESTAPIKey { get; protected set; }
#endregion
#region 리다이렉트 URL - RedirectURL
/// <summary>
/// 리다이렉트 URL
/// </summary>
public string RedirectURL { get; protected set; }
#endregion
#region 인증 코드 - AuthenticationCode
/// <summary>
/// 인증 코드
/// </summary>
public string AuthenticationCode { get; protected set; }
#endregion
#region 액세스 토큰 - AccessToken
/// <summary>
/// 액세스 토큰
/// </summary>
public string AccessToken { get; protected set; }
#endregion
#region 갱신 토큰 - RefreshToken
/// <summary>
/// 갱신 토큰
/// </summary>
public string RefreshToken { get; protected set; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - KakaoAPIHelper(applicationID, restAPIKey, redirectURL)
/// <summary>
/// 생성자
/// </summary>
/// <param name="applicationID">애플리케이션 ID</param>
/// <param name="restAPIKey">REST API 키</param>
/// <param name="redirectURL">리다이렉트 URL</param>
public KakaoAPIHelper(string applicationID, string restAPIKey, string redirectURL)
{
ApplicationID = applicationID;
RESTAPIKey = restAPIKey;
RedirectURL = redirectURL;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 로그인 URL 구하기 - GetLoginURL()
/// <summary>
/// 로그인 URL 구하기
/// </summary>
/// <returns>로그인 URL</returns>
public string GetLoginURL()
{
return $"https://kauth.kakao.com/oauth/authorize?response_type=code&client_id={RESTAPIKey}&redirect_uri={RedirectURL}&scope=talk_message,friends";
}
#endregion
#region 인증 코드 설정하기 - SetAuthenticationCode(authenticationCodeURL)
/// <summary>
/// 인증 코드 설정하기
/// </summary>
/// <param name="authenticationCodeURL">인증 코드 URL</param>
public void SetAuthenticationCode(string authenticationCodeURL)
{
string authenticationCode = authenticationCodeURL.Substring(authenticationCodeURL.IndexOf("=") + 1);
if(authenticationCodeURL.CompareTo($"{RedirectURL}?code={authenticationCode}") == 0)
{
AuthenticationCode = authenticationCode;
}
else
{
AuthenticationCode = null;
}
}
#endregion
#region 액세스 토큰 설정하기 - SetAccessToken()
/// <summary>
/// 액세스 토큰 설정하기
/// </summary>
public void SetAccessToken()
{
RestClient client = new RestClient();
RestRequest request = new RestRequest("https://kauth.kakao.com/oauth/token", Method.POST);
request.AddParameter("grant_type" , "authorization_code");
request.AddParameter("client_id" , RESTAPIKey );
request.AddParameter("redirect_uri", RedirectURL );
request.AddParameter("code" , AuthenticationCode );
IRestResponse response = client.Execute(request);
if(response.IsSuccessful)
{
JObject responseObject = JObject.Parse(response.Content);
AccessToken = responseObject["access_token" ].ToString();
RefreshToken = responseObject["refresh_token"].ToString();
}
}
#endregion
#region 액세스 토큰 갱신하기 - UpdateAccessToken()
/// <summary>
/// 액세스 토큰 갱신하기
/// </summary>
public void UpdateAccessToken()
{
RestClient client = new RestClient();
RestRequest request = new RestRequest("https://kauth.kakao.com/oauth/token", Method.POST);
request.AddParameter("grant_type" , "refresh_token");
request.AddParameter("client_id" , RESTAPIKey );
request.AddParameter("refresh_token", RefreshToken );
IRestResponse response = client.Execute(request);
if(response.IsSuccessful)
{
JObject responseObject = JObject.Parse(response.Content);
AccessToken = responseObject["access_token" ].ToString();
if(responseObject["refresh_token"] != null)
{
RefreshToken = responseObject["refresh_token"].ToString();
}
}
}
#endregion
#region 로그인 하기 - Login()
/// <summary>
/// 로그인 하기
/// </summary>
/// <returns>처리 결과</returns>
public bool Login()
{
LoginForm form = new LoginForm(this);
form.ShowInTaskbar = false;
form.StartPosition = FormStartPosition.CenterScreen;
DialogResult result = form.ShowDialog();
return (result == DialogResult.OK);
}
#endregion
#region 로그아웃 하기 - Logout()
/// <summary>
/// 로그아웃 하기
/// </summary>
/// <returns>처리 결과</returns>
public bool Logout()
{
RestClient client = new RestClient();
RestRequest request = new RestRequest("https://kapi.kakao.com/v1/user/unlink", Method.POST);
request.AddHeader("Authorization", $"bearer {AccessToken}");
AuthenticationCode = null;
AccessToken = null;
return client.Execute(request).IsSuccessful;
}
#endregion
#region 나에게 커스텀 메시지 보내기 - SendCustomMessageToMySelf(message)
/// <summary>
/// 나에게 커스텀 메시지 보내기
/// </summary>
/// <param name="message">메시지</param>
/// <returns>처리 결과</returns>
public bool SendCustomMessageToMySelf(JObject templateObject)
{
RestClient client = new RestClient();
RestRequest request = new RestRequest("https://kapi.kakao.com/v2/api/talk/memo/default/send", Method.POST);
request.AddHeader("Authorization", $"bearer {AccessToken}");
request.AddParameter("template_object", templateObject);
return client.Execute(request).IsSuccessful;
}
#endregion
#region 나에게 템플리트 메시지 보내기 - SendTemplateMessageToMySelf(templateMessageID)
/// <summary>
/// 나에게 템플리트 메시지 보내기
/// </summary>
/// <param name="templateMessageID">템플리트 메시지 ID</param>
/// <returns>처리 결과</returns>
public bool SendTemplateMessageToMySelf(string templateMessageID)
{
RestClient client = new RestClient();
RestRequest request = new RestRequest("https://kapi.kakao.com/v2/api/talk/memo/send", Method.POST);
request.AddHeader("Authorization", $"bearer {AccessToken}");
request.AddParameter("template_id", templateMessageID);
return client.Execute(request).IsSuccessful;
}
#endregion
}
}
▶ LoginForm.cs
using System.Windows.Forms;
namespace TestProject
{
/// <summary>
/// 로그인 폼
/// </summary>
public partial class LoginForm : Form
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 카카오 API 헬퍼
/// </summary>
private KakaoAPIHelper kakaoAPIHelper;
/// <summary>
/// 로그인 URL
/// </summary>
private string loginURL = null;
/// <summary>
/// 시도 카운트
/// </summary>
private int tryCount = 0;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - LoginForm()
/// <summary>
/// 생성자
/// </summary>
public LoginForm(KakaoAPIHelper helper)
{
this.kakaoAPIHelper = helper;
InitializeComponent();
this.webBrowser.ScriptErrorsSuppressed = true;
this.webBrowser.DocumentCompleted += webBrowser_DocumentCompleted;
this.loginURL = this.kakaoAPIHelper.GetLoginURL();
this.webBrowser.Navigate(this.loginURL);
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 웹 브라우저 문서 완료시 처리하기 - webBrowser_DocumentCompleted(sender, e)
/// <summary>
/// 웹 브라우저 문서 완료시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
string url = this.webBrowser.Url.ToString();
if(this.loginURL == url)
{
}
else
{
this.kakaoAPIHelper.SetAuthenticationCode(url);
if(!string.IsNullOrEmpty(this.kakaoAPIHelper.AuthenticationCode))
{
this.kakaoAPIHelper.SetAccessToken();
DialogResult = DialogResult.OK;
Close();
}
else
{
if(this.tryCount < 3)
{
this.tryCount++;
this.webBrowser.Navigate(this.loginURL);
}
else
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}
}
#endregion
}
}
▶ MainForm.cs
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.Windows.Forms;
using Newtonsoft.Json.Linq;
namespace TestProject
{
/// <summary>
/// 메인 폼
/// </summary>
public partial class MainForm : Form
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 카카오 API 헬퍼
/// </summary>
private KakaoAPIHelper kakaoAPIHelper;
/// <summary>
/// 애플리케이션 ID
/// </summary>
private readonly string applicationID = "[애플리케이션 ID를 설정한다.]";
/// <summary>
/// REST API 키
/// </summary>
private readonly string restAPIKey = "[REST API 키를 설정한다.]";
/// <summary>
/// 리다이렉트 URL
/// </summary>
private readonly string redirectURL = "[Redirect URI를 설정한다.]";
/// <summary>
/// 메시지 템플리트 ID
/// </summary>
private readonly string messageTemplateID = "[메시지 템플릿 ID를 설정한다.]";
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
this.kakaoAPIHelper = new KakaoAPIHelper(this.applicationID, this.restAPIKey, this.redirectURL);
Load += Form_Load;
this.loginButton.Click += loginButton_Click;
this.refreshTokenButton.Click += refreshTokenButton_Click;
this.sendToMySelfSendButton.Click += sendToMySelfSendButton_Click;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 폼 로드시 처리하기 - Form_Load(sender, e)
/// <summary>
/// 폼 로드시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Form_Load(object sender, EventArgs e)
{
string applicationFileName = $"{Process.GetCurrentProcess().ProcessName}.exe";
SetRegistryKeyForWebBrowserControl(applicationFileName);
}
#endregion
#region 로그인 버튼 클릭시 처리하기 - loginButton_Click(sender, e)
/// <summary>
/// 로그인 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void loginButton_Click(object sender, EventArgs e)
{
if(this.loginButton.Text == "로그인")
{
bool result = this.kakaoAPIHelper.Login();
if(result)
{
this.loginButton.Text = "로그아웃";
}
}
else
{
bool result = this.kakaoAPIHelper.Logout();
if(result)
{
this.loginButton.Text = "로그인";
}
}
}
#endregion
#region 토큰 갱신 버튼 클릭시 처리하기 - refreshTokenButton_Click(sender, e)
/// <summary>
/// 토큰 갱신 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void refreshTokenButton_Click(object sender, EventArgs e)
{
this.kakaoAPIHelper.UpdateAccessToken();
}
#endregion
#region 보내기 버튼 클릭시 처리하기 (나에게 발송) - sendToMySelfSendButton_Click(sender, e)
/// <summary>
/// 보내기 버튼 클릭시 처리하기 (나에게 발송)
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void sendToMySelfSendButton_Click(object sender, EventArgs e)
{
if(this.sendToMySelfCustomMessageRadioButton.Checked)
{
SendCustomMessageToMySelf(this.sendToMySelfMessageTextBox.Text);
this.sendToMySelfMessageTextBox.Text = string.Empty;
}
else
{
SendTemplateMessageToMySelf();
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 웹 브라우저 컨트롤용 레지스트 키 설정하기 - SetRegistryKeyForWebBrowserControl(applicationFileName)
/// <summary>
/// 웹 브라우저 컨트롤용 레지스트 키 설정하기
/// </summary>
/// <param name="applicationFileName">애플리케이션 파일명</param>
/// <remarks>WebBrowser 컨트롤을 Internet Explorer 11 버전으로 동작하도록 해준다.</remarks>
private void SetRegistryKeyForWebBrowserControl(string applicationFileName)
{
RegistryKey registryKey = null;
try
{
registryKey = Registry.LocalMachine.OpenSubKey
(
@"SOFTWARE\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION",
true
);
if(registryKey == null)
{
MessageBox.Show(this, "해당 레지스트리 키를 찾을 수 없습니다.");
return;
}
string registryKeyValue = Convert.ToString(registryKey.GetValue(applicationFileName));
if(registryKeyValue == "11001")
{
registryKey.Close();
return;
}
if(string.IsNullOrEmpty(registryKeyValue))
{
registryKey.SetValue(applicationFileName, unchecked((int)0x2AF9), RegistryValueKind.DWord);
}
registryKeyValue = Convert.ToString(registryKey.GetValue(applicationFileName));
if(registryKeyValue == "11001")
{
MessageBox.Show(this, "IE11 레지스트리 설정이 완료되었습니다.");
}
else
{
MessageBox.Show(this, $"IE11 레지스트리 설정을 실패했습니다.\n키 값 : {registryKeyValue}");
}
}
catch(Exception exception)
{
MessageBox.Show(this, $"IE11 레지스트리 설정시 에러가 발생했습니다.\n{exception}");
}
finally
{
if(registryKey != null)
{
registryKey.Close();
}
}
}
#endregion
#region 나에게 커스텀 메시지 보내기 - SendCustomMessageToMySelf(message)
/// <summary>
/// 나에게 커스텀 메시지 보내기
/// </summary>
/// <param name="message">메시지</param>
private void SendCustomMessageToMySelf(string message)
{
JObject linkObject = new JObject();
linkObject.Add("web_url" , "https://icodebroker.tistory.com");
linkObject.Add("mobile_web_url", "https://icodebroker.tistory.com");
JObject templateObject = new JObject();
templateObject.Add("object_type" , "text" );
templateObject.Add("text" , message );
templateObject.Add("link" , linkObject );
templateObject.Add("button_title", "링크로 이동");
bool result = this.kakaoAPIHelper.SendCustomMessageToMySelf(templateObject);
if(result)
{
MessageBox.Show(this, "커스텀 메시지 전송을 성공했습니다.");
}
else
{
MessageBox.Show(this, "커스텀 메시지 전송을 실패했습니다.");
}
}
#endregion
#region 나에게 템플리트 메시지 보내기 - SendTemplateMessageToMySelf()
/// <summary>
/// 나에게 템플리트 메시지 보내기
/// </summary>
private void SendTemplateMessageToMySelf()
{
bool result = this.kakaoAPIHelper.SendTemplateMessageToMySelf(this.messageTemplateID);
if(result)
{
MessageBox.Show(this, "템플리트 메시지 전송을 성공했습니다.");
}
else
{
MessageBox.Show(this, "템플리트 메시지 전송을 실패했습니다.");
}
}
#endregion
}
}
※ 관리자 권한으로 실행해야 한다.
728x90
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] 사운드 필터링 사용하기 (0) | 2021.12.09 |
---|---|
[C#/WINFORM] NativeWindow 클래스 : 마우스 캡처 변경시 이벤트 전달하기 (0) | 2021.12.06 |
[C#/WINFORM] 마우스 히트 테스트(Hit Test) 사용하기 (0) | 2021.12.06 |
[C#/WINFORM] 특정 영역에서 마우스 커서 설정하기 (0) | 2021.12.06 |
[C#/WINFORM] 마우스 드래그 대상 이미지 표시하기 (0) | 2021.12.06 |
[C#/WINFORM] 누겟 설치 : CefSharp.WinForms (0) | 2021.11.23 |
[C#/WINFORM] 누겟 설치 : CefSharp.Common (0) | 2021.11.23 |
[C#/WINFORM] WebBrowser 클래스 : Internet Explorer의 브라우저 에뮬레이션 모드 구하기 (0) | 2021.11.23 |
[C#/WINFORM] WebBrowser 클래스 : Internet Explorer 버전 11 사용하기 (0) | 2021.11.23 |
[C#/WINFORM] 카카오 링크를 사용해 나에게 카카오톡 메시지 보내기 (기능 개선) (0) | 2021.11.23 |