개발팁2022. 10. 28. 15:26

LINE 메신저의 그룹에서 그룹을 추가한다.

 

 

 

그룹을 만들때는 알림을 받아야 하기 때문에,

 

 

LINE Notify 를 선택해줘야 한다.

 

LINE Notify 가 친구에 안나온다면, 친구추가를 먼저 하고 진행해야 한다.

 

 

 

 

 

 

이제 웹브라우저로 아래 링크에 들어가서,

 

API 토큰을 생성해야 한다.

 

 

https://notify-bot.line.me/

 

 

 

로그인후에, 상단 오른쪽의 이름을 클릭하고, My page 로 들어가서,

 

Generate token 을 클릭한다.

 

 

 

 

 

 

아까 만들었던 그룹명을 선택한다.

 

Generate token 을 누르면, token 이 생성된다.

 

 

 

API 문서는 이 사이트에서 볼 수 있다.

 

https://notify-bot.line.me/doc/en/

 

 

API 메서드가 여러개가 있는데, 이중에 메세지 전송하는 API 만 보면 아래와 같다.

 

 

 

간단하게

POST 로 https://notify-api.line.me/api/notify 를 호출하면 되고,
인증은 Bearer 에 위에서 생상한 token 을 넣어주면 되고,
메세지는 form data 로
message=test_message

 

이렇게 호출해주면 메세지가 전송이 된다.

 

curl -X POST -H "Authorization: Bearer 토큰을이곳에입력하세요" -F "message=foobar" https://notify-api.line.me/api/notify

 

command 창에서 위와같이 실행해보면, 메세지가 전송되는걸 볼 수 있다.

 

 

 

Posted by 헝개
개발팁2022. 7. 27. 15:56

타자게임이란 키보드 타자 연습을 위한 게임으로,

한라인의 문장을 제시해주고, 똑같이 입력하면 성공, 그렇지 못하면 실패로 체크하고,

성공하면, 분당 타수를 알려주는, 간단한 게임을 말한다.

 

개인적으로 혼자서 연습도 가능하지만, 이를 채팅방에 적용하면, 다수의 사람과 경쟁을 통해 성취감을 얻을 수도 있다.

 

타자게임을 만들때 필요한 것은,

 

1. 한글 한줄 문장 데이터이다.

2. 한글을 초/중/종 성으로 쪼개는 작업이 필요하다.

3. 분당 타수를 계산하는 로직을 적용하면 된다.

 

 

 

 

 

프로그램은 시작 버튼을 누르면, 제시어를 보여주고, 똑같이 입력을 하면, 결과를 보여준다.

 

 

 

1. 한글 한줄 문장 데이터이다.

 

문장 데이터는 많을수록 좋다.

 

 

한컴 타자연습 사이트 - 짧은글 연습에서 문장을 가져왔다.

 


2692개의 문장이 제공되고 있다.

 

해당 문장은 DB 에 입력해서 꺼내와도 되고, 구글시트에 넣어놓고 꺼내와도 상관없다.

 

예제는 구글시트에 한줄 문장을 관리하기 때문에, 구글API 가 필요하다.

 

nuget 패키지 관리자에서, Google.Apis.Sheets.v4 를 설치한다.

 

 

 

public static List<string> GetTypingSentenceList()
{
List<string> result;

string _apikey = "***********************";
string _sheetid = "***********************";

result = new List<string>();

try
{
// API 서비스 생성
var service = new SheetsService(new BaseClientService.Initializer()
{
ApplicationName = "GoogleDocs .net API",
ApiKey = _apikey
});

var request = service.Spreadsheets.Values.Get(_sheetid, "타자!A1:A");

ValueRange response = request.Execute();
IList<IList<Object>> values = response.Values;
if (values != null && values.Count > 0)
{
foreach (var row in values)
{
if (row[0] != null && row[0].ToString() != "")
result.Add(row[0].ToString());
}
}

}
catch (Exception e1)
{
MessageBox.Show(e1.Message);
}

return result;
}

 

전체 한줄문장 목록은 이렇게 google sheet 에서 읽어오면 된다.

 

이렇게 읽어온 데이터는 캐시에 저장해두었다가, 요청시마다 꺼내서, 랜덤하게 한 라인을 select 하면 된다.

 

 

시작버튼 클릭시 처리 로직

 

Random rand = new Random();

// 문장 뽑기
List<string> sentence_list = GoogleDocsRepository.GetTypingSentenceList();
int rndNum = rand.Next(0, sentence_list.Count);
string sentence = sentence_list[rndNum].Trim();

this.txtKeyword.Text = sentence;

// 타자수 계산 : 1. 글자를 초/중/종 성으로 쪼갠다.
string[] split_words = HangulWorker.GetDisassemble(sentence, true);
// 타자수 계산 : 2. 글자수를 계산한다.
this._typingCount = HangulWorker.GetTypingSize(split_words);

this._isStart = true;
this._isKeyKirstPress = false;
this.txtInput.Focus();

 

이제 TextBox 에 첫 글자가 입력되는 순간부터 시간을 재고, 단어 입력이 끝나면, 결과를 발표하면 된다.

 

 

2. 한글을 초/중/종 성으로 쪼개는 작업이 필요하다.

 

제시어에서 글자를 모두 초/중/종 성으로 쪼개서, 타자수를 계산해야한다.

한글이라고 모두 2번의 타자가 아니기 때문이다.

 

안녕하세요 를 초/중/종 성으로 쪼개면

ㅇ ㅏ ㄴ ㄴ ㅕ ㅇ ㅎ ㅏ ㅅ ㅔ ㅇ ㅇ

12글자가 되는 것이다.

 

이중에 된발음 ㄲ, ㄸ 이런 글자는 shift 키를 누르고 글짜를 누르기 때문에, 두번의 타자로 계산할지 정의가 필요하다.

예제에서는 한번의 타자로 계산했다.

 

또한 종성에서는

갉 갏 값  등으로 ㄺ ㅀ ㅄ 등의 글자들이 있는데, 이 종성 글자들은 타자수 두번으로 계산해야 한다.

 

시작버튼 클릭시 처리 로직에서 사용한 HangulWorker 의 기본 코드

 

// 유니코드표에서의 기본 위치
private const int hangulStartingPoint = 0xAC00;  // hangulStartingPoint : 유니코드에서 '가'의 위치

