쿠팡 파트너스 API 자동등록 프로그램 소개, 소스코드 예제 (C#)

쿠팡 파트너스 API 자동등록 프로그램 소개(범쿠)

1. 쿠팡 파트너스 API 참고하기

2. OAuth를 이용한 구글 블로거 호출하기

예제 자료입니다.

그대로 사용하시면 절대 수익이 발생하지 않습니다.

이러한 프로그램은 정성 들여 작성한 하나의 포스팅을 따라잡을 수 없습니다~

참고용으로만 활용해 주세요.😘

파트너스 아이디랑 채널 아이디는 본인 아이디를 넣으셔야 해요.

기본 화면 안내

쿠팡 파트너스

아이디 입력란, 상품 개수와 상품명을 검색하는 부분, 블로거 게시 연동이 있습니다.

블로거 게시 연동

블로거 게시 연동

블로거 자동 게시를 테스트해보겠습니다.

실행하기

실행하기

아이폰 상위 10순위를 검색해보겠습니다.

쿠팡 랭킹

쿠팡 랭킹

실제 쿠팡 아이폰 랭킹 순

블로거 게시 확인(제목)

블로거 게시 확인

블로거 게시물 확인하기(상단)

블로거 게시 확인(내용)

쿠팡 파트너스 내용

기능은 크게 없습니다. 사진이랑 제목, 금액, 상품설명을 가져오는 것뿐입니다.

참고용 자료입니다~

혹시라도 소스코드가 필요하면 다운로드 파일을 참고해 주세요😘

테스트 블로그

다음은 테스트 게시물이 등록된 블로그입니다. 결과물을 확인할 수 있습니다. => https://beomsangs.blogspot.com

다운로드

다음은 다운로드 링크입니다. 드라이버 공간 확보 등을 위해 파일은 예고 없이 삭제할 수도 있습니다. => https://drive.google.com/file/d/1hQRZBHFz6oQj_aHcVEJBEe7G-3WwlB4H/view?usp=sharing

쿠팡 파트너스 연동 소스 예제(C#)

using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Windows.Media.Animation;
using System.ComponentModel;
using BeomCou.Model;
using AdsJumboWinForm;
using BeomCore;

namespace BeomCou.View
{
    public partial class ViewBeomSang : Window
    {
        public const string g_ver = "2022.08.05.01";
        public const string g_appName = "범쿠";
        public const string g_caption = "범상(https://beomsang.com/)";
        public const string g_beomsangBlg = "https://beomsang.com/";
        public const string g_beomAdsId_BeomCou = "";
        public const int PROD_MAX_CNT = 36;
        public const string c_traceIdPrefix = "V0-126-";
        public const int c_elapsedMonth = 12;
        public const string c_patternUri = "products/(?<pi>.*?)\\?itemId=(?<ii>.*?)&vendorItemId=(?<vi>.*?)$";
        public const string NOTE = "Note";
        public const string ERROR = "Error";
        public const string WARN = "Warn";
        public const string INSERT = "Insert";
        public const string DELETE = "Delete";
        public const string TEST = "Test";
        public const string INTERFACE = "Interface";
        public const string SAVE = "Save";
        public const string LOAD = "Load";
        ActionType? m_setType = null;
        List<CpObj> m_cpObjs = null;
        CpObj m_cpObj;
        WebBrowser[] m_wbs = null;
        private int m_subRowNum = 0;
        DispatcherTimer m_subNavTimer = null;
        bool m_isInit = false;

        enum ActionType
        {
            Navigate,
            P,
            W
        }

        private enum SetVarType
        {
            Init,
            InitOnlyOnce,
            Begin
        }

        private void ShowBannerAds()
        {
            if (Debugger.IsAttached)
                ((BannerAds)adsHost.Child).ShowAd(468, 60, "#ID#");
            else
                ((BannerAds)adsHost.Child).ShowAd(468, 60, g_beomAdsId_BeomCou);
        }

        public ViewBeomSang()
        {
            InitializeComponent();

            ShowBannerAds();

            SetVars(SetVarType.InitOnlyOnce);

            m_isInit = true;
        }

        private void DoAction()
        {
            SetVars(SetVarType.Begin);

            if (DoValidate())
            {
                switch (m_setType)
                {
                    case ActionType.Navigate:
                        webBrowser.Navigate(txtSrc.Text);
                        break;
                    case ActionType.W:
                        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(txtSrc.Text);
                        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                        {
                            SetLog(((HttpWebResponse)response).StatusDescription);

                            using (Stream dataStream = response.GetResponseStream())
                            {
                                using (StreamReader reader = new StreamReader(dataStream))
                                {
                                    string responseFromServer = reader.ReadToEnd();
                                    SetLog(responseFromServer);
                                }
                            }
                        }
                        break;
                    default:
                        throw new Exception("Do : undefined");
                }
            }
            else
            {
                btnExe.IsEnabled = !btnExe.IsEnabled;
            }
        }

        private void SetVars(SetVarType _setVarType)
        {
            try
            {
                switch (_setVarType)
                {
                    case SetVarType.Begin:
                        string category = string.Empty;

                        txtProdNm.TrimText();
                        txtMainId.TrimText();
                        txtSubId.TrimText();
                        txtProdCnt.TrimText();

                        OAuthBeomSang.BLOGGER_CONTENT = string.Empty;
                        OAuthBeomSang.BLOGGER_TITLE = string.Empty;

                        dataGrid.IsReadOnly = true;
                        dataGrid.ItemsSource = null;

                        btnExe.IsEnabled = !btnExe.IsEnabled;
                        SetLog(string.Format("[{0}] {1}", NOTE, "집계를 시작합니다."));
                        webBrowser.LoadCompleted += webBrowser_LoadCompleted;

                        switch (m_setType)
                        {
                            case ActionType.Navigate:
                            case ActionType.P:
                                category = string.Empty;
                                txtSrc.Text = string.Format("https://www.coupang.com/np/search?component={0}&q={1}&channel=user",
                                    category, CoreBeomSang.StrToHex(txtProdNm.Text));
                                break;
                        }
                        break;
                    case SetVarType.InitOnlyOnce:
                        m_setType = ActionType.Navigate;

                        this.Title += g_ver;

                        string d = string.Empty;

                        m_wbs = new WebBrowser[100];

                        m_subNavTimer = new DispatcherTimer();
                        m_subNavTimer.Interval = new TimeSpan(0, 0, 1);

                        cmbStyle.Items.Add(new ComboBoxItem() { Content = "Style1", Tag = CoupangPartnersBeomSang.STYLE.Style1 });
                        cmbStyle.Items.Add(new ComboBoxItem() { Content = "Style is currently only provided in basic form by BeomSang", Tag = CoupangPartnersBeomSang.STYLE.NONE });
                        cmbStyle.SelectedIndex = 0;

                        SetLog(((FrameworkElement)cmbStyle.SelectedItem).Tag.ToString());

                        Title = $"{g_appName} (Version : {g_ver})";

                        txtMainId.IsReadOnly = true;
                        txtSubId.IsReadOnly = true;
                        dataGrid.IsReadOnly = true;

                        if (Properties.Settings.Default.MainId != string.Empty)
                        {
                            txtMainId.Text = Properties.Settings.Default.MainId;

                            SetLog(string.Format("LOAD : {0} = {1}", "파트너스 아이디", Properties.Settings.Default.MainId));
                        }

                        if (Properties.Settings.Default.SubId != string.Empty)
                        {
                            txtSubId.Text = Properties.Settings.Default.SubId;

                            SetLog(string.Format("LOAD : {0} = {1}", "채널 아이디", Properties.Settings.Default.SubId));
                        }

                        if (Properties.Settings.Default.ProdCnt != 0)
                        {
                            txtProdCnt.Text = Properties.Settings.Default.ProdCnt.ToString();

                            SetLog(string.Format("LOAD : {0} = {1}", "상품개수", Properties.Settings.Default.ProdCnt));
                        }

                        if (Properties.Settings.Default.ProdNm != string.Empty)
                        {
                            txtProdNm.Text = Properties.Settings.Default.ProdNm;

                            SetLog(string.Format("LOAD : {0} = {1}", "상품명", Properties.Settings.Default.ProdNm));
                        }

                        if (Properties.Settings.Default.OAuthBloggerId != string.Empty)
                        {
                            txtBloggerId.Text = Properties.Settings.Default.OAuthBloggerId;

                            SetLog(string.Format("LOAD : {0} = {1}", "블로거 아이디", Properties.Settings.Default.OAuthBloggerId));
                        }

                        if (Properties.Settings.Default.BloggerTitle != string.Empty)
                        {
                            txtBloggerTitle.Text = Properties.Settings.Default.BloggerTitle;
                            SetLog($"LOAD : 블로거 타이틀 : {Properties.Settings.Default.BloggerTitle}");
                        }

                        webBrowser.Visibility = Visibility.Hidden;


                        pwdAccessKey.Password = Environment.GetEnvironmentVariable(SaveOAuthBeomSang.OAuthACC, EnvironmentVariableTarget.User);
                        pwdSecretKey.Password = Environment.GetEnvironmentVariable(SaveOAuthBeomSang.OAuthSEC, EnvironmentVariableTarget.User);



                        break;
                    default:
                        SetLog(string.Format("[{0}] Type Undefined", MethodBase.GetCurrentMethod().Name));
                        return;
                }
            }
            catch (Exception ex)
            {
                SetLog(ex.GetExMsg(MethodBase.GetCurrentMethod().Name));
            }
        }

        bool DoValidate()
        {
            if (txtProdNm.Text == string.Empty)
            {
                MessageBox.Show("검색어를 입력하지 않으셨어요.", g_caption, MessageBoxButton.OK, MessageBoxImage.Warning);
                return false;
            }

            if (Regex.IsMatch(txtProdCnt.Text, "^[0-9]+$") == false)
            {
                MessageBox.Show("상품 개수는 숫자여야 합니다.", g_caption, MessageBoxButton.OK, MessageBoxImage.Warning);
                return false;
            }

            if (Convert.ToInt32(txtProdCnt.Text) < 1 || Convert.ToInt32(txtProdCnt.Text) > PROD_MAX_CNT)
            {
                MessageBox.Show($"상품 개수가 1개 미만이거나 {PROD_MAX_CNT}개(최대)를 초과하였습니다.", g_caption, MessageBoxButton.OK, MessageBoxImage.Warning);
                return false;
            }

            if (txtMainId.Text == string.Empty)
            {
                MessageBox.Show("파트너스 아이디를 확인해 주세요.", g_caption, MessageBoxButton.OK, MessageBoxImage.Warning);
                return false;
            }

            if (txtSubId.Text == string.Empty)
            {
                MessageBox.Show("채널 아이디를 확인해 주세요.", g_caption, MessageBoxButton.OK, MessageBoxImage.Warning);
                return false;
            }

            return true;
        }

        private void webBrowser_LoadCompleted(object sender, NavigationEventArgs e)
        {
            webBrowser.LoadCompleted -= webBrowser_LoadCompleted;

            SetLog("webBrowser_LoadCompleted : " + e.Uri.ToString());

            string traceId = c_traceIdPrefix + CoreBeomSang.GetRandomHexNumber(16);
            string tmp = string.Empty;
            int rowId = 0;
            int rowNum = 0;
            string htmlAll = string.Empty;

            switch (m_setType)
            {
                case ActionType.Navigate:
                    m_cpObjs = m_cpObjs.InitCp();

                    foreach (mshtml.IHTMLElement el in ((mshtml.HTMLDocument)webBrowser.Document).getElementsByTagName("li"))
                    {
                        if (el.getAttribute("className") == null || el.getAttribute("className") == string.Empty)
                            continue;

                        if (Regex.IsMatch(el.getAttribute("className"), "search-product"))
                        {
                            if (rowNum >= Convert.ToInt32(txtProdCnt.Text))
                                break;

                            m_cpObj = new CpObj();

                            foreach (Match m in Regex.Matches(el.innerHTML.Replace("\n", ""),
                                @"data-item-id[^0-9]*(?<beomsang>.*?)[^0-9]"))
                            {
                                m_cpObj.ItemId = m.Groups["beomsang"].Value.Trim();
                                break;
                            }

                            foreach (Match m in Regex.Matches(el.innerHTML.Replace("\n", ""),
                                @"data-vendor-item-id[^0-9]*(?<beomsang>.*?)[^0-9]"))
                            {
                                m_cpObj.VendorItemId = m.Groups["beomsang"].Value.Trim();
                                break;
                            }

                            foreach (Match m in Regex.Matches(el.innerHTML.Replace("\n", ""),
                                @"data-product-id[^0-9]*(?<beomsang>.*?)[^0-9]"))
                            {
                                m_cpObj.ProductId = m.Groups["beomsang"].Value.Trim();
                                break;
                            }

                            foreach (Match m in Regex.Matches(el.innerHTML.Replace("\n", ""),
                                @"class *= *""name"" *>(?<beomsang>.*?)</"))
                            {
                                m_cpObj.Name = m.Groups["beomsang"].Value.Trim();
                                break;
                            }

                            foreach (Match m in Regex.Matches(el.innerHTML.Replace("\n", ""),
                                @"class *= *""instant-discount-rate"" *>(?<beomsang>.*?)</"))
                            {
                                m_cpObj.InstantDiscountRate = m.Groups["beomsang"].Value.Trim();
                                break;
                            }

                            foreach (Match m in Regex.Matches(el.innerHTML.Replace("\n", ""),
                                @"class *= *""base-price"" *>(?<beomsang>.*?)</"))
                            {
                                m_cpObj.BasePrice = m.Groups["beomsang"].Value.Trim();
                                break;
                            }

                            foreach (Match m in Regex.Matches(el.innerHTML.Replace("\n", ""),
                                @"class *= *""price-value"" *>(?<beomsang>.*?)</"))
                            {
                                m_cpObj.PriceValue = m.Groups["beomsang"].Value.Trim();
                                break;
                            }

                            foreach (Match m in Regex.Matches(el.innerHTML.Replace("\n", ""),
                                @"class *= *""rating-total-count"" *>(?<beomsang>.*?)</"))
                            {
                                tmp = m.Groups["beomsang"].Value.Trim();
                                m_cpObj.RatingTotalCount = tmp;
                                break;
                            }

                            foreach (Match m in Regex.Matches(el.innerHTML.Replace("\n", ""),
                                @"class *= *""search-product-wrap-img"".*(?<beomsang>//thumbnail.*?)"""))
                            {
                                if (Properties.Settings.Default.ThumbnailSize != 0)
                                    m_cpObj.ThumbnailWiHei = Properties.Settings.Default.ThumbnailSize;
                                else
                                    m_cpObj.ThumbnailWiHei = 492;

                                tmp = m.Groups["beomsang"].Value.Trim();

                                tmp = Regex.Replace(tmp, "/[0-9]{3}x[0-9]{3}ex/", "/" + m_cpObj.ThumbnailWiHei + "x" + m_cpObj.ThumbnailWiHei + "ex/");

                                m_cpObj.Thumbnail = tmp;
                                break;
                            }

                            foreach (Match m in Regex.Matches(el.innerHTML.Replace("\n", ""),
                                @"class *= *""number *no-(?<beomsang>.*?)"""))
                            {
                                tmp = m.Groups["beomsang"].Value.Trim();
                                tmp = Regex.Replace(tmp, "[^0-9]", string.Empty);
                                m_cpObj.No = tmp;
                                break;
                            }

                            foreach (Match m in Regex.Matches(el.innerHTML.Replace("\n", ""),
                                @"class *= *""rating"".*?>(?<beomsang>.*?)</"))
                            {
                                m_cpObj.Rating = m.Groups["beomsang"].Value.Trim();
                                break;
                            }

                            foreach (Match m in Regex.Matches(el.innerHTML.Replace("\n", ""),
                                @"class *= *""ad-badge-text"".*?>(?<beomsang>.*?)</"))
                            {
                                if (m.Groups["beomsang"].Value.Trim() == "광고"
                                    || m.Groups["beomsang"].Value.Trim() == "AD")
                                    m_cpObj.IsAds = true;
                                else
                                    m_cpObj.IsAds = false;
                                break;
                            }

                            m_cpObj.PartnersId = txtMainId.Text;
                            m_cpObj.SubId = txtSubId.Text;
                            m_cpObj.TraceId = traceId;
                            m_cpObj.RowId = rowId;
                            m_cpObj.RowNum = rowNum;
                            m_cpObj.Wb = new WebBrowser();
                            m_cpObj.SetObj();

                            if ((m_cpObj.IsAds && Properties.Settings.Default.OptIncludeAds == true)
                                || !m_cpObj.IsAds)
                            {
                                m_cpObjs.Add(m_cpObj);
                                ++rowNum;
                            }

                            ++rowId;
                        }
                    }

                    if (true)
                    {
                        Task task = DoNavigationSubAsync();
                        task.ContinueWith((tt) =>
                        {
                            btnExe.IsEnabled = true;
                            SetLog(string.Format("[{0}] {1}", NOTE, "★★★★★완료하였습니다."));
                            SetLog("DoNavigationSubAsync done.");
                        }, TaskScheduler.FromCurrentSynchronizationContext());
                    }
                    else
                    {
                        NavigateSub();
                    }

                    foreach (CpObj fObj in m_cpObjs)
                    {
                    }
                    break;
                case ActionType.P:
                    bool isPwdExist = false;
                    int loginClicked = 0;
                    foreach (mshtml.IHTMLElement el in ((mshtml.HTMLDocument)webBrowser.Document).getElementsByTagName("input"))
                    {
                        if (el.getAttribute("className") == "product-row")
                        {
                            if (el.innerHTML.Contains("Send Invitations"))
                            {

                            }
                        }

                        if (el.id == "password" && el.getAttribute("className") == "ant-input")
                        {
                            isPwdExist = true;
                        }

                        if (isPwdExist == true && loginClicked == 0)
                        {
                            foreach (mshtml.IHTMLElement el2 in ((mshtml.HTMLDocument)webBrowser.Document).getElementsByTagName("button"))
                            {
                                if (el2.getAttribute("className") == "ant-btn ant-btn-primary ant-btn-lg")
                                {
                                    loginClicked++;

                                    SetLog(el2.getAttribute("className"));

                                    break;
                                }
                            }
                        }

                        SetLog("loginClicked " + loginClicked.ToString());


                        break;
                    }

                    break;
                default:
                    throw new Exception("Do : undefined");
            }
        }

        private void btnExe_Click(object sender, RoutedEventArgs e)
        {
            DoAction();
        }







        private void txtProdCnt_KeyDown(object sender, KeyEventArgs e)
        {
        }



        private void ThreadStrt(object _obj)
        {
            CpObj obj = (CpObj)_obj;
            string subReq = "https://www.coupang.com/vp/products/" + obj.ProductId + "?itemId=" + obj.ItemId + "&vendorItemId=" + obj.VendorItemId;
        }

        private void dg_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
        }



        private void txtInput_KeyUp(object sender, KeyEventArgs e)
        {
            Properties.Settings.Default.ProdNm = ((TextBox)sender).Text;
            Properties.Settings.Default.Save();

            SetLog(string.Format("SAVE : {0} = {1}", "상품", Properties.Settings.Default.ProdNm));
        }


        private void NavigateSub()
        {
        }



        async Task DoNavigationSubAsync()
        {
            try
            {
                TaskCompletionSource<bool> tcsNavigated = null;
                TaskCompletionSource<bool> tcsLdCmpltd = null;
                LoadCompletedEventHandler loadCompHandler = null;
                EventHandler subTimerHandler = null;
                DispatcherTimer subTimer = new DispatcherTimer();
                subTimer.Interval = new TimeSpan(0, 0, 1);
                m_subRowNum = 0;
                SetLog(string.Format("[{0}] {1}", NOTE, "명세를 시작합니다."));

                CoreBeomSang.SuppressScriptErrors(webBrowser);

                loadCompHandler = (s, e) =>
                {
                    if (tcsLdCmpltd.Task.IsCompleted)
                        return;

                    bool isScriptLoaded = false;
                    string tmp = string.Empty;
                    string productId = string.Empty;
                    string itemId = string.Empty;
                    string vendorItemId = string.Empty;
                    Match match = null;

                    this.webBrowser.LoadCompleted -= loadCompHandler;

                    SetLog("DoNavigationSubAsync : LoadCompleted -= handler , " + e.Uri.ToString());

                    match = Regex.Match(e.Uri.ToString(), c_patternUri);
                    productId = match.Groups["pi"].ToString();
                    itemId = match.Groups["ii"].ToString();
                    vendorItemId = match.Groups["vi"].ToString();
                    subTimerHandler =
                    delegate
                    {
                        SetLog("DoNavigationSubAsync : Begin Tick Delegate");

                        foreach (mshtml.IHTMLElement el in ((mshtml.HTMLDocument)webBrowser.Document).getElementsByTagName("li"))
                        {
                            if (el.getAttribute("className") == null || el.getAttribute("className") == string.Empty)
                                continue;

                            isScriptLoaded = false;

                            if (Regex.IsMatch(el.getAttribute("className"), "^product-detail$"))
                            {
                                if (!string.IsNullOrEmpty(el.innerHTML))
                                    isScriptLoaded = true;
                            }

                            if (isScriptLoaded)
                                break;
                        }

                        if (isScriptLoaded)
                        {
                            subTimer.Tick -= subTimerHandler;
                            subTimer.Stop();

                            SetLog("DoNavigationSubAsync : -Tick , Timer Stop");

                            foreach (mshtml.IHTMLElement el in ((mshtml.HTMLDocument)webBrowser.Document).getElementsByTagName("li"))
                            {
                                if (el.getAttribute("className") == null || el.getAttribute("className") == string.Empty)
                                    continue;

                                if (Regex.IsMatch(el.getAttribute("className"), "^product-detail$"))
                                {
                                    if (!string.IsNullOrEmpty(el.innerHTML))
                                    {

                                        foreach (Match m in Regex.Matches(el.innerHTML.Replace("\n", ""),
                                                @"(?<beomsang><table class=""prod-delivery-return-policy-table essential-info-table"">.*?</table>)"))
                                        {
                                            tmp = m.Groups["beomsang"].Value.Trim();

                                            string test = string.Empty;
                                            List<string> a = new List<string>();
                                            foreach (Match m2 in Regex.Matches(tmp, "<(th|td).*?>(?<beomsang>.*?)</(th|td)>"))
                                            {
                                                a.Add(m2.Groups["beomsang"].Value);
                                                test += m2.Groups["beomsang"].Value + Environment.NewLine;
                                            }

                                            tmp = Regex.Replace(tmp, "<table.*?>", CoupangPartnersBeomSang.g_regex_infoTable);
                                            tmp = Regex.Replace(tmp, "<th.*?>", CoupangPartnersBeomSang.g_regex_infoTableTh);
                                            tmp = Regex.Replace(tmp, "<td.*?>", CoupangPartnersBeomSang.g_regex_infoTableTd);
                                            tmp = Regex.Replace(tmp, "[0-9]{2,3}-?[0-9]{3,4}-?[0-9]{4}", "상품상세 참조");
                                            m_cpObjs.GetAndSetFieldCp("SubInfoTable", tmp, productId, itemId, vendorItemId);                                           
                                            break;
                                        }



                                    }
                                }
                            }

                            ++m_subRowNum;
                            if (m_subRowNum < m_cpObjs.Count)
                            {                                
                                SetLog(string.Format("[{0}] {1}", NOTE, (m_subRowNum + 1) + "번 째 명세 진입점입니다."));
                                string subUri = "https://www.coupang.com/vp/products/"
                                            + m_cpObjs[m_subRowNum].ProductId + "?itemId="
                                            + m_cpObjs[m_subRowNum].ItemId + "&vendorItemId="
                                            + m_cpObjs[m_subRowNum].VendorItemId;
                                this.webBrowser.LoadCompleted += loadCompHandler;
                                this.webBrowser.Navigate(subUri);

                                SetLog("DoNavigationSubAsync : + Handler , Navigate");

                            }
                            else
                            {
                                SetLog(string.Format("[{0}] {1}", NOTE, "완료하였습니다."));
                                this.webBrowser.LoadCompleted -= loadCompHandler;                                
                                subTimer.Tick -= subTimerHandler;
                                subTimer.Stop();

                                SetLog("DoNavigationSubAsync : - Handler , -Tick , Timer Stop");

                                btnExe.IsEnabled = !btnExe.IsEnabled;

                                OAuthBeomSang.BLOGGER_CONTENT = CoupangPartnersBeomSang.GetBlogContent(m_cpObjs,
                                        (CoupangPartnersBeomSang.STYLE)((FrameworkElement)cmbStyle.SelectedItem).Tag);

                                Random random = null;
                                int ranInt = 0;
                                random = new Random();
                                
                                ranInt = random.Next(0, CoupangPartnersBeomSang.g_blogContentPrefaceTemplates.Length);
                                OAuthBeomSang.BLOGGER_CONTENT_PREFACE = CoupangPartnersBeomSang.g_blogContentPrefaceTemplates[ranInt];

                                SetLog("[테스트 머리말]" + OAuthBeomSang.BLOGGER_CONTENT_PREFACE);

                                int fileSeq = 1;
                                string targetDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
                                string fullPath = targetDirectory + "\\" + txtProdNm.Text + ".html";

                                if (File.Exists(fullPath))
                                {
                                    while (true)
                                    {
                                        ++fileSeq;
                                        fullPath = targetDirectory + "\\" + txtProdNm.Text + "_" + fileSeq + ".html";
                                        if (!File.Exists(fullPath))
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            continue;
                                        }
                                    }

                                    using (StreamWriter sw = File.CreateText(fullPath))
                                    {
                                        sw.Write(OAuthBeomSang.BLOGGER_CONTENT);
                                    }
                                }
                                else
                                {
                                    using (StreamWriter sw = File.CreateText(fullPath))
                                    {
                                        sw.Write(OAuthBeomSang.BLOGGER_CONTENT);
                                    }
                                }

                                if (OAuthBeomSang.g_access_token != string.Empty
                                    && chkBloggerInsertPost.IsChecked == true ? true : false)
                                {
                                    SetLog("블로거 게시를 시도합니다.");
                                    OAuthBeomSang.BLOGGER_PATH_CONTENT = fullPath;
                                    OAuthBeomSang.BLOGGER_TITLE = txtBloggerTitle.Text.Replace("^prod$", txtProdNm.Text).Replace("^cnt$", txtProdCnt.Text);
                                    OAuthBeomSang.DoInsertBloggerPost();
                                    SetLog("블로거 게시를 완료합니다.");
                                }

                                DataTable dataTable = new DataTable();
                                dataTable.Columns.Add("번호", typeof(string));
                                dataTable.Columns.Add("품명", typeof(string));
                                foreach (CpObj fObj in m_cpObjs)
                                {
                                    dataTable.Rows.Add(new string[] { (fObj.RowNum + 1).ToString(), fObj.Name });
                                }
                                dataGrid.ItemsSource = dataTable.DefaultView;

                                tcsLdCmpltd.SetResult(true);
                            }
                        }
                    };

                    subTimer.Tick += subTimerHandler;
                    subTimer.Start();


                    SetLog("DoNavigationSubAsync : +Tick , Timer Start");


                };

                this.webBrowser.LoadCompleted += loadCompHandler;
                
                foreach (var cpObj in m_cpObjs)
                {
                    tcsNavigated = new TaskCompletionSource<bool>();
                    tcsLdCmpltd = new TaskCompletionSource<bool>();

                    string subUri = "https://www.coupang.com/vp/products/"
                                + cpObj.ProductId + "?itemId="
                                + cpObj.ItemId + "&vendorItemId="
                                + cpObj.VendorItemId;

                    this.webBrowser.Navigate(subUri);


                    SetLog("DoNavigationSubAsync : Navigate " + subUri);

                    bool bolTsk = await tcsLdCmpltd.Task;

                    SetLog("DoNavigationSubAsync : Task Completion");
                }                
            }
            catch (Exception ex)
            {
                SetLog(ex.Message);
            }
        }

        private static void CatchUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (e.IsTerminating == true)
            {
                string logDir = $"{ AppDomain.CurrentDomain.BaseDirectory}\\{Assembly.GetEntryAssembly()}.log";
                string logMsg = $"\n[{ DateTime.Now.ToString()}] {e.ExceptionObject.ToString()} ";

                FileMode mode = FileMode.CreateNew;
                if (File.Exists(logDir) == true)
                {
                    FileInfo leftFileInfo = new FileInfo(logDir);

                    if (leftFileInfo.Length < 1929891)
                    {
                        mode = FileMode.Append;
                    }
                    else
                    {
                        mode = FileMode.Create;
                    }
                }

                using (FileStream fs = new FileStream(logDir, mode))
                {
                    using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8))
                    {
                        sw.WriteLine(logMsg);
                    }
                }
            }
        }

        private void SetLog(string _log, bool _setMsg = false)
        {
            try
            {
                if (txtLog.Text == string.Empty)
                {
                    txtLog.Text = "[" + DateTime.Now + "] " + _log;
                }
                else
                {
                    txtLog.Text += Environment.NewLine + "[" + DateTime.Now + "] " + _log;
                }
                txtLog.ScrollToEnd();                 
            }
            catch (Exception)
            {
            }
        }



        private void Txt_TextChanged(object sender, TextChangedEventArgs e)
        {
            try
            {
                if (!m_isInit)
                    return;

                if (sender == txtMainId)
                {
                    ((TextBox)sender).Text = ((TextBox)sender).Text.Trim();
                    CoupangPartnersBeomSang.g_partnersId = ((TextBox)sender).Text;
                    SetLog($"파트너스 아이디 = {CoupangPartnersBeomSang.g_partnersId}");
                }
                else if (sender == txtSubId)
                {
                    ((TextBox)sender).Text = ((TextBox)sender).Text.Trim();
                    CoupangPartnersBeomSang.g_subId = ((TextBox)sender).Text;
                    SetLog($"채널 아이디 = {CoupangPartnersBeomSang.g_subId}");
                }
                else if (sender == txtBloggerId)
                {
                    Properties.Settings.Default.OAuthBloggerId = ((TextBox)sender).Text.Trim();
                    Properties.Settings.Default.Save();

                    SetLog(string.Format("SAVE : {0} = {1}", "블로거 아이디", Properties.Settings.Default.OAuthBloggerId));
                }
                else if (sender == txtBloggerTitle)
                {
                    Properties.Settings.Default.BloggerTitle = ((TextBox)sender).Text.Trim();
                    Properties.Settings.Default.Save();
                    SetLog($"SAVE : 블로거 제목 = {Properties.Settings.Default.BloggerTitle}");
                }
                else
                {
                    SetLog($"Not Registered Command");
                }
            }
            catch (Exception ex)
            {
                SetLog($"Ex : {ex.ToString()}");
            }
        }

        private void Btn_Click(object sender, RoutedEventArgs e)
        {
            if (sender == btnSaveId)
            {
                Properties.Settings.Default.MainId = txtMainId.Text.Trim();
                Properties.Settings.Default.SubId = txtSubId.Text.Trim();
                Properties.Settings.Default.Save();

                SetLog(string.Format("SAVE : {0} = {1}", "파트너스 아이디", Properties.Settings.Default.MainId));
                SetLog(string.Format("SAVE : {0} = {1}", "채널 아이디", Properties.Settings.Default.SubId));

                txtMainId.IsReadOnly = true;
                txtSubId.IsReadOnly = true;

                MessageBox.Show("저장했습니다."
                    + Environment.NewLine
                    + "(우측 상단 공지사항을 확인해 주세요)"
                    + Environment.NewLine
                    + Environment.NewLine
                    + "파트너스 아이디 : "
                    + Properties.Settings.Default.MainId
                    + Environment.NewLine
                    + "채널 아이디 : "
                    + Properties.Settings.Default.SubId,
                    g_caption, MessageBoxButton.OK, MessageBoxImage.Information);
            }
            else if (sender == btnActivate)
            {
                txtMainId.IsReadOnly = !txtMainId.IsReadOnly;
                txtSubId.IsReadOnly = !txtSubId.IsReadOnly;

                if (txtMainId.IsReadOnly)
                    SetLog("아이디를 수정하지 못하도록 비활성화 합니다.");
                else
                    SetLog("아이디를 수정할 수 있도록 활성화 합니다.");
            }
            else if (sender == btnDoOAuth)
            {
                OAuthBeomSang.InitOAuthVar();
                OAuthBeomSang.g_lblOAuthToken = lblOAuthToken;
                OAuthBeomSang.ACCESSKEY = pwdAccessKey.Password;
                OAuthBeomSang.SECRETKEY = pwdSecretKey.Password;
                OAuthBeomSang.BLOGGER_ID = txtBloggerId.Text;
                OAuthBeomSang.DoSendAuthRequest(this);
            }
            else if (sender == btnSaveOAuth)
            {
                SaveOAuthBeomSang saveOAuthBeomSang = new SaveOAuthBeomSang();
                saveOAuthBeomSang.Topmost = true;
                saveOAuthBeomSang.ShowDialog();
                pwdAccessKey.Password = Environment.GetEnvironmentVariable(SaveOAuthBeomSang.OAuthACC, EnvironmentVariableTarget.User);
                pwdSecretKey.Password = Environment.GetEnvironmentVariable(SaveOAuthBeomSang.OAuthSEC, EnvironmentVariableTarget.User);
            }
            else if (sender == btnOption)
            {
                OptionBeomSang option = new OptionBeomSang();
                option.Topmost = true;
                option.ShowDialog();
            }
            else
            {
                SetLog("Not Registered Command");
            }
        }

        private void Txt_KeyUp(object sender, KeyEventArgs e)
        {
            if (sender == txtProdCnt)
            {
                if (Regex.IsMatch(((TextBox)sender).Text, "^[0-9]+$"))
                {
                    Properties.Settings.Default.ProdCnt = Convert.ToInt32(((TextBox)sender).Text);
                    Properties.Settings.Default.Save();

                    SetLog(string.Format("SAVE : {0} = {1}", "상품개수", Properties.Settings.Default.ProdCnt));
                }
            }
            else if (sender == txtProdNm)
            {
                Properties.Settings.Default.ProdNm = ((TextBox)sender).Text;
                Properties.Settings.Default.Save();

                SetLog(string.Format("SAVE : {0} = {1}", "상품명", Properties.Settings.Default.ProdNm));
            }
            else if (sender == txtBloggerId)
            {
                Properties.Settings.Default.OAuthBloggerId = ((TextBox)sender).Text;
                Properties.Settings.Default.Save();
                SetLog(string.Format("SAVE : {0} = {1}", "블로거 아이디", Properties.Settings.Default.OAuthBloggerId));
            }
            else
            {
                SetLog("Not Registered Command");
            }
        }

        private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
        {
            Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
            e.Handled = true;
        }
    }
}
댓글 쓰기
가져가실 때, 출처 표시 부탁드려요! 감사합니다. 💗