[야매코딩] 누구나 만들어보는 스팀봇! - (5) 예제로 따라하는 스팀봇 뚝딱
0. 드디어 프린이만의 봇 탄생, 30분 전!
코딩 1도 몰라도 일단 따라하면 되는, '누구나' 하는 야매코딩 시리즈입니다.
누구나 만들어보는 스팀봇! 강좌 다섯 번째 편에 오신 것을 환영합니다. 두둥! 이번 편에서 드디어 봇이 1차적으로 완성됩니다 하핳
반가워요 프린이(프로그래밍 어린이) 여러분!
혹시 처음 오셨다면, 소개편이 있습니다. 강좌가 새로 올라오면 소개편에 링크가 업데이트 되니, 리스팀/북마크 해두면 편할겁니다 :)
저번 시간에 레시피를 작성하는 방법을 배웠죠?
vim으로 메모장을 열어 i
를 눌러 작성한 뒤 ESC 그리고 :wq
로 저장 및 종료했었습니다. 그리고 파이썬 레시피(코드)를 실행하려면 python3 메모장이름.py
였죠.
또한 스팀 API 심화 단계로 블록체인이랑 포스트 개념도 소개되었습니다. 일단 따라는 하면 뭔가 막 실시간으로 스팀 블록체인에서 받아와졌죠.
하지만 아직은 막연한 존재로만 느껴질거예요. 뭔가... 되긴 하는데 이게 과연 뭔지 했죠? 저번 편에 제가 애매하게 끊어서 그렇습니다ㅠㅠ 이번 편에서 마저 설명을 드리도록 하겠습니다.
만약 저번의 스팀 블록체인 API 관련 코드가 어려웠어도 괜찮아요. 지금 꼭 이해를 완벽히 해야 하는 부분은 아닙니다.
중요한 부분은 스팀봇이 어떤 조건에 어떻게 반응하냐겠죠?
그래서 이번 편에서는 지금까지 배운 내용에 살을 붙여 실제로 작동하는 기본적인 스팀봇을 함께 만들어볼게요. 드디어 여태까지 함께 달려온 노력의 결실을 맺는 편입니다! 두구두구두구
A. 개발 환경설정 따라하기 I - Google Cloud 세팅
B. 개발 환경설정 따라하기 II - Conda 세팅
C. 스팀 API 설치 및 살펴보기 101
D. 스팀 API 심화, 블록체인 & 포스트
E. 예제로 따라하는 스팀봇 뚝딱 ☜
F. nohup으로 자동화, 알아서 언제나 24/7
그럼 본격적으로 시작해볼까요?
- 난이도: 上
- 소요시간: 약 40분
이미지 출처 - https://dribbble.com/shots/3974885-Bumblebee by Pat Grivet
1. 이제는 알 수 있어요.
여기까지 함께한 프린이라면 이제 강좌를 위한 준비 단계는 거뜬히 혼자 할 수 있다고 믿어요. VM인스턴스(부엌) 접속하고 조리기구 세팅까지 해주세요.
- 구글 클라우드 콘솔 사이트로 이동하고,
- Compute Engine 항목을 클릭하여,
- VM인스턴스의 SSH 버튼을 눌러 접속해주세요.
- 그리고
source activate steembot
을 입력해주세요. (조리기구 세팅)
자 준비됐나요?
우선 저번 강좌의 기억을 되살리기 위해 ls
명렁어 부터 시작해볼까요?
제일 첫 연습용 레시피(코드)였던 test.py와 저번 시간에 스팀 블록체인에서 실시간으로 포스트 정보를 받아오던 정체모를 레시피(코드) blockpost.py가 보이네요.
메모장을 굳이 열지 않고, 레시피 안에 내용을 보는 명령어는 cat이었죠?
cat blockpost.py
만약 숙제를 해오셨다면, 마지막 줄은 print(post)가 아닌 print(post.export())으로 되어 있을겁니다 :) 숙제 완성 여부 상관없이 일단 레시피(코드)는 그대로 놔둬주세요.
그리고 저번에 의문의 결과...! 이제 설명드리겠습니다.
레시피 실행방법은 기억나시죠? python3 blockpost.py
2번째 사진처럼 정체모를 실시간 결과와 3번째 사진처럼 갑자기 찾아오는 에러 메세지! 2번째 사진을 좀 더 자세히 살펴봅시다.
실시간 결과가 아직 뭔지 감이 안 오시는 프린이 여러분들, 힌트는 URL 상단에 있습니다.
눈치 채셨나요?
스팀잇 웹사이트 내용을 보느라 쉽게 놓쳤을 수도 있는 스팀잇 URL의 구성이 답입니다.
이전편 URL을 보시면:
- https://steemit.com
- /kr-dev
- /@hellocrypto
- /4-api-and
이렇게 4가지 부분으로 구성되어 있습니다.
1번은 기본 웹사이트 URL이죠?
2번은 해당 포스트의 첫 번째 태그입니다. 최대 5개까지 태그를 달 수 있고 언제든 수정도 가능 하지만, 한 번 글을 올리고 나면 첫 번째 태그만큼은 절대 변경이 안 되요. 나머지 4개는 되지만요. 그래야 URL이 바뀌지 않겠죠?
3번은 제 아이디 @hellocrypto네요.
4번은 글을 올리면 스팀에서 자동으로 생성시키는 해당 글의 고유 이름입니다.
이렇게 4가지 요소들이 합쳐서 특정 글의 고유주소를 나타내죠. 그리고 주소는 쉽게 바뀌면 안 되기 때문에 글을 포스팅 하는 순간, 딱 정해지고 그 이후 바뀌지 않아요.
이를 영어로 permlink(permanent link, 고유주소)라고 합니다.
그럼 포스트만 그러냐, 하면 아닙니다! 댓글도 마찬가지로 고유주소가 있습니다. 구조는 비슷하나 길이는 훨씬 깁니다. 댓글 시간 표시에 우측 클릭해서 링크를 확인할 수 있습니다.
이해되게 설명할게요 오치님ㅠㅠ
자 그럼 permlink에 대한 이해를 가지고 다시 레시피(코드)의 결과를 볼까요?
이제 보이시나요? 실시간으로 출력되던 결과들은 permlink의 기본 형태였습니다.
다만 포스트(게시물)이랑 댓글이 둘 다 보이네요. 뒤에 긴 숫자가 붙는건 댓글, 비교적 짧은건 포스트(게시물)죠.
그리고 <Post- 뒤에는 스팀ID/포스트링크
형식입니다. 다만 스팀ID 앞에 @ 골뱅이는 빠져있죠.
실제로 확인해볼까요?
스크린샷 제일 하단의 bigssam/are-you-broken
으로 테스트해보겠습니다.
인터넷 브라우저 URL에 steemit.com/@bigssam/are-you-broken
를 입력했더니, 자동으로 맨 앞에 steemchurch라는 변경불가의 첫 태그가 자동으로 붙어 최종적으로 steemit.com/steemchurch/@bigssam/are-you-broken
라는 포스트가 보이게 되었습니다.
짜잔! 참고로, 만약 안 나온다면 그 사이 삭제된 댓글일 수도 있습니다.
레시피(코드)는 분명 filter_by=['comment']로 입력했었죠? 댓글만 필터하기로 했는데, 왜 게시물이랑 댓글이 섞여 나오는걸까요?ㅠㅠ 이 또한 함께 뒤에서 고쳐보겠습니다.
이제 이해도 +1이 생겼으니, 저번 숙제 내용으로 넘어갈까요?
좋아요. 이제 프린이 여러분은 스팀 블록체인에서 실시간으로 생겨나는 게시물/댓글의 permlink를 얻어오는 능력을 갖췄어요.
하지만 그걸로는 부족하죠?
예를 들어, @주사위 같은 봇을 만들고 싶다면 댓글 내용을 읽을 수 있어야 하고, 내용 중에 '@주사위'라는 문구가 있는지 확인을 할 수 있어야겠죠?
그래서 첫 번째 '댓글 내용 읽기'가 저번 숙제의 목표였습니다.
숙제를 아직 못 했다면, blockpost.py
레시피(코드)를 vim
으로 열어서 마지막 줄 print(post)
를 print(post.export())
로 변경해주세요.
그리고 들어가서는
i
를 눌러 수정모드, 나올 때는 ESC,:wq
그리고 엔터 잊지 마세요!
이전에 그냥 post를 인쇄 print() 해왔다면, 이제는 post의 내용을 밖으로 꺼내어 .export() 인쇄를 print() 하는겁니다.
python3 blockpost.py
그 결과는, 복잡하고 긴 양의 텍스트가 돌아옵니다.
하지만 맨 처음 스팀API를 통해 계정 정보를 확인했을 때도 그랬죠?
사실 별 내용은 없는데, 괜히 복잡해보일 뿐입니다.
계정 정보 확인할 때 s.get_account('hellocrypto')
입력하면 길었지만, 뒤에 .['name']을 붙여 s.get_account('hellocrypto').['name']
으로 요청하면 간단히 이름 부분만 출력 됐었죠?
여기도 마찬가지로 게시물/댓글의 내용만 뽑아보면 보기 편하겠죠? 실질적으로 필요한 부분이고도 하고요.
마지막 줄을 print(post.export()['body'])
으로 수정해줍시다.
자 다시 python3 blockpost.py
로 레시피(코드)를 실행시켜주면,
이렇게 본문 내용들만 하나씩 출력되네요 :)
2. 힘을 내요 블록체인 씨!
지금까지 따라오셨으면 프린이는 실시간으로 게시물/댓글의 내용을 읽을 수 있네요.
그럼 일단 5~6개 출력 후 멈춰버리는 문제부터 해결해볼까요?
파이썬 스팀API의 개발 이슈에다가 기본 노드의 문제로 인해 발생하는 오류입니다. 그게 뭐냐고요? 먹는거냐고요?
실제로는 프린이가 바로 스팀 블록체인에 접속하는게 아니라 사이에 '노드'라고 중간매체가 있어요. 그런데 스팀에서 기본으로 제공하는 '노드'가 살짝 아프다는게 문제죠.
그래서 기본 노드에서 다른 노드로 바꿔볼게요.
우선 from steem import Steem
을 추가해주세요(3번째 줄). 노드 변경은 블록체인Blockchain이나 포스트Post 처럼 특별한 기능이 아닌 스팀의 기본이거든요.
그리고 바로 아래에 s = Steem(nodes=["https://rpc.buildteam.io"])
를 입력해주세요. https://rpc.buildteam.io라는 노드를 사용하게 되는겁니다. 스팀API 첫 예제에서는 s = Steem()
뿐이었는데 안에 노드 정보가 추가된거죠 이번에는.
마지막으로 b = Blockchain()
을 b = Blockchain(s)
로 바꿔주세요. 스팀의 노드 정보를 s에다가 저장을 했으니, 이를 이용해서 스팀 블록체인에 접근하라고 알려줘야겠죠?
이제 python3 blockpost.py
로 레시피(코드)를 테스트 삼아 실행 해보면, 전과 달리 술술 출력이 될겁니다. 이제 뭔가 좀 있어 보이죠? :)
이제 안 멈추니까 오히려 곤란한가요? Ctrl+Z를 누르면 강제 중단을 할 수 있습니다.
하.지.만!
아직도 간혹 멈추는 경우가 있습니다. 한 번 계속 출력되게 놔두다 보면 아래와 같은 에러가 발생합니다.
바로 포스트가 삭제된 경우죠. PostDoesNotExist라고 되어 있죠?
스팀 댓글 같은 경우에는 대댓글이 없고, 일정 기간 내라면 삭제가 가능하니 .export()로 내용을 읽으려는 찰나! 그 사이 삭제되어 버려서 읽을게 없어진겁니다 ㅂㄷㅂㄷ
이것이 바로 코딩의 삶!
끝 없는 오류를 고쳐나가는 여정
그리고 여태까지 겪어봤듯이, 에러가 발생하면 덜컥 멈춰버리죠?
그런데 스팀봇은 그러면 안 되잖아요. 24/7 계속 풀가동 해야 하는데! 에러를 마주쳤다고 도망가면 안 되죠. 그렇게 약하게 키우진 않았어, 스팀봇!
다행히 두 가지 조합으로 해결할 수 있습니다.
while문과 try/except문입니다.
프린이를 위한 토막 상식! while문은
while (조건):
으로 작성되며 안쪽에 있는 내용을 특정 조건에 달할 때까지 반복해서 돌립니다. 다시 말해, 영원히 돌려버릴 수도 있죠.
그리고 try/except도
try:
랑except:
으로 작성되는데, try 안쪽의 내용을 진행하다가 위와 같이 에러가 생기면 덜컥 멈추는게 아니라, 바로 except의 안쪽 내용으로 넘어가게 합니다.
이를 적용한 해결법 부터 공개하고 설명드리겠습니다.
stream = map(Post, b.stream(filter_by=['comment']))
for post in stream:
print(post.export()['body'])
위에서 아래처럼 바뀌었습니다.
while True:
try:
stream = map(Post, b.stream(filter_by=['comment']))
for post in stream:
print(post.export()['body'])
except:
print("Hello! Error!")
겁 먹지 말아요 :) 하나씩 설명드릴게요.
우선, 말했듯이 파이썬에서는 띄어쓰기가 틀리면 안 되요. 수정하면서 유의해주세요!
while True:
(탭)try:
(탭)(탭)for:
기존 코드는 이제 try:
안에 다 들어갔죠?
이제는 try 안의 내용을 진행하다가 PostDoesNotExist 에러 같은 일이 발생하면, 덜컥 멈추기 전에 except 안의 내용으로 들어가게 됩니다.
즉 에러가 발생하면 print("Hello! Error!")
가 실행되겠죠? 이상한 에러 문구 대신, Hello! Error!라는 활기찬 텍스트만 짧게 인쇄됩니다.
하지만 Hello! Error!가 인쇄된 후에는 프로그램이 종료됩니다. 왜냐하면 try에서 except으로 넘어왔는데 여기는 계속 스팀 블록체인 정보를 받아오는 기존의 코드가 없잖아요?
다시 try로 돌아오면 좋겠는데 말이죠.
그.래.서! 전체 코드가 while True:
안에 들어가 있습니다.
while은 특정 조건이 성립될 때까지 안의 코드를 계속 반복시킵니다.
예를 들어 while i < 3:이었으면 i가 3보다 작을 때 계속 반복되죠. 그러다가 안의 코드가 i를 3보다 크게 바꾸는 경우가 생기면 while 조건이 더 이상 성립되지 않아 종료됩니다.
그런데 지금은 조건이 True입니다. 언제나 조건 성립!이라는 뜻이죠. 어떻게 바뀔 여지가 없이 무한히 계속 안의 코드가 반복됩니다.
다시 말해, try에서 에러가 발생하면 except로 넘어가고 종료가 되야 하지만, while 안에 있으니 다시 try부터 시작하게 됩니다. True가 조건이니 영원히요.
이제 다시 레시피(코드)를 실행하면 끝없이 출력이 됩니다.
다만 에러가 발생했을 시점이라면 종료가 되지 않고, 대신 'Hello! Error!'만 출력되고 넘어가죠.
3. 똑똑해져라 스팀봇, 얍!
프린이만의 스팀봇을 만들려면 이제 뭐가 남았을까요?
어떤 스팀봇을 만들고 싶은지 따라서 다를텐데요, 이번 편에서는 똑같은 기본적인 스팀봇을 만들겁니다.
누군가 '@특정문구'를 게시물/댓글에 남기면, 자동으로 스팀봇이 댓글을 남기게 할겁니다.
댓글에 본인만의 스팀봇이 어떤 조건에 어떻게 행동했으면 좋겠다!를 남겨주세요 :) 참고해서 야매코딩 스팀봇 시리즈 마지막에 심화편을 하나 추가할게요!
그러려면, 현재 레시피(코드)에서 더 필요한 능력은 현재 실시간으로 읽어오는 포스트에서 '특정문구'의 존재여부를 확인하는 것이겠네요.
만일 해당 특정문구가 없다면 스팀봇과는 별 상관이 없는 게시물/댓글일테니 사뿐히 무시해야겠죠.
다행히 간단하게 추가할 수 있습니다.
예를 들어, '@야매코딩'의 존재여부를 확인하고 싶다고 가정할까요?
그럼 파이썬 레시피(코드)는 다음과 같을겁니다.
if "@야매코딩" in 내용:
댓글을 남겨라!
말 그대로 if 만약에 "@야매코딩"가 내용 in 안에 있다면, (:) 안의 내용을 해라! 입니다.
그럼 댓글의 맨 앞에 '@야매코딩'이 있든, 중간 어디간에 '@야매코딩'가 섞여있든 상관없이 '@야매코딩' 문구가 확실히 들어만 있다면 조건이 성립됩니다.
이제 본래 레시피(코드)에 반영해볼까요?
while True:
try:
stream = map(Post, b.stream(filter_by=['comment']))
for post in stream:
if "@야매코딩" in post.export()['body']:
print(post.export()['body'])
except:
print("뀨")
이전에는 단순히 print(post.export()['body'])
로 스팀 블록체인에서 받아오는 모든 글을 인쇄했지만, 이제는 if를 이용해 "@야매코딩" 문구가 있어야만 인쇄되게끔 if "@야매코딩" in post.export()['body']:
이 추가됐죠?
이제 저장하고 python3 blockpost.py
를 실행하면 반응이 없을겁니다. 누군가가 "@야매코딩"을 쓰지 않는 이상 말이죠.
지금은 의미 없으니, Ctrl+Z로 종료할 수 있습니다.
4. 일을 해라 핫산 스팀봇!
자 이제 마지막으로 댓글을 남기는 능력을 줘야겠죠?
그런데 알다시피, 스팀에서 뭔가 글을 남기려면 그럴 권한이 필요합니다.
지금의 레시피 어디에도 프린이 '본인'이라는 내용은 없죠? 레시피를 실행할 때, 이게 @hellocrypto인지, @hellocrypto.bot인지 혹은 또 다른 사람인지 알 수가 없습니다.
그래서 노드를 입력했던 s = Steem() 안에 key를 넣어줘야 합니다.
s = Steem(nodes=["https://rpc.buildteam.io"], keys=["Key Goes Here"])
"Key Goes Here" 대신에 본인이 로그인 할 때 쓰는 길다란 비밀번호(key)나 안전하기 위해 Posting Key를 이용해주시길 바랍니다. 이는 절대 외부에 공개해서는 안 됨을 잘 알고 계시죠?
저어얼대 키를 포함한 스크린샷을 남기지 마세요!!!!
자 여기까지 수정했으면 이제 포스팅 능력을 갖춘 스팀봇이 되었습니다.
그럼 이제 글을 쓰도록 해야겠죠?
while True:
try:
stream = map(Post, b.stream(filter_by=['comment']))
for post in stream:
if "@야매코딩" in post.export()['body']:
print(post.export()['body'])
post.reply("Hi there!","","hellocrypto")
except:
print("뀨")
기존의 print(post.export()['body'])
아래에 post.reply("Hi there!","","hellocrypto")
를 추가해주시면 끝입니다.
실시간으로 불러오고 있는 post 중에서 "@야매코딩"이 있다면, .reply() 답변을 답니다. 그 내용은 ("Hi there!","","hellocrypto")인데요, "Hi there!" 대신 다른 문구를 넣어도 당연히 됩니다. 그리고 끝에 "hellocrypto"는 작성자 ID입니다. 이를 본인 ID로 바꿔주세요 :)
대댓글 내용과 ID 사이에 있는 ,"",은 꼭 남겨주세요.
자 그럼 최종적으로 테스트 할까요?
다시 나와서 python3 blockpost.py
를 실행해주세요.
그리고 실행 후에 여기 글 밑에다가 댓글로 본인만의 '@특정문구'를 작성해주세요.
vim 안에서 한국어를 이용 시 글이 깨져보일 수 있습니다. 사실 별 문제 없이 입력되나 화면상 그렇게 보입니다. 그럴 때 마저 한국어를 작성하시고, 해당 줄 끝에서 엔터를 눌러 다음 줄로 넘어갔다가, 백스페이스를 바로 눌러 돌아가면 정상적으로 돌아갈겁니다 :)
그럼 아직까진 빈 화면으로 실행중이던 레시피(코드)에 새로운 문구가 인쇄됩니다.
이렇게 말이죠.
조금 기다려야 할 수도 있습니다. 댓글이 블록체인에 포함되고, 다시 그걸 읽어와야 하잖아요?
그 결과는 훌륭합니다!
자동으로 스팀봇이 대댓글을 남긴 모습을 확인할 수 있습니다! 으핳핳
숙제입니다! 댓글에 본인만의 '@특정문구'를 입력해서 봇이 대댓글을 남기게 해봐요 :)
여기까지 잘 따라오셨나요 프린이 여러분?
드디어 작동하는 기본적인 스팀봇이 완성됐습니다!
대단한 스팀봇은 아니지만, 원하는 특정문구에 반응해서 대댓글을 남길 수가 있게 됐죠 :)
하지만 여전히 큰 문제점이 하나 남았습니다. VM인스턴스의 검은화면을 종료하면, 스팀봇도 같이 종료되고 맙니다. 24/7 돌아가기 위해 그래선 안 되겠죠?
다음 시간에 함께 이를 고쳐보도록 하겠습니다.
다음 마지막 편(F. nohup으로 자동화, 알아서 언제나 24/7)으로 찾아뵙겠습니다. 그리고 기회가 되면 심화편으로 좀 더 스팀봇을 커스텀 하는 법을 알려드릴게요.
궁금하신 점, 지적하실 점(환영합니다) 혹은 문제가 발생했다! 싶으면 댓글 언제든 남겨주세요. 빠른 답변은 아니겠지만(...) 대답드리겠습니다 :)
그리고, 본인이 원하는 스팀봇의 조건과 능력을 댓글에 남겨주시면 최대한 반영해 심화편에서 방법을 알려드리겠습니다.
이만 상병 크립토였습니다. 필승!
휴 이번 글을 busy.org에서 임시저장 하면서 작성하고 글쓰기 제출했는데, 이전 편 글을 덮어씌우는 바람에 잠시 식은땀 흘렸네요. 다행히 이전 기록을 저장해주는 사이트가 있어서 겨우겨우 복구했습니다 :) 날아가는줄 알고 핵식겁ㅠㅠ
오! 조건문을 저런식을 했군요.
문자열 추출로만 생각했는데 표현이 간단하네요.
참고하고 갑니다.
자바스크립트로 한번 따라서 한개의 게시물에서만 body에서 해당 문자열 찾기 해봤네요.
steem.api.getContent('hellocrypto', '5', function (err, result) {
var str = result['body'];
if(str.match('@야매코딩')) console.log("찾았다");
});
python 으로는 어떻게 해야 할까요? 변환 부탁 드려도 될까요?
포스트 쓰신문의 명령문이 파이썬이에요.
그대로 하시면 돼요.
위의 포스트 글에서 if문 있잖아요 그게 특정 문자열 찾는 명령이에요.
전 그냥 자바스크립트에서 한개의 게시물에서만 특정 문자열을 찾는 방식을 한 것이고요.
위 포스트 방식으로 코딩 하시면 돼요.
while True:
try:
stream = map(Post, b.stream(filter_by=['comment']))
for post in stream:
steem.api.getContent('hellocrypto', '5', function (err, result) {
var str = result['body'];
if(str.match('@야매코딩')) console.log("찾았다");
});
except:
print("뀨")
이렇게 넣으면 되는거야?
호오.. 스팀 개발도 이 글 보다보니 관심이 생기네요.. 파이썬 기반인가요?
감사합니다. 알려주신대로 해서 돌려보고 있는데요
아주 아주 잘됩니다. 신기하게도
메모를 여러개 적어두고 랜덤하게 나가게 할 수 도 있을까요?
한 게시물안에 같은 내용만 쭉 보이니까.. 별로라
https://steemit.com/kr-gazua/@dailypro/kr-gazua-newbie-02220180420t233316651z
상당히 친절하게 설명해 주셨네요!
많은 도움이 될 것 같습니다 : )
포스트인지 댓글인지 확인하는 과정을 빼먹은 크립토님... ㅋㅋㅋㅋ
헉 그러네요...ㅋㅋ is_comment() / is_main_post()를 쓰면 되는데, 다음 편에 꼭 넣어둘게요 하핳
ㅎㅎㅎ :D 설명하시면 얻어먹어야징...
월요일부터 실전연습 들어갑니다!
이번에는 주말을 이용해서 천천히 해봐야겠네요 ㅎㅎ 상병 크립토님 좋은 포스팅 응원해요오!! :) 감사감사!
여기까지만 해도 제가 궁금했던 내용 대부분이 들어있네요 ㅎㅎ 감사합니다.
혹시 텔레그램으로 스팀잇에 대댓글다는 기능도 구현할 수 있나요??
텔레그램의 steem alert로 새 댓글 달린건 확인하고 있는데, 대댓글을 달기 위해서 스팀잇 들어오는게 너무 귀찮더라고요 ㅋㅋ
이 댓글도 읽어오네요 ㅋㅋ 잘 작동되고 있는것 같아 만족스럽습니다
이건 텔레그램으로 연결하는것 까지 해야해서 너무 어렵겠죠...?
특정 '글쓴이'의 글에 댓글다는 건 별로 안어려워보이는데 가능할까요??
공부 해야겠어요 공부 공부 공부 ~
좋은 정보 감사합니다. 아직 실습을 안해서 곧 해보겠니다.