// 자소 목록
private static List<string> chosungHangulWords = (
new string[] { "ㄱ", "ㄲ", "ㄴ", "ㄷ", "ㄸ", "ㄹ", "ㅁ", "ㅂ", "ㅃ", "ㅅ"
 , "ㅆ", "ㅇ", "ㅈ", "ㅉ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ" }
).ToList<string>();    // 초성 19개 요소
private static List<string> jungsungHangulWords = (
   new string[] { "ㅏ", "ㅐ", "ㅑ", "ㅒ", "ㅓ", "ㅔ", "ㅕ", "ㅖ", "ㅗ", "ㅘ"
 , "ㅙ", "ㅚ", "ㅛ", "ㅜ", "ㅝ", "ㅞ", "ㅟ", "ㅠ", "ㅡ", "ㅢ"
 , "ㅣ" }
   ).ToList<string>();    // 중성 21개 요소
private static List<string> jongsungHangulWords = (
   new string[] { string.Empty, "ㄱ", "ㄲ", "ㄳ", "ㄴ", "ㄵ", "ㄶ", "ㄷ", "ㄹ", "ㄺ"
 , "ㄻ", "ㄼ", "ㄽ", "ㄾ", "ㄿ", "ㅀ", "ㅁ", "ㅂ", "ㅄ", "ㅅ"
 , "ㅆ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ" }
   ).ToList<string>();    // 종성 28개 요소

 

아래는, 한글문장을 초/중/종 성의 글자별로 쪼개는 GetDisassemble 함수 본문이다.

 

public static string[] GetDisassemble(string str, bool bSkipBase)
{
if (str == "") return null;

List<string> list = new List<string>();
int uniValue;   // 유니코드 상의 글자 위치
int iTemp;
string s;

for (int n = 0; n < str.Length; n++)
{
uniValue = 0;
s = str.Substring(n, 1);
byte[] bytes = Encoding.Unicode.GetBytes(s);
// 빅앤디안 방식이지만 아래 계산 편이를 위해 리틀앤디안으로 변환


// 유니코드 상의 글자 위치 구하기
for (int b = 0; b < bytes.Length; b++)
{
uniValue += (int)(bytes[b] * Math.Pow(256.0, b));
}

if (uniValue < hangulStartingPoint) { list.Add(s); continue; }

// 초성
list.Add(chosungHangulWords[(uniValue - hangulStartingPoint) / jongsungMultiply]);


// 중성
list.Add(jungsungHangulWords[(uniValue - hangulStartingPoint) % jongsungMultiply / jongsungHangulWords.Count]);

// 종성
iTemp = (uniValue - hangulStartingPoint) % jongsungHangulWords.Count;
if (bSkipBase && iTemp == 0) continue;
list.Add(jongsungHangulWords[iTemp]);
}

return list.ToArray();
}

 

GetDisassemble  에서 쪼개진 글자 배열에서 타자수를 계산하는 GetTypingSize 함수 본문이다.

 

public static int GetTypingSize(string[] str_list)
{
int addCount = str_list.Select(d => d == "ㅘ" || d == "ㅙ" || d == "ㅚ" || d == "ㅝ" || d == "ㅞ" || d == "ㅟ" || d == "ㅢ" || d == "ㄳ" || d == "ㄵ" || d == "ㄶ" || d == "ㄺ" || d == "ㄻ" || d == "ㄼ" || d == "ㄽ" || d == "ㄾ" || d == "ㄾ" || d == "ㅀ" || d == "ㅄ").Count(d => d);

return str_list.Length + addCount;
}

 

초/중/종 성을 모두 1글자로 취급하며,

ㅟ ㅚ ㄻ ㄼ  등의 글자는 2글자로 취급하도록 계산하였다.

 

 

3. 분당 타수를 계산하는 로직을 적용하면 된다.

 

이제, 입력글자가 모두 일치 할경우, 분당 타수를 계산해서 알려주면 끝이다.

 

입력 TextBox 의 KeyDown 이벤트를 아래와 같이 정의한다.

 

private void txtInput_KeyDown(object sender, KeyEventArgs e)
{
if (this._isStart == true)
{
if (this._isKeyKirstPress == false)
{
this._isKeyKirstPress = true;
this._startDateTime = System.DateTime.Now;
}

if (this.txtKeyword.Text == this.txtInput.Text)
{
this._isStart = false;
this.checkDone();
}
}
}

 

이제 분당 타수를 표시해주면 끝이난다.

 

private void checkDone()
{
TimeSpan elapsed = DateTime.Now - this._startDateTime;

double typingMM = Math.Round(_typingCount * (60000.0 / elapsed.TotalMilliseconds));

this.txtResult.Text = $"{typingMM:N0} 타/분";
}

 

 

코드를 모두 적용하고, 프로그램을 실행하면, 아래와 같은 결과가 나오게 된다.

 

 

 

 

이것은 혼자하는 타자게임이지만, 채팅방에 이 로직을 적용하면, 여러명이서 경쟁하면서 게임을 즐길 수 있다.

 

아래는, 실제 네이버웍스메신저 단톡방에 메세지Bot 으로 구현한 타자 게임이다.

 

 

 

 

직접 만든 채팅방에 적용할 수 있다면, 좀더 편리한 UI 로 구현할 수 있을 것이다.

 

 

Posted by 헝개
개발팁2022. 4. 7. 11:53

PC에 이더넷 어댑터가 여러개 설치되어 있거나, Virtual Box 와 같은 Virtual Marchine 이 설치되어 있다면,

IP주소 / 맥어드레스를 구하는 다른 소스로는 엉뚱한 IP/Mac 주소를 반환하는 경우가 있다.

정확한 사용 주소를 가져오는 C# 코드는 아래와 같다.

 

 

IP주소

 

            string ipAddress = "";

            using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
            {
                socket.Connect("8.8.8.8", 65530);
                IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
                ipAddress = endPoint.Address.ToString();
            }

 

 

맥어드레스

 

            string macAddress = "";

            ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
            using (ManagementObjectCollection moc = mc.GetInstances())
            {
                foreach (ManagementObject mo in moc)
                {
                    if (mo["MacAddress"] != null)
                    {
                        if ((bool)mo["IPEnabled"] == true)
                        {
                            macAddress = mo["MacAddress"].ToString();
                            break;
                        }

                        mo.Dispose();
                    }
                }

            }
Posted by 헝개
개발팁2022. 3. 29. 14:04

mysql 또는 mariadb 에는 slow query 를 탐지해서 log 파일에 저장해주는 기능이 있다.

DB 튜닝을 위해, 속도가 느린 쿼리를 탐지해서 알려주는 기능은 참 유용한 기능이다.

 

현재, slow query 탐지 기능이 동작중인지 확인하려면, 쿼리창에 아래와 같이 실행해주면 알 수 있다.

 

show variables like 'slow_query_%';
show variables like 'long_query_%';

 

 

slow_query_log 가 OFF 상태로 동작중이지 않다.

 

탐지 기능을 켜려면,

 

mysql 이 설치된 폴더의 data 폴더아래 my.ini 설정 파일을 수정해야 한다.

 

MariaDB 10.5 버전이 설치되어 있다면, 아마도 아래와 같은 경로일 것이다.

 

C:\Program Files\MariaDB 10.5\data\my.ini

 

파일을 편집기로 열어서 아래와 같은 내용을 추가해준다.

 

slow_query_log = 1
slow_query_log_file = C:/slowlog/mysql-slow.log
long_query_time = 5

 

slow_query_log = 1

SLOW QUERY 탐지 기능을 사용한다는 의미이다.

 

slow_query_log_file = C:/slowlog/mysql-slow.log

슬로우 쿼리가 저장되는 경로와 파일명인데, 경로 규칙에 주의 해야 한다.

\ 문자가 아니라 / 문자로 폴더가 구분된다.

 

long_query_time = 5

초단위로 입력하며, 5초 이상의 쿼리를 탐지하겠다는 내용이다.

 

 

mysql 서비스를 재시작해야, 변경된 내용이 적용된다.

 

# mysql
net stop MySQL & net start MySQL
# mariadb
net stop mariadb & net start mariadb

 

윈도우의 서비스 항목에서 재시작하거나, command 창에서 재시작 해도 된다.

 

 

 

이제 변경된 설정을 확인해보면 된다.

 

show variables like 'slow_query_%';
show variables like 'long_query_%';

 

 

설정한 경로에 log 파일도 생성되었다.

 

 

슬로우쿼리 탐지가 잘 되는지 테스트 쿼리를 날려서 확인해 볼 수 있다.

 

SELECT SLEEP(5), 'slow query test.';

 

 

슬로우쿼리가 탐지될때마다, 로그 파일의 뒤에 계속 추가가 된다.

 

여기까지만 해도, 주기적으로 로그파일을 열어보고, 확인하면 되지만, 실시간으로 알림을 받을 수 있는 방법이 있다.

 

C# 의 FileSystemWatcher 를 이용하면, 파일의 내용이 변경되는걸 감지해서, slack 이나 naverworks 등의 메신저로 단체 채팅방에 알림메세지를 발송 할 수 있다.

 

 

FileSystemWatcher watcher = new FileSystemWatcher();

watcher.Filter = "mysql-slow.log";
watcher.Path = "C:\\slowlog\\";
watcher.IncludeSubdirectories = false;


watcher.NotifyFilter = NotifyFilters.DirectoryName |
   NotifyFilters.LastWrite |
   NotifyFilters.FileName |
   NotifyFilters.Size;

watcher.Changed += Watcher_Changed;
watcher.EnableRaisingEvents = true;

 

그리고, 파일에 추가되는 내용만 알림을 해야 하기 때문데, 파일 스트림의 position 을 전역변수로 기록해두자.

 

FileInfo fileinfo = new FileInfo(this.logFullPath);

if (this.streamPosition > fileinfo.Length)
{
       this.streamPosition = fileinfo.Length;
}            

 

Watcher_Changed 이벤트에서는 파일이 변경되었으니, append 된 내용만 알림을 보내면 된다.

 

using (FileStream stream = fileinfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
  stream.Position = this.streamPosition;

  using (StreamReader reader = new StreamReader(stream))
  {
    string mesageContent = reader.ReadToEnd()

    // MessageSend(messageContent);
  }
}

 

이렇게 해서 테스트를 해보면, 실시간 알림이 안오고, 한참 있다가 알림이 오게 되는걸 볼 수 있다.

 

이유는, 윈도우 시스템 (NTFS) 이 파일에 쓰기 버퍼를 사용하기 때문이다.

즉, 일정한 시간이 지나야 버퍼를 실제 물리적인 파일에 저장하기 때문이다.

 

윈도우 시스템이 실시간으로 파일을 변경하도록 하기 위해서는

로그파일을 Open / Close 를 주기적으로 해주면 된다.

 

 

try
{
  // NTFS 의 파일 캐싱으로 인해 로그파일이 변화를 watcher 가 즉시 탐지하지 못한다.
  // 파일 변화를 즉시 감지하기 위해 open 모드로 읽고 닫기를 한다.
  File.Open(this.logFullPath, FileMode.Open).Close();
}
catch (Exception)
{
}

 

try catch 를 쓰는 이유는, 로그 파일을 mysql 이 잡고 있기 때문에, Exception 이 발생하기 때문이다.

하지만, 이렇게 주기적으로 해당 파일을 건들어 주면, 윈도우 시스템이 버퍼를 파일로 저장하는 효과를 얻을 수 있어,

실시간 파일 감시가 가능해지기 때문이다.

 

이렇게 해서, 프로그램을 돌려놓고, slow query 를 발생해보면, 알림이 오는것을 확인할 수 있다.

 

 

네이버웍스 메신저르 알림을 보낸 샘플이다.

 

주의할점은 슬로우 쿼리는 트랜잭션 단위의 쿼리가 아니라, 쿼리문장 단위로 탐지를 한다는 점이다.

 

 

Posted by 헝개
개발팁2022. 3. 22. 18:46

웹API 및 Rest API 에서 swagger 는 강력한 테스트 도구이자, 문서화 도구이며,

API 를 사용하는 개발자와의 인터페이스 도구이다.

 

 

Swagger 설치 및 환경 설정

 

 

 

NuGet 패키지관리자에서 swashbuckle 을 검색해서 최신버전을 설치한다.

 

 

 

프로젝트 설정에서

웹 > 시작 작업 > 특정 페이지

 

swagger/ui/index

 

를 입력한다.

 

 

이제 F5 를 눌러 디버그를 해보면, 바로 swagger 페이지가 호출된다.

 

 

REST API 의 기본 샘플인 Values 컨트롤러에 대한 API 테스트 화면이다.

 

API 테스트 도구로서는 훌륭하지만, 문서화로써는 부족하다.

 

 

 

프로젝트 설정 > 빌드 > 출력

XML 문서 파일 체크를 한다.

 

 

 

 

 

 

App_Start > SwaggerConfig.cs 파일을 편집한다.

 

EnableSwagger 아래에 아래 라인을 추가한다.

 

c.IncludeXmlComments(string.Format(@"{0}\bin\WebApiTest.xml",
       System.AppDomain.CurrentDomain.BaseDirectory));

 

그리고, 테스트용 Api 컨트롤러 TodoController.cs 를 생성한다.

 

    public class TodoController : ApiController
    {
        // GET api/Todo
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/Todo/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/Todo
        /// <summary>
        /// Test 데이터 업로드 (dynamic by json)
        /// </summary>
        /// <remarks>
        /// {<br />
        ///     UserID: "round1",<br />
        ///     UserName: "홍길동",<br />
        ///     WorkTitle: "데이터 백업"<br />
        /// }<br />
        /// </remarks>
        /// <param name="data">
        /// json object {<br />
        /// UserID: 유저아이디<br />
        /// UserName: 유저이름<br />
        /// WorkTitle: 작업이름<br />
        /// }<br />
        /// </param>
        /// <returns></returns>
        public string Post([FromBody] dynamic data)
        {
            return "Data Posted : " + data.UserID + "=" + data.UserName + "<br />" + data.WorkTitle;
        }


        // PUT api/Todo/5
        /// <summary>
        /// PUT 데이터
        /// </summary>
        /// <remarks>
        /// {<br />
        ///     UserID: "round1",<br />
        ///     UserName: "홍길동",<br />
        ///     WorkTitle: "데이터 백업"<br />
        /// }<br />
        /// </remarks>
        /// <param name="data">
        /// json object {<br />
        /// UserID: 유저아이디<br />
        /// UserName: 유저이름<br />
        /// WorkTitle: 작업이름<br />
        /// }<br />
        /// </param>
        public string Put(int id, [FromBody] dynamic data)
        {
            return "put : " + data.WorkTitle;
        }

        // DELETE api/Todo/5
        public void Delete(int id)
        {
        }
    }

 

샘플데이터로 ValuesController 를 복사해서 수정했다.

Post / Put 메서드에 xml 주석이 들어가 있는것을 볼 수 있다.

 

프로젝트를 빌드 하면, 이 주석이 bin/WebApiTest.xml 파일로 저장이 되고,

Swagger 에서는 의 xml 을 읽어서 화면을 만들어 주게 된다.

 

 

 

TodoController 에서 메서드에 작성한 xml 주석이 swagger 에 잘 나온다.

 

xml 주석에 작성해둔 json 샘플 양식도 복사해서 붙여 넣기 하고,

Try it out! 을 누르면, 테스트도 간편하게 된다.

 

 

여기서 한가지 더 개선을 해본다면,

 

 

매번 json 샘플을 복사해서, parametar 에 붙여넣기를 해야 하는데, 이걸 자동화 해볼 것이다.

 

 

 


// Copyright 헝그리개발자(https://bemeal2.tistory.com)
// 소스는 자유롭게 사용가능합니다. Copyright 는 삭제하지 마세요.

$(document).ready(function () {

$(".toggleOperation").on('click', function (e) {

let el_content = $(e.target).closest("li.operation").find(".content");

setTimeout(function () {
if (el_content.css("display") == "block") {

let param_text = el_content.children(".markdown").text();

let el_textarea = el_content.find("textarea.body-textarea");

el_textarea.val(param_text);
let ev = new Event('input', { bubbles: true });
ev.simulated = true;

el_textarea[0].dispatchEvent(ev);

}
}, 500);

});


});

 

js 폴더를 만들고 그 아래  swager-control.js 파일을 생성한다.

 

.js 파일의 내용은 위와 같이 넣어준다.

 

 

그리고, 속성창에서 빌드작업을 [포함리소스] 로 바꿔준다.

 

SwaggerConfig.cs 파일을 열어서, EnableSwaggerUI 아래에 아래와 같이 추가해준다.

 

                .EnableSwaggerUi(c =>
                    {
                        c.InjectJavaScript(thisAssembly, "WebApiTest.js.swagger-control.js");

 

여기서 주의 할 점은 .js 파일의 경로를 지정하는 방식이다.

 

프로젝트명.폴더명.파일명  이러한 규칙으로 작성해야 한다.

 

상식적으로는 js 폴더 아래에  swagger-control.js  파일이 있으니까

"/js/swagger-control.js"  라고 해야 할것 같지만. 그렇지 않다.

 

WebApiTest 라는 프로젝트명.js라는폴더명.swagger-control.js라는파일명

 

이렇게 해서, 

"WebApiTest.js.swagger-control.js"

 

이러한 양식으로 입력해줘야 한다.

 

 

이제 swagger 페이지를 열어보면, 파라미터가 자동으로 입력된것을 볼 수 있다.

API 테스트를 위해서 Try it out! 만 눌러주면 된다!!!

 

Posted by 헝개
개발팁2022. 3. 21. 18:55

Jenkins 는 Rest API 를 통해, Project / Job 을 조회하고,

빌드하고, 결과를 확인할 수 있다.

 

 

Rest API 를 이용하면, 빌드완료후에, 빌드 결과를 메신저로 단체방에 공유 할 수 있다.

 

 

Rest API 사용하기

 

 

 

Jenkins 에 로그인하고, 오른쪽 상단에 로그인한 ID 를 클릭한다.

 

 

 

설정 메뉴를 클릭한다.

 

 

ADD NEW TOKEN 을 클릭한다.

 

 

Default name 을 입력하고, GENERATE 를 클릭하면, Token String 이 생성된다.

 

 

이 토큰문자가 REST API 를 호출할때, 인증하는 수단이 된다.

 

형식은 위에서 입력한 이름:토큰스트링 형식이다.

 

ex)

admin:12eb2d6e1d73cfa260d9e42e4d3f080b19

 

이 값은 Basic API 호출시에는 Base64 String 으로 변환해서 호출해야 한다.

간단히 fiddler 의 text wizard 에서 변환해서 쓰면 된다.

 

 

 

base64 string ex)

YWRtaW46MTJlYjJkNmUxZDczY2ZhMjYwZDllNDJlNGQzZjA4MGIxOQ==

 

 

 

Jenkins Rest API 호출

 

Job 조회 / 빌드 조회 URL 뒤에  /api/json   또는 /api/xml 만 붙여주면된다.

(소문자로 입력해야 한다.)

 

웹브라우저에서 로그인 한 상태에서, JOB 조회 화면뒤에 api/json 을 붙여보면 된다.

 

 

 

 

 

 

웹브라우저에서는 jenkins 사이트에 로그인이 된 상태에서 호출했기 때문에, 조회가 정상적으로 이뤄진다.

curl 명령어로 command prompt 에서 실행해보자.

 

 

curl -X GET "http://url:port/job/BUILD/job/BUILD_CLIENT_FOR_Develop/api/json" -H "Content-Type: application/json"

 

오류가 날 것이다. 아래와같이 Basic Authorization 을 추가하여 호출해보자.

 

curl -X GET "http://url:port/job/BUILD/job/BUILD_CLIENT_FOR_Develop/api/json" -H "Content-Type: application/json" -H "Authorization: Basic YWRtaW46MTJlYjJkNmUxZDczY2ZhMjYwZDllNDJlNGQzZjA4MGIxOQ=="

 

 

결과가 잘 나올 것이다.

 

 

 

Jenkins 결과 확인 API

 

빌드 결과 확인 API
{jobUrl}{buildNumber}/api/json

빌드 결과 Console 확인 API
{jobUrl}{buildNumber}/consoleText

 

 

Jenkins 빌드 후 조치

 

 

 

Jenkins 의 job 설정에서 빌드 후 조치

 

Execute Windows batch command 를 통해서, 빌드완료후에, 빌드결과 알림 Console Application 을 호출할것이다.

 

jenkins_build_noti.bat

 

파일과, 그 안에서 호출하는 Application 을 만들어야 한다.

 

Application 은 Visual Studio 에서 Console Application 으로 만들면 된다.

 

 

 

jenkins_build_noti.bat

 

D:\경로\Util.NaverWorks.BuildNoti.exe "jenkins" "%JOB_URL%" "%BUILD_NUMBER%"

 

jenkins 빌드가 완료되면, 전역변수

 

%JOB_URL% 에 현재 빌드된 job 의 url 이 자동으로 입력되고,

%BUILD_NUMBER% 에는 빌드된 빌드번호가 자동으로 입력된다.

 

 

 

Console Application

 

main 함수

            if (args.Length >= 1)
            {
                using (NaverWorksNoti noti = new NaverWorksNoti())
                {
                    switch (args[0])
                    {
                        case "jenkins":
                            noti.SendJenkins(args[1], args[2]);
                            break;
                        default:
                            WriteUsage();
                            break;
                    }

                    return 0;   // always return success
                }

 

여기서 주의 할 점은 return 0 이다. 0 이 아닌 값을 리턴하면,  jenkins 는 빌드가 실패한걸로 처리하게 된다.

 

 

SendJenkins 함수

string url = $"{jobUrl}{buildNumber}/api/json";

 

using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

client.DefaultRequestHeaders.Add("Authorization", "Basic YWRtaW46MTJlYjJkNmUxZDczY2ZhMjYwZDllNDJlNGQzZjA4MGIxOQ==");

HttpResponseMessage response = client.GetAsync(url).Result;
string result = response.Content.ReadAsStringAsync().Result;

dynamic objResult = JsonConvert.DeserializeObject(result);

........

}

 

이제 objResult 라는 json 객체에서 빌드 성공/실패 여부를 판단하고, 알림 메세지를 만들어 내면 된다.

 

bool buildSuccess = objResult.result.ToString() == "SUCCESS";

 

result 값이 SUCCESS 라면 빌드성공 아니면 실패로 처리하면 된다.

 

actions 의 parameters 를 통해 job 빌드시 사용한 파라미터를 가져올 수 도 있다.

 

                    for (int i = 0; i < objResult.actions.Count; i++)
                    {
                        if (objResult.actions[i].parameters != null)
                        {
                            for (int k = 0; k < objResult.actions[i].parameters.Count; k++)
                            {
                                if (objResult.actions[i].parameters[k].value != null && objResult.actions[i].parameters[k].value.ToString() != "")
                                {
                                        
                                    sbParameter.Append($"{objResult.actions[i].parameters[k].name.ToString()} : {objResult.actions[i].parameters[k].value.ToString()}");

sbParameter.AppendLine();
                                }
                            }
                        }
                    }

 

svn 연동해서, 빌드하는 경우, changeSet 을 통해서, svn 커밋내용들을 가져올 수 있다.

 

if (objResult.changeSet.items != null)
{
for (int i = 0; i < objResult.changeSet.items.Count; i++)
{
sbMessage.AppendLine($"{objResult.changeSet.items[i].user.ToString()} : {(objResult.changeSet.items[i].date == null ? "" : Convert.ToDateTime(objResult.changeSet.items[i].date).ToLocalTime().ToString())}");
sbMessage.Append(objResult.changeSet.items[i].msg.ToString());

sbMessage.AppendLine();
}
}

 

빌드가 실패한경우에는 consoleText 를 보여줘서, 오류를 확인하도록 할 수도 있다.

 

string consoleUrl = $"{jobUrl}{buildNumber}/consoleText";

 

response = client.GetAsync(consoleUrl).Result;
byte[] resultBytes = response.Content.ReadAsByteArrayAsync().Result;

// EUC-KR 인코딩
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
string resultText = Encoding.GetEncoding(51949).GetString(resultBytes);

sbMessage.Append(resultText);

 

 

이렇게 단체방에 전송할 메세지를 만들어서 단체방 메세지를 보낼 수 있다.

 

 

 

알림 메세지 예제

 

아래 예제는 네이버웍스에 Bot 을 생성해서, 단체방에 메세지를 보낸 화면이고, api 가 제공된다면 다른 메신저로 보낼 수도 있다.

 

Posted by 헝개
개발팁2021. 3. 18. 21:48

스틸 이미지가 많이 나오는 웹화면을 좀 더 다이나믹하고 보이려면 어떻게 해야 할까..

네이버 메인이나, 이미지 많은 쇼핑몰에서 주로 쓰는 방법이 마우스를 이미지 위로 올려놓을때, 이미지를 확대해서 보여주는 방법이다.

 

 

 

 

css 스타일시트를 분석해 볼 줄 안다면 아래와 같은 형태의 코드로 되어 있다는 것을 알 수 있다.

 

.default_list table tr:hover .photo img {
  -moz-transition: all 0.3s;
  -webkit-transition: all 0.3s;
  -ms-transition: all 0.3s;
  transition: all 0.3s;
  -moz-transform: scale(1.1);
  -webkit-transform: scale(1.1);
  -ms-transform: scale(1.1);
  transform: scale(1.1);
}

 

 

hover 즉, 마우스가 이미지 위로 올라왔을때 css 가 적용된다.

이미지를 확대해서 동적으로 보여주는 css 스타일은 2가지다.

 

transform: scale(1.1);

 

즉, 10% 확대해서 보여준다는 것이다.

scale(1.5) 로 하면, 50% 확대가 된다.

 

하지만, 이 효과만 있다면, 마우스 오버시 즉시 확대된다.

여기에 좀더 동적으로 보여지게 하는것이

 

transition: all 0.3s;

 

즉, 0.3 초 동인 A -> B 의 변화를 보여준다는 것이다.

 

(A)원래이미지 -> (B)확대된이미지

 

A에서 B 로 변화하는 과정을 보여준다는 것이다.

 

1.0s 로 바꾸면, 1초동안의 변화를 볼 수 있다.

 

 

어라, css 스타일은 2가지라고 했는데, 처음의 css 를 보면 몇가지 다른것들이 보인다.

 

-webkit-transform  // 크롬, 사파리
-moz-transform     // 파이어폭스
-ms-transform       // 익스플로러

 

위 3종류는 브라우저 호환성을 위해서 쓰여진 것이다.

 

 

 

이제, G마켓은 이미지 확대 기능이 적용되지 않은 사이트인데, 아래의 주소로 이동해서 테스트를 해볼 것이다.

 

corners.gmarket.co.kr/Bestsellers

 

아래 자바스크립트 코드를 실행해보자. (크롬의 개발자도구)

 

$('img').hover(function(){
    $(this).css("transform", "scale(1.1)");
    $(this).css("transition", "all 0.3s");
  }, function() {
    $(this).css("transform", "scale(1)");
});

 

이제 G마켓 사이트도 동적으로 이미지가 확대되는걸 볼 수 있다.

 

 

 

 

scale 숫자와 transition 숫자를 바꿔가면서 테스트 해보면, 재밌는 효과를 볼 수 있다.

 

Posted by 헝개
개발팁2020. 8. 27. 13:24

underscore.js 는 자바스크립트 라이브러리로, 컬럭션, 배열을 처리하는데 유용한 함수들이 제공된다.

 

https://underscorejs.org/

 

Underscore.js

Underscore is a JavaScript library that provides a whole mess of useful functional programming helpers without extending any built-in objects. It’s the answer to the question: “If I sit down in front of a blank HTML page, and want to start being produc

underscorejs.org

 

위 링크에서, 다운받을 수 있고, API 매뉴얼이 제공되니, 필요한거를 찾아서, 프로젝트에 적용할 수 있다.

현재 최신버전은 1.10.2 이다.

 

 

UMD 버전으로 받으면 되고, Production 버전은, min 버전으로

일단, 2개 다 다운받아 놓고, min 버전을 사용하다가, 특별한 경우.. (디버깅 등) 에는 Development 버전을 사용하면 될 것이다.

 

CDN 으로 이용하고자 한다면,

 

<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.10.2/underscore-min.js"></script>

 

위와 같이 사용하면 된다.

 

 

Collections / Arrays / Functions / Objects / Utility 로 구분되어 있고,

모든 함수는 언더바 _ 안에 들어 있다.

 

즉, _.each  _.isDate   _.union   이렇게 사용할 수 있다.

 

prototype 을 보면, 전체 함수 내역이 들어있는걸 볼 수 있다.

 

 

 

.toString() 을 하면, 함수 구현 내용도 바로 확인이 가능하다.

 

 

 

 

 

each 함수를 보면, forEach 와 같다는걸 볼 수 있다.

자바스크립트 array 에 있는 forEach 보다, 더 유연하게 사용할 수 있다.

 

 

 

pluck 함수는 json 에서 원하는 데이터만 배열로 꺼내올때 유용하다.

 

위의 예제에서는 name 값만을 배열로 가져왔으며, 여기에 추가로, sortBy 를 호출하면, 정렬된 데이터로 가져올 수도 있다.

 

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}];
_.sortBy(_.pluck(stooges, 'name'));

 

 

 

shuffle 이나 sample 는 게임같은곳에서 유용하게 사용할 수 있는 함수로,

shuffle 는 카드를 섞는것이 셔플링이라고 하는데, 배열 또는 json obejct 을 무작위로 섞어준다.

위의 샘플에서는 array 에 대해서만, 예가 나와 있지만, json object 를 섞어줄 수 있기 때문에, 상당히 유용하다.

 

참고로, Collections 아래 있는 모든 함수는 array 와 json object 에 대해서 모두 동작하는 함수이다.

 

sample 는 첫번째 인자의 array / json object 중에서, 두번째 인자의 갯수만큼 랜덤하게 샘플링을 하는 함수이다.

 

 

 

Array 함수중에 first / initial  / last / rest 는 지정된 갯수만큼 배열을 가져오는 함수이다.

 

sample 함수가 없다면, 

 

이런식으로 샘플링도 가능하다.

 

flatten 은 평탄화 를 위미하여, 여러개의 배열을 최상단의 value 로 묶어주고, 이때, 중복된 값에 상관없이 작업이 이뤄진다.

union 은 평탄화와는 다르지만, 여러개의 배열을 묶어서 하나의 배열로 만들고, 중복된 값은 제거된다.

uniq 는 하나의 배열안에서, 중복된 값을 제거하는 함수이다.

 

 

Objects 안에 있는 함수들은 json object 를 처리하는 함수들이 있다.

 

keys, findKy, clone, has, ...  그 외에는 많은 is 함수들이 있다.

 

값이 같은지 비교하는 isEqual

값이 포함되어 있는지 isMatch

isEmpty

isElement, isArray, isObejct, isArguments, isFunction, isString, isNumber, isFinite, isBoolean, isDate, isRegExp, isError

isSymbol, isMap, isWeakMap, isSet, isWeakSet, isNaN, isNull, isUndefined

 

 

Utility 에는 유용함 함수들이 들어 있다.

 

 

 

Math.random 으로 구현해야 했던, random 함수도 있다.

 

 

uniqueId 는 고유값을 생성하는것으로, 1부터 시작해서, 순차적으로 생성이 된다.

 

동적으로 DOM 을 생성하게 될때, id 속성에 유니크값을 넣어주면, 특정 위치를 바로 탐색할 수 있기에 유용하다.

 

그 외에도, 수많은 유용한 함수들이 있으니, 필요할때 꺼내먹어요 헉...

 

 

Posted by 헝개
개발팁2020. 7. 30. 17:05

자바스크립트의 언어 특성상, 배열도 자유자재로 다룰 수 있고,

자바스크립트의 배열은 다양하고 역동적이고, 자유로운 영혼이다.

 

 

 

배열 선언

 

var arrTemp = new Array();

 

var arrTemp = [];

 

 

자바스트립트의 배열을 선언하는 방법은 Array() 객체를 가지고 만드는 방법과,

이를 단순히 [] 만으로도 선언할 수 있다.

 

이는 객체를 만들때 new Object() 로 만들거나 {} 로 만들수 있는것과 같은 이치이다.

 

위의 배열 선언문은 사이즈가 0인 배열이었고,

아래와 같이 하면 배열의 사이즈를 줄 수 있다.

 

var arrTemp = new Array(5);

 

var arrTemp = [,,,,,];

 

위 예제는 모두 사이즈가 5개인 배열을 만들었다.

 

new Array() 즉,

일반적인 랭귀지와 달리 자바스크립트의 배열은 Array 라는 객체라는 것을 알 수 있다.

 

즉, Array 도 Object 인 것이다.

 

 

 

Array 의 prototype 을 보면, 자바스트립트의 Array 로 무엇을 할 수 있는지 알 수 있다.

 

 

[크롬 기준]

 

 

length 라는 속성외에는 전부 함수로 구성되어 있다는것을 알 수 있다.

 

 

 

데이터 탐색

 

배열에 대한 데이터 탐색은 모든 언어가 아래와 같이 사용하는것이 일반적이다.

 

for(var i=0; i < arrTemp.length; i++)
{
    console.log(arrTemp[i]);
}

 

이를 forEach 문으로 바꾸면 아래와 같이 쓸 수 있다.

 

arrTemp.forEach(function(d) { console.log(d) } );

 

이를 람다식으로 쓰면 아래와 같다.

 

arrTemp.forEach( d => console.log(d) );

 

 

큐(Queue)

 

자료구조에서 큐는 FIFO 로써, 먼저 들어간 데이터 먼저 나온다는 뜻이다.

 

[배열의 맨뒤에 데이터를 입력]

arrTemp.push('test');

 

[배열의 첫번째 데이터를 꺼내온다. (꺼내온 데이터는 삭제됨)]

console.log(arrTemp.shift());

 

 

 

스택(Stack)

 

스택은 LIFO 로써, 제일 나중에 들언간 데이터가 먼저 나온다는 뜻이다.

 

[배열의 맨뒤에 데이터를 입력]

arrTemp.push('test');

 

[배열의 마지막 데이터를 꺼내온다. (꺼내온 데이터는 삭제됨)]

console.log(arrTemp.pop());

 

 

배열에 데이터 입력

 

큐/스택의 예에서 처럼 배열의 맨뒤에 데이터를 입력하는 함수는 push 이다.

 

[배열의 맨뒤에 데이터를 입력]

arrTemp.push('test');

 

[배열의 맨앞에 데이터를 입력]

arrTemp.unshift('test');

 

[배열의 중간에 데이터를 입력]

arrTemp.splice(1, 0, 'add')

 

1은 데이터를 삽입할 index 이고, 0은 삭제할 count 이기 때문에, 0으로 입력하여 삭제하지 않도록 한것이다.

 

 

배열의 데이터 삭제

 

큐/스택의 예에서 처럼, 배열의 첫번째 삭제시는 shift() 함수를 쓰면 된다.

마지막 데이터삭제는 pop() 함수를 쓰면 된다.

 

[중간의 데이터 삭제는 splice 를 사용하면 된다.]

arrTemp.splice(1, 3)

 

배열의 index 1번 부터 시작해서, 3개의 배열항목을 삭제한다.

 

 

좀 더 심화된 자바스크립트 배열을 사용하고 싶다면, 아래 내용을 참고하면 될 것이다.

 

 

 

변경자 메서드

 

- copyWithin()
배열 내의 지정된 요소들을 동일한 배열 내에서 복사합니다.
- fill()
배열 안의 시작 인덱스부터 끝 인덱스까지의 요소값을 지정된 정적 값으로 채웁니다.
- pop()
배열에서 마지막 요소를 뽑아내고, 그 요소를 반환합니다.
- push()
배열의 끝에 하나 이상의 요소를 추가하고, 변경된 배열의 길이를 반환합니다.
- reverse()
배열의 요소 순서를 반전시킵니다. 첫 번째가 마지막이 되고 마지막이 첫 번째가 됩니다.
- shift()
배열에서 첫 번째 요소를 삭제하고 그 요소를 반환합니다.
- sort()
배열의 요소를 정렬하고 그 배열을 반환합니다.
- splice()
배열에서 요소를 추가/삭제합니다.
- unshift()
배열의 앞에 하나 이상의 요소를 추가하고 새로운 길이를 반환합니다.

 

 

접근자 메서드

 

- concat()
배열을 매개변수로 주어진 배열/값과 이어붙인 새로운 배열을 반환합니다.
- filter()
지정한 콜백의 반환 결과가 true인 요소만 모은 새로운 배열을 반환합니다.
- includes()
배열이 주어진 값을 포함하는지 판별해 true 또는 false를 반환합니다.
- indexOf()
배열에서 주어진 값과 일치하는 제일 앞의 인덱스를 반환합니다. 없으면 -1을 반환합니다.
- join()
배열의 모든 요소를 문자열로 합칩니다.
- lastIndexOf()
배열에서 주어진 값과 일치하는 제일 뒤의 인덱스를 반환합니다. 없으면 -1을 반환합니다.
- slice()
배열의 일부를 추출한 새 배열을 반환합니다.
- toSource() 
지정한 배열을 나타내는 배열 리터럴을 반환합니다. 새로운 배열을 만들기 위해 이 값을 사용할 수 있습니다. Object.prototype.toSource() 메서드를 재정의합니다.
- toString()
배열과 그 요소를 나타내는 문자열을 반환합니다. Object.prototype.toString() 메서드를 재정의합니다.
- toLocaleString()
배열과 그 요소를 나타내는 지역화된 문자열을 반환합니다. Object.prototype.toLocaleString() 메서드를 재정의합니다.

 

 

순회 메서드

 

- entries()
배열의 각 인덱스에 대한 키/값 쌍을 포함하는 새로운 배열 반복자 객체를 반환합니다.
- every()
배열의 모든 요소가 주어진 판별 콜백을 만족할 경우 true를 반환합니다.
- find()
주어진 판별 콜백을 만족하는 첫 번째 요소를 반환합니다. 만족하는 요소가 없으면 undefined를 반환합니다.
- findIndex()
주어진 판별 콜백을 만족하는 첫 번째 요소의 인덱스를 반환합니다. 만족하는 요소가 없으면 undefined를 반환합니다.
- forEach()
배열의 각각의 요소에 대해 콜백을 호출합니다.
- keys()
배열의 각 인덱스에 대한 키를 가지는 새로운 배열 반복자 객체를 반환합니다.
- map()
배열의 모든 요소 각각에 대하여 주어진 콜백 함수를 호출하고, 그 반환값을 모은 새로운 배열을 반환합니다.
- reduce()
주어진 콜백 함수를 가산기와 요소 각각에 대해 왼쪽에서 오른쪽으로 호출하여 하나의 값으로 줄인(reduce) 결과를 반환합니다.
- reduceRight()
주어진 콜백 함수를 가산기와 요소 각각에 대해 오른쪽에서 왼쪽으로 호출하여 하나의 값으로 줄인(reduce) 결과를 반환합니다.
- some()
배열의 어떤 요소가 주어진 판별 콜백을 만족할 경우 true를 반환합니다.
- values()
배열의 각 인덱스에 대한 값을 가지는 새로운 배열 반복자 객체를 반환합니다.

 

 

 

Posted by 헝개
개발팁2020. 3. 20. 19:23

 

텔레그램봇을 만들기 위해서는 위선 봇아부지(BotFather) 에게 토큰을 만들어야 한다.

 

 

1. 봇 Token ID 생성하기

 

 

 

우선 텔레그렘에서 BotFather 와 대화를 시작해야 한다.

모든 요청은 BotFather 와의 채팅방에서 이뤄진다고 보면 된다.

 

텔레그램의 검색창에 botfather 를 치고, 맨위의 BotFather 를 클릭한다.

 

 

채팅창에 /start 라고 치면, 도움말이 나온다.

 

 

 

이제 나만의 봇을 만들어보자.

 

/newbot 이라고 치면, 봇의 이름을 입력하라고 나온다.

봇의 이름은 한글로 치던 어떤걸 치던 상관이 없다.

 

그리고 나면, bot의 username 을 입력하라고 하는데, 이 username 은, 텔레그램 시스템 안에서 중복되지 않는 이름이어야 한다. 그리고, 뒤에는 bot 로 끝나야 한다.

 

 

 

 

username 입력이 끝나면, 봇이 생성되고, 본의 token 값이 나온다.

이 token 값은 잘 간직하고 있다가, 나중에 메세지를 보낼때 사용하게 된다.

 

한사람당 하나의 봇만 만들 수 있는게 아니라, 여러개도 만들 수 있다. (/newbot)

 

 

 

2. 대화방 만들고 ChatID 가져오기

 

 

이제 봇과 대화를 시작해볼것이다.

 

아까 생성했던 본의 이름을 앞에 @ 를 붙여서 검색해보자.

 

 

 

 

클릭하고 들어가서 시작을 누르면, 봇과의 채팅이 시작된 것이다.

시작을 누르고, 아무 메세지나 적어보자.

 

그러면, 이 대화방의 ChatID 가 생성이 된다.

 

이제, ChatID 를 가져오는 방법은 텔레그램 API 를 이용할것이다.

 

웹브라우저 주소창에 아까 받은 token 값을 이용해서, 아래와 같이 입력한다.

 

 

https://api.telegram.org/bot{토큰값}/getUpdates

 

{토큰값} 은 실제 token 값으로 입력해야 합니다.

api.telegram.org/bot1234?????:ABCD??????????????????????/getUpdates

 

 

chat id 값이 나왔으니, 이제 텔레그램 API 를 통해서 바로 채팅방에 메세지를 보낼 수 있게 됐다.

(chatid 는 양수 또는 음수로 나온다)

 

https://api.telegram.org/bot{토큰값}/sendMessage?chat_id={ChatID}&text={메세지}

 

{ChatID} 는 실제 chatid 를 입력해야 합니다.

sendMessage?chat_id=1234????&text=테스트

sendMessage?chat_id=-1234????&text=테스트 (음수일때)

 

 

웹브라우저 주소창에 위의 내용을 넣어보자. 결과는 ok: true 라고 해서 성공적으로 메세지를 전송했다.

 

 

 

텔레그램 채팅창에 메세지가 도착한것을 확인할 수 있다.

 

 

 

 

3. 봇이 있는 그룹채팅방 만들기

 

 

위 2번에서는 봇과 나 단 둘만 있는 채팅방이다.

즉 token / chatid 를 통해 메세지를 보내면, 나만 볼 수 있는 채팅방인것이다.

동일한 봇 채팅방을 여러명이 있는 채팅방을 만드려면 그룹(Group) 이라는 단체 채팅방으로 통해 생성가능하다.

 

 

 

 

텔레그램의 메뉴에 가면, [그룹 만들기] 라는 메뉴가 보인다. 이것이 단체 채팅방을 만드는 기능이다.

 

 

 

 

여기서 그룹에 추가하려는 친구를 선택하는데, 선택하지 말고, 검색창에

위에서 만든 봇의 이름을 @ 를 먼저쓰고 입력해보자.

첫번째 나오는것이 위에서 만들었던 봇이다. 이를 선택하면, 그룹이 생성된다.

 

 

 

그룹이 만들어졌지만, 아직까지는 나와 봇 2명밖에 없다.

 

상단의 그룹이름을 클릭하면, 단체채팅방에 친구를 초대할 수 있다.

 

 

 

 

참가자 추가 버튼을 눌러 친구를 초대하면 된다.

 

이제 단체 채팅방에서, 메세지를 아무거나 입력하고 나서,

 

[2. 대화방 만들고 ChatID 가져오기] 에서 했던것처럼, getUpdates 로 단체채팅방의 chat_id 를 가져올 수 있고, sendMessage 로 메세지를 보낼 수 도 있다.

 

 

https://api.telegram.org/bot{토큰값}/getUpdates

 

https://api.telegram.org/bot{토큰값}/sendMessage?chat_id={ChatID}&text={메세지}

 

Posted by 헝개