duo_cafe_comment 0.0.39 → 0.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/duo_cafe_comment.rb +2224 -527
- metadata +2 -2
data/lib/duo_cafe_comment.rb
CHANGED
@@ -493,33 +493,7 @@ class Naver
|
|
493
493
|
sleep(1)
|
494
494
|
@driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
|
495
495
|
|
496
|
-
|
497
|
-
|
498
|
-
if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
|
499
|
-
content = ''
|
500
|
-
else
|
501
|
-
if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
|
502
|
-
content = @data['내용설정']['내용'].sample[2]
|
503
|
-
else
|
504
|
-
content = @data['내용설정']['내용'][@content_soon][2]
|
505
|
-
@content_soon += 1
|
506
|
-
@content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
|
507
|
-
end
|
508
|
-
end
|
509
|
-
|
510
|
-
# 디엠 자동 변경이 체크된 경우 content를 변환
|
511
|
-
if @data['포스트설정']['내용자동변경'].checked?
|
512
|
-
change_memory = {}
|
513
|
-
@data['포스트설정']['내용자동변경값'].each do |key, v|
|
514
|
-
change_memory[key] = v.sample
|
515
|
-
end
|
516
|
-
@data['포스트설정']['내용자동변경값'].each do |key, _|
|
517
|
-
if content.include?(key)
|
518
|
-
content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
|
519
|
-
else
|
520
|
-
end
|
521
|
-
end
|
522
|
-
end
|
496
|
+
|
523
497
|
|
524
498
|
if option['좋아요'] == 'true'
|
525
499
|
puts "좋아요 클릭 옵션 진행!!".cyan
|
@@ -548,134 +522,707 @@ class Naver
|
|
548
522
|
else
|
549
523
|
end
|
550
524
|
|
551
|
-
|
552
|
-
begin
|
553
|
-
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
|
554
|
-
wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
|
555
|
-
|
556
|
-
# 댓글 입력
|
557
|
-
element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
|
558
|
-
@driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
|
559
|
-
sleep(1)
|
560
|
-
if option['ChatGPT사용'] == 'true'
|
561
|
-
pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
|
562
|
-
sleep(1)
|
563
525
|
|
564
|
-
puts "ChatGPT로 댓글을 만드는 중입니다."
|
565
|
-
@api_key = api_key
|
566
|
-
url = 'https://api.openai.com/v1/chat/completions'
|
567
|
-
headers = {
|
568
|
-
'Content-Type' => 'application/json',
|
569
|
-
'Authorization' => 'Bearer ' + @api_key
|
570
|
-
}
|
571
|
-
data = {
|
572
|
-
'model' => 'gpt-3.5-turbo',
|
573
|
-
'messages' => [
|
574
|
-
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
575
|
-
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
576
|
-
]
|
577
|
-
}
|
578
526
|
|
527
|
+
if option['re_coment'] == 'true' # 대 댓글 작업때
|
528
|
+
if @data['포스트설정']['전체대댓글'].checked?
|
579
529
|
begin
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
530
|
+
comment_items = @driver.find_elements(:css, 'li.CommentItem')
|
531
|
+
original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
|
532
|
+
|
533
|
+
original_comments.each_with_index do |item, index|
|
534
|
+
|
535
|
+
begin
|
536
|
+
|
537
|
+
if @data['포스트설정']['순서사용2'].checked?
|
538
|
+
@content_soon ||= 0 # 초기 한 번만 0으로 세팅
|
539
|
+
|
540
|
+
if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
|
541
|
+
content = ''
|
542
|
+
else
|
543
|
+
if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
|
544
|
+
content = @data['내용설정']['내용'].sample[2]
|
545
|
+
else
|
546
|
+
content = @data['내용설정']['내용'][@content_soon][2]
|
547
|
+
@content_soon += 1
|
548
|
+
@content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
|
549
|
+
end
|
550
|
+
end
|
551
|
+
else
|
552
|
+
end
|
553
|
+
|
554
|
+
# 디엠 자동 변경이 체크된 경우 content를 변환
|
555
|
+
if @data['포스트설정']['내용자동변경'].checked?
|
556
|
+
change_memory = {}
|
557
|
+
@data['포스트설정']['내용자동변경값'].each do |key, v|
|
558
|
+
change_memory[key] = v.sample
|
559
|
+
end
|
560
|
+
@data['포스트설정']['내용자동변경값'].each do |key, _|
|
561
|
+
if content.include?(key)
|
562
|
+
content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
|
563
|
+
else
|
564
|
+
end
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
if option['ChatGPT사용'] == 'true'
|
569
|
+
pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
|
570
|
+
sleep(1)
|
571
|
+
|
572
|
+
puts "ChatGPT로 댓글을 만드는 중입니다."
|
573
|
+
@api_key = api_key
|
574
|
+
url = 'https://api.openai.com/v1/chat/completions'
|
575
|
+
headers = {
|
576
|
+
'Content-Type' => 'application/json',
|
577
|
+
'Authorization' => 'Bearer ' + @api_key
|
578
|
+
}
|
579
|
+
data = {
|
580
|
+
'model' => 'gpt-3.5-turbo',
|
581
|
+
'messages' => [
|
582
|
+
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
583
|
+
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
584
|
+
]
|
585
|
+
}
|
586
|
+
|
587
|
+
begin
|
588
|
+
req = HTTP.headers(headers).post(url, json: data)
|
589
|
+
puts "HTTP Status: #{req.status}" # 상태 코드 확인
|
590
|
+
response = JSON.parse(req.body.to_s)
|
591
|
+
puts "API Response: #{response}" # 전체 응답 출력
|
592
|
+
|
593
|
+
if req.status == 429
|
594
|
+
return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
|
595
|
+
end
|
596
|
+
|
597
|
+
# 응답 데이터에서 안전하게 값 추출
|
598
|
+
raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
|
599
|
+
content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
|
600
|
+
|
601
|
+
rescue => e
|
602
|
+
puts "Error: #{e.message}"
|
603
|
+
content = "오류가 발생했습니다."
|
604
|
+
end
|
605
|
+
else
|
606
|
+
end
|
607
|
+
|
608
|
+
reply_button = item.find_element(:css, 'a.comment_info_button')
|
609
|
+
puts "대댓글 #{index + 1} 작성 중..."
|
610
|
+
reply_button.click
|
611
|
+
sleep(1.5)
|
612
|
+
|
613
|
+
textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
|
614
|
+
textarea.send_keys(content)
|
615
|
+
sleep(1)
|
616
|
+
|
617
|
+
if option['이모티콘자동삽입'] == 'true'
|
618
|
+
puts "이모티콘 자동 삽입 옵션 진행!!".cyan
|
619
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
620
|
+
reply_comments.each_with_index do |item, index|
|
621
|
+
begin
|
622
|
+
|
623
|
+
|
624
|
+
# 해당 대댓글 내부의 이모티콘 버튼 찾기
|
625
|
+
sticker_button = item.find_element(:css, 'a.button_sticker')
|
626
|
+
sticker_button.click
|
627
|
+
sleep(1)
|
628
|
+
|
629
|
+
rescue
|
630
|
+
end
|
631
|
+
end
|
632
|
+
begin
|
633
|
+
# 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
|
634
|
+
sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
|
635
|
+
|
636
|
+
# 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
|
637
|
+
random_li = sticker_list_elements.sample
|
638
|
+
random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
|
639
|
+
random_button.click
|
640
|
+
|
641
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
642
|
+
|
643
|
+
# 첫 번째 클릭한 <li> 내에서 버튼을 찾기
|
644
|
+
inner_buttons = random_li.find_elements(:tag_name, 'button')
|
645
|
+
|
646
|
+
# 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
|
647
|
+
random_button_in_li = inner_buttons.sample
|
648
|
+
sleep(1)
|
649
|
+
random_button_in_li.click
|
650
|
+
|
651
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
652
|
+
|
653
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
|
654
|
+
#puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
|
655
|
+
# 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
|
656
|
+
# 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
|
657
|
+
|
658
|
+
rescue => e
|
659
|
+
puts "기타 오류로 인해 이모티콘 삽입 안됨"
|
660
|
+
# 기타 오류 처리
|
661
|
+
# 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
|
662
|
+
end
|
663
|
+
else
|
664
|
+
puts "이모티콘 자동 삽입 옵션이 비활성화됨."
|
665
|
+
end
|
666
|
+
|
667
|
+
# 이미지 자동 삽입
|
668
|
+
if option['이미지자동삽입'] == 'true'
|
669
|
+
puts "이미지 자동 상입 옵션 진행!!".cyan
|
670
|
+
|
671
|
+
# 아이프레임 요소가 나타날 때까지 기다립니다.
|
672
|
+
@image = image
|
673
|
+
image_path = image
|
674
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
675
|
+
|
676
|
+
reply_comments.each_with_index do |item, index|
|
677
|
+
begin
|
678
|
+
|
679
|
+
|
680
|
+
# 해당 대댓글 내부에서 for="attach2"인 라벨 클릭
|
681
|
+
attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
|
682
|
+
attach_button.click
|
683
|
+
sleep(1)
|
684
|
+
|
685
|
+
rescue
|
686
|
+
end
|
687
|
+
end
|
688
|
+
key_stroke('escape')
|
689
|
+
# 파일 경로 자동 입력
|
690
|
+
file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
|
691
|
+
|
692
|
+
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
693
|
+
file_input.send_keys(image_path)
|
694
|
+
sleep(2)
|
695
|
+
|
696
|
+
else
|
697
|
+
end
|
698
|
+
|
699
|
+
register_btn = @driver.find_element(:css, 'a.button.btn_register')
|
700
|
+
register_btn.click
|
701
|
+
sleep(2)
|
702
|
+
|
703
|
+
rescue => e
|
704
|
+
puts "대댓글 #{index + 1} 처리 중 오류 발생: #{e.message}"
|
705
|
+
next
|
706
|
+
end
|
707
|
+
end
|
593
708
|
rescue => e
|
594
|
-
|
595
|
-
answer = "오류가 발생했습니다."
|
709
|
+
puts "전체대댓글 처리 중 예외 발생: #{e.message}"
|
596
710
|
end
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
711
|
+
|
712
|
+
elsif @data['포스트설정']['지정대댓글'].checked?
|
713
|
+
targets = @data['포스트설정']['nik_or_number'].text.to_s.force_encoding('utf-8').split(',').map(&:strip)
|
714
|
+
targets.each do |target|
|
715
|
+
if target.match?(/^\d+$/)
|
716
|
+
index = target.to_i - 1
|
717
|
+
comment_items = @driver.find_elements(:css, 'li.CommentItem')
|
718
|
+
original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
|
719
|
+
|
720
|
+
if original_comments[index]
|
721
|
+
begin
|
722
|
+
|
723
|
+
if @data['포스트설정']['순서사용2'].checked?
|
724
|
+
@content_soon ||= 0 # 초기 한 번만 0으로 세팅
|
725
|
+
|
726
|
+
if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
|
727
|
+
content = ''
|
728
|
+
else
|
729
|
+
if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
|
730
|
+
content = @data['내용설정']['내용'].sample[2]
|
731
|
+
else
|
732
|
+
content = @data['내용설정']['내용'][@content_soon][2]
|
733
|
+
@content_soon += 1
|
734
|
+
@content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
|
735
|
+
end
|
736
|
+
end
|
737
|
+
else
|
738
|
+
end
|
739
|
+
|
740
|
+
# 디엠 자동 변경이 체크된 경우 content를 변환
|
741
|
+
if @data['포스트설정']['내용자동변경'].checked?
|
742
|
+
change_memory = {}
|
743
|
+
@data['포스트설정']['내용자동변경값'].each do |key, v|
|
744
|
+
change_memory[key] = v.sample
|
745
|
+
end
|
746
|
+
@data['포스트설정']['내용자동변경값'].each do |key, _|
|
747
|
+
if content.include?(key)
|
748
|
+
content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
|
749
|
+
else
|
750
|
+
end
|
751
|
+
end
|
752
|
+
end
|
753
|
+
|
754
|
+
if option['ChatGPT사용'] == 'true'
|
755
|
+
pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
|
756
|
+
sleep(1)
|
757
|
+
|
758
|
+
puts "ChatGPT로 댓글을 만드는 중입니다."
|
759
|
+
@api_key = api_key
|
760
|
+
url = 'https://api.openai.com/v1/chat/completions'
|
761
|
+
headers = {
|
762
|
+
'Content-Type' => 'application/json',
|
763
|
+
'Authorization' => 'Bearer ' + @api_key
|
764
|
+
}
|
765
|
+
data = {
|
766
|
+
'model' => 'gpt-3.5-turbo',
|
767
|
+
'messages' => [
|
768
|
+
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
769
|
+
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
770
|
+
]
|
771
|
+
}
|
772
|
+
|
773
|
+
begin
|
774
|
+
req = HTTP.headers(headers).post(url, json: data)
|
775
|
+
puts "HTTP Status: #{req.status}" # 상태 코드 확인
|
776
|
+
response = JSON.parse(req.body.to_s)
|
777
|
+
puts "API Response: #{response}" # 전체 응답 출력
|
778
|
+
|
779
|
+
if req.status == 429
|
780
|
+
return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
|
781
|
+
end
|
782
|
+
|
783
|
+
# 응답 데이터에서 안전하게 값 추출
|
784
|
+
raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
|
785
|
+
content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
|
786
|
+
|
787
|
+
rescue => e
|
788
|
+
puts "Error: #{e.message}"
|
789
|
+
content = "오류가 발생했습니다."
|
790
|
+
end
|
791
|
+
else
|
792
|
+
end
|
793
|
+
|
794
|
+
puts "#{index + 1}번째 댓글에 대댓글 작성 시작"
|
795
|
+
reply_button = original_comments[index].find_element(:css, 'a.comment_info_button')
|
796
|
+
reply_button.click
|
797
|
+
sleep(1.5)
|
798
|
+
|
799
|
+
textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
|
800
|
+
textarea.send_keys(content)
|
801
|
+
sleep(1)
|
802
|
+
|
803
|
+
if option['이모티콘자동삽입'] == 'true'
|
804
|
+
puts "이모티콘 자동 삽입 옵션 진행!!".cyan
|
805
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
806
|
+
reply_comments.each_with_index do |item, index|
|
807
|
+
begin
|
808
|
+
|
809
|
+
|
810
|
+
# 해당 대댓글 내부의 이모티콘 버튼 찾기
|
811
|
+
sticker_button = item.find_element(:css, 'a.button_sticker')
|
812
|
+
sticker_button.click
|
813
|
+
sleep(1)
|
814
|
+
|
815
|
+
rescue
|
816
|
+
end
|
817
|
+
end
|
818
|
+
|
819
|
+
begin
|
820
|
+
# 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
|
821
|
+
sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
|
822
|
+
|
823
|
+
# 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
|
824
|
+
random_li = sticker_list_elements.sample
|
825
|
+
random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
|
826
|
+
random_button.click
|
827
|
+
|
828
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
829
|
+
|
830
|
+
# 첫 번째 클릭한 <li> 내에서 버튼을 찾기
|
831
|
+
inner_buttons = random_li.find_elements(:tag_name, 'button')
|
832
|
+
|
833
|
+
# 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
|
834
|
+
random_button_in_li = inner_buttons.sample
|
835
|
+
sleep(1)
|
836
|
+
random_button_in_li.click
|
837
|
+
|
838
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
839
|
+
|
840
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
|
841
|
+
#puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
|
842
|
+
# 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
|
843
|
+
# 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
|
844
|
+
|
845
|
+
rescue => e
|
846
|
+
puts "기타 오류로 인해 이모티콘 삽입 안됨"
|
847
|
+
# 기타 오류 처리
|
848
|
+
# 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
|
849
|
+
end
|
850
|
+
else
|
851
|
+
puts "이모티콘 자동 삽입 옵션이 비활성화됨."
|
852
|
+
end
|
853
|
+
|
854
|
+
# 이미지 자동 삽입
|
855
|
+
if option['이미지자동삽입'] == 'true'
|
856
|
+
puts "이미지 자동 상입 옵션 진행!!".cyan
|
857
|
+
|
858
|
+
# 아이프레임 요소가 나타날 때까지 기다립니다.
|
859
|
+
@image = image
|
860
|
+
image_path = image
|
861
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
862
|
+
|
863
|
+
reply_comments.each_with_index do |item, index|
|
864
|
+
begin
|
865
|
+
|
866
|
+
|
867
|
+
# 해당 대댓글 내부에서 for="attach2"인 라벨 클릭
|
868
|
+
attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
|
869
|
+
attach_button.click
|
870
|
+
sleep(1)
|
871
|
+
|
872
|
+
rescue
|
873
|
+
end
|
874
|
+
end
|
875
|
+
key_stroke('escape')
|
876
|
+
# 파일 경로 자동 입력
|
877
|
+
file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
|
878
|
+
|
879
|
+
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
880
|
+
file_input.send_keys(image_path)
|
881
|
+
sleep(2)
|
882
|
+
|
883
|
+
else
|
884
|
+
end
|
885
|
+
|
886
|
+
register_btn = @driver.find_element(:css, 'a.button.btn_register')
|
887
|
+
register_btn.click
|
888
|
+
sleep(2)
|
889
|
+
|
890
|
+
puts "#{index + 1}번째 댓글에 대댓글 작성 완료"
|
891
|
+
rescue => e
|
892
|
+
puts "댓글 인덱스 #{index + 1} 처리 중 오류 발생: #{e.message}"
|
893
|
+
end
|
894
|
+
else
|
895
|
+
puts "해당 인덱스(#{index + 1})의 답글쓰기 버튼이 없습니다."
|
896
|
+
end
|
897
|
+
|
898
|
+
else # 닉네임으로 찾기
|
899
|
+
comment_items = @driver.find_elements(:css, 'li.CommentItem')
|
900
|
+
original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
|
901
|
+
|
902
|
+
matched = false
|
903
|
+
last_matched_item = nil # 마지막에 닉네임이 일치한 댓글 저장
|
904
|
+
|
905
|
+
original_comments.each_with_index do |item, idx|
|
906
|
+
begin
|
907
|
+
nickname_element = item.find_element(:css, 'a.comment_nickname')
|
908
|
+
nickname = nickname_element.text.strip
|
909
|
+
|
910
|
+
if nickname.include?(target)
|
911
|
+
puts "#{target} 닉네임이 포함된 댓글 발견 (#{idx + 1}번째)"
|
912
|
+
last_matched_item = item # 매번 갱신 → 마지막에 발견된 걸 저장
|
913
|
+
end
|
914
|
+
rescue => e
|
915
|
+
puts "닉네임 검사 중 오류 발생: #{e.message}"
|
916
|
+
next
|
917
|
+
end
|
918
|
+
end
|
919
|
+
|
920
|
+
# 루프 끝난 뒤 마지막 댓글에만 작업 실행
|
921
|
+
if last_matched_item
|
922
|
+
begin
|
923
|
+
|
924
|
+
if @data['포스트설정']['순서사용2'].checked?
|
925
|
+
@content_soon ||= 0 # 초기 한 번만 0으로 세팅
|
926
|
+
|
927
|
+
if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
|
928
|
+
content = ''
|
929
|
+
else
|
930
|
+
if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
|
931
|
+
content = @data['내용설정']['내용'].sample[2]
|
932
|
+
else
|
933
|
+
content = @data['내용설정']['내용'][@content_soon][2]
|
934
|
+
@content_soon += 1
|
935
|
+
@content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
|
936
|
+
end
|
937
|
+
end
|
938
|
+
else
|
939
|
+
end
|
940
|
+
|
941
|
+
# 디엠 자동 변경이 체크된 경우 content를 변환
|
942
|
+
if @data['포스트설정']['내용자동변경'].checked?
|
943
|
+
change_memory = {}
|
944
|
+
@data['포스트설정']['내용자동변경값'].each do |key, v|
|
945
|
+
change_memory[key] = v.sample
|
946
|
+
end
|
947
|
+
@data['포스트설정']['내용자동변경값'].each do |key, _|
|
948
|
+
if content.include?(key)
|
949
|
+
content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
|
950
|
+
else
|
951
|
+
end
|
952
|
+
end
|
953
|
+
end
|
954
|
+
|
955
|
+
if option['ChatGPT사용'] == 'true'
|
956
|
+
pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
|
957
|
+
sleep(1)
|
958
|
+
|
959
|
+
puts "ChatGPT로 댓글을 만드는 중입니다."
|
960
|
+
@api_key = api_key
|
961
|
+
url = 'https://api.openai.com/v1/chat/completions'
|
962
|
+
headers = {
|
963
|
+
'Content-Type' => 'application/json',
|
964
|
+
'Authorization' => 'Bearer ' + @api_key
|
965
|
+
}
|
966
|
+
data = {
|
967
|
+
'model' => 'gpt-3.5-turbo',
|
968
|
+
'messages' => [
|
969
|
+
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
970
|
+
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
971
|
+
]
|
972
|
+
}
|
973
|
+
|
974
|
+
begin
|
975
|
+
req = HTTP.headers(headers).post(url, json: data)
|
976
|
+
puts "HTTP Status: #{req.status}" # 상태 코드 확인
|
977
|
+
response = JSON.parse(req.body.to_s)
|
978
|
+
puts "API Response: #{response}" # 전체 응답 출력
|
979
|
+
|
980
|
+
if req.status == 429
|
981
|
+
return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
|
982
|
+
end
|
983
|
+
|
984
|
+
# 응답 데이터에서 안전하게 값 추출
|
985
|
+
raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
|
986
|
+
content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
|
987
|
+
|
988
|
+
rescue => e
|
989
|
+
puts "Error: #{e.message}"
|
990
|
+
content = "오류가 발생했습니다."
|
991
|
+
end
|
992
|
+
else
|
993
|
+
end
|
994
|
+
|
995
|
+
reply_button = last_matched_item.find_element(:css, 'a.comment_info_button')
|
996
|
+
reply_button.click
|
997
|
+
sleep(1.5)
|
998
|
+
|
999
|
+
textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
|
1000
|
+
textarea.send_keys(content)
|
1001
|
+
sleep(1)
|
1002
|
+
|
1003
|
+
if option['이모티콘자동삽입'] == 'true'
|
1004
|
+
puts "이모티콘 자동 삽입 옵션 진행!!".cyan
|
1005
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
1006
|
+
reply_comments.each_with_index do |item, index|
|
1007
|
+
begin
|
1008
|
+
|
1009
|
+
sticker_button = item.find_element(:css, 'a.button_sticker')
|
1010
|
+
sticker_button.click
|
1011
|
+
sleep(1)
|
1012
|
+
rescue
|
1013
|
+
end
|
1014
|
+
end
|
1015
|
+
begin
|
1016
|
+
sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
|
1017
|
+
random_li = sticker_list_elements.sample
|
1018
|
+
random_button = random_li.find_element(:tag_name, 'button')
|
1019
|
+
random_button.click
|
1020
|
+
sleep(1)
|
1021
|
+
inner_buttons = random_li.find_elements(:tag_name, 'button')
|
1022
|
+
random_button_in_li = inner_buttons.sample
|
1023
|
+
sleep(1)
|
1024
|
+
random_button_in_li.click
|
1025
|
+
sleep(1)
|
1026
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError
|
1027
|
+
rescue => e
|
1028
|
+
puts "기타 오류로 인해 이모티콘 삽입 안됨"
|
1029
|
+
end
|
1030
|
+
else
|
1031
|
+
puts "이모티콘 자동 삽입 옵션이 비활성화됨."
|
1032
|
+
end
|
1033
|
+
|
1034
|
+
if option['이미지자동삽입'] == 'true'
|
1035
|
+
puts "이미지 자동 삽입 옵션 진행!!".cyan
|
1036
|
+
@image = image
|
1037
|
+
image_path = image
|
1038
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
1039
|
+
reply_comments.each_with_index do |item, index|
|
1040
|
+
begin
|
1041
|
+
|
1042
|
+
attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
|
1043
|
+
attach_button.click
|
1044
|
+
sleep(1)
|
1045
|
+
rescue
|
1046
|
+
end
|
1047
|
+
end
|
1048
|
+
key_stroke('escape')
|
1049
|
+
file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
|
1050
|
+
file_input.send_keys(image_path)
|
1051
|
+
sleep(2)
|
1052
|
+
end
|
1053
|
+
|
1054
|
+
register_btn = @driver.find_element(:css, 'a.button.btn_register')
|
1055
|
+
register_btn.click
|
1056
|
+
sleep(2)
|
1057
|
+
|
1058
|
+
matched = true
|
1059
|
+
rescue => e
|
1060
|
+
puts "대댓글 등록 중 오류 발생: #{e.message}"
|
1061
|
+
end
|
1062
|
+
end
|
1063
|
+
|
1064
|
+
puts "닉네임 '#{target}'을 포함한 댓글을 찾지 못했습니다." unless matched
|
1065
|
+
|
1066
|
+
end
|
607
1067
|
end
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
1068
|
+
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
elsif option['re_coment'] == 'false' # 대 댓글 아닐때
|
1072
|
+
if @data['포스트설정']['순서사용2'].checked?
|
1073
|
+
@content_soon ||= 0 # 초기 한 번만 0으로 세팅
|
1074
|
+
|
1075
|
+
if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
|
1076
|
+
content = ''
|
1077
|
+
else
|
1078
|
+
if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
|
1079
|
+
content = @data['내용설정']['내용'].sample[2]
|
1080
|
+
else
|
1081
|
+
content = @data['내용설정']['내용'][@content_soon][2]
|
1082
|
+
@content_soon += 1
|
1083
|
+
@content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
|
1084
|
+
end
|
1085
|
+
end
|
1086
|
+
else
|
1087
|
+
end
|
1088
|
+
|
1089
|
+
# 디엠 자동 변경이 체크된 경우 content를 변환
|
1090
|
+
if @data['포스트설정']['내용자동변경'].checked?
|
1091
|
+
change_memory = {}
|
1092
|
+
@data['포스트설정']['내용자동변경값'].each do |key, v|
|
1093
|
+
change_memory[key] = v.sample
|
1094
|
+
end
|
1095
|
+
@data['포스트설정']['내용자동변경값'].each do |key, _|
|
1096
|
+
if content.include?(key)
|
1097
|
+
content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
|
1098
|
+
else
|
1099
|
+
end
|
1100
|
+
end
|
1101
|
+
end
|
1102
|
+
|
1103
|
+
if option['ChatGPT사용'] == 'true'
|
1104
|
+
pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
|
1105
|
+
sleep(1)
|
1106
|
+
|
1107
|
+
puts "ChatGPT로 댓글을 만드는 중입니다."
|
1108
|
+
@api_key = api_key
|
1109
|
+
url = 'https://api.openai.com/v1/chat/completions'
|
1110
|
+
headers = {
|
1111
|
+
'Content-Type' => 'application/json',
|
1112
|
+
'Authorization' => 'Bearer ' + @api_key
|
1113
|
+
}
|
1114
|
+
data = {
|
1115
|
+
'model' => 'gpt-3.5-turbo',
|
1116
|
+
'messages' => [
|
1117
|
+
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
1118
|
+
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
1119
|
+
]
|
1120
|
+
}
|
1121
|
+
|
1122
|
+
begin
|
1123
|
+
req = HTTP.headers(headers).post(url, json: data)
|
1124
|
+
puts "HTTP Status: #{req.status}" # 상태 코드 확인
|
1125
|
+
response = JSON.parse(req.body.to_s)
|
1126
|
+
puts "API Response: #{response}" # 전체 응답 출력
|
1127
|
+
|
1128
|
+
if req.status == 429
|
1129
|
+
return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
|
1130
|
+
end
|
1131
|
+
|
1132
|
+
# 응답 데이터에서 안전하게 값 추출
|
1133
|
+
raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
|
1134
|
+
content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
|
1135
|
+
|
1136
|
+
rescue => e
|
1137
|
+
puts "Error: #{e.message}"
|
1138
|
+
content = "오류가 발생했습니다."
|
1139
|
+
end
|
1140
|
+
else
|
1141
|
+
end
|
1142
|
+
|
1143
|
+
wait = Selenium::WebDriver::Wait.new(timeout: 10)
|
1144
|
+
wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
|
1145
|
+
|
1146
|
+
element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
|
1147
|
+
@driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)
|
616
1148
|
sleep(1)
|
617
|
-
|
618
|
-
|
619
|
-
# 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
|
620
|
-
sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
|
621
|
-
|
622
|
-
# 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
|
623
|
-
random_li = sticker_list_elements.sample
|
624
|
-
random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
|
625
|
-
random_button.click
|
626
|
-
|
627
|
-
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
628
|
-
|
629
|
-
# 첫 번째 클릭한 <li> 내에서 버튼을 찾기
|
630
|
-
inner_buttons = random_li.find_elements(:tag_name, 'button')
|
631
|
-
|
632
|
-
# 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
|
633
|
-
random_button_in_li = inner_buttons.sample
|
1149
|
+
|
1150
|
+
element.send_keys(content)
|
634
1151
|
sleep(1)
|
635
|
-
|
636
|
-
|
637
|
-
|
1152
|
+
|
1153
|
+
# 이모티콘 자동 삽입
|
1154
|
+
if option['이모티콘자동삽입'] == 'true'
|
1155
|
+
puts "이모티콘 자동 삽입 옵션 진행!!".cyan
|
1156
|
+
|
1157
|
+
# '이모티콘' 버튼 클릭
|
1158
|
+
@driver.find_element(:xpath, '//*[@class="button_sticker"]').click
|
1159
|
+
sleep(1)
|
1160
|
+
|
1161
|
+
begin
|
1162
|
+
# 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
|
1163
|
+
sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
|
1164
|
+
|
1165
|
+
# 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
|
1166
|
+
random_li = sticker_list_elements.sample
|
1167
|
+
random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
|
1168
|
+
random_button.click
|
1169
|
+
|
1170
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
1171
|
+
|
1172
|
+
# 첫 번째 클릭한 <li> 내에서 버튼을 찾기
|
1173
|
+
inner_buttons = random_li.find_elements(:tag_name, 'button')
|
1174
|
+
|
1175
|
+
# 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
|
1176
|
+
random_button_in_li = inner_buttons.sample
|
1177
|
+
sleep(1)
|
1178
|
+
random_button_in_li.click
|
1179
|
+
|
1180
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
1181
|
+
|
1182
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
|
1183
|
+
#puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
|
1184
|
+
# 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
|
1185
|
+
# 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
|
1186
|
+
|
1187
|
+
rescue => e
|
1188
|
+
puts "기타 오류로 인해 이모티콘 삽입 안됨"
|
1189
|
+
# 기타 오류 처리
|
1190
|
+
# 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
|
1191
|
+
end
|
1192
|
+
else
|
1193
|
+
puts "이모티콘 자동 삽입 옵션이 비활성화됨."
|
1194
|
+
end
|
1195
|
+
|
1196
|
+
# 이미지 자동 삽입
|
1197
|
+
if option['이미지자동삽입'] == 'true'
|
1198
|
+
puts "이미지 자동 상입 옵션 진행!!".cyan
|
1199
|
+
|
1200
|
+
# 아이프레임 요소가 나타날 때까지 기다립니다.
|
1201
|
+
@image = image
|
1202
|
+
image_path = image
|
638
1203
|
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
1204
|
+
@driver.find_element(:xpath, '//*[@for="attach2"]').click
|
1205
|
+
sleep(1)
|
1206
|
+
key_stroke('escape')
|
1207
|
+
# 파일 경로 자동 입력
|
1208
|
+
file_input = @driver.find_element(:xpath, '//*[@class="button_file"]')
|
1209
|
+
|
1210
|
+
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
1211
|
+
file_input.send_keys(image_path)
|
1212
|
+
sleep(2)
|
643
1213
|
|
644
|
-
|
645
|
-
puts "기타 오류로 인해 이모티콘 삽입 안됨"
|
646
|
-
# 기타 오류 처리
|
647
|
-
# 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
|
1214
|
+
else
|
648
1215
|
end
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
puts "이미지 자동 상입 옵션 진행!!".cyan
|
656
|
-
|
657
|
-
# 아이프레임 요소가 나타날 때까지 기다립니다.
|
658
|
-
@image = image
|
659
|
-
image_path = image
|
660
|
-
|
661
|
-
@driver.find_element(:xpath, '//*[@for="attach2"]').click
|
662
|
-
sleep(1)
|
663
|
-
key_stroke('escape')
|
664
|
-
# 파일 경로 자동 입력
|
665
|
-
file_input = @driver.find_element(:xpath, '//*[@id="attach2"]')
|
666
|
-
|
667
|
-
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
668
|
-
file_input.send_keys(image_path)
|
669
|
-
sleep(2)
|
670
|
-
|
671
|
-
else
|
1216
|
+
|
1217
|
+
|
1218
|
+
wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
|
1219
|
+
@driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
|
1220
|
+
puts "#{board_url} [댓글 작성 완료 !!]".cyan
|
1221
|
+
sleep(2)
|
672
1222
|
end
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
puts "#{board_url} [댓글 작성 완료 !!]".cyan
|
677
|
-
|
678
|
-
sleep(2)
|
1223
|
+
|
1224
|
+
|
1225
|
+
|
679
1226
|
begin
|
680
1227
|
@driver.switch_to.alert
|
681
1228
|
sleep(1)
|
@@ -717,7 +1264,7 @@ class Naver
|
|
717
1264
|
puts '-[√] 로그 파일 생성 완료.......'.yellow
|
718
1265
|
end
|
719
1266
|
end
|
720
|
-
|
1267
|
+
|
721
1268
|
@driver.switch_to.default_content() # 아이프레임 해제
|
722
1269
|
def sleep_with_progress(sleep_delay)
|
723
1270
|
print "[설정 딜레이 진행 중] "
|
@@ -736,172 +1283,713 @@ class Naver
|
|
736
1283
|
rescue => e
|
737
1284
|
puts "Error: #{e.message}"
|
738
1285
|
end
|
739
|
-
|
1286
|
+
end
|
740
1287
|
else
|
741
1288
|
end
|
742
1289
|
|
743
1290
|
################################################################################ 설정게시글사용 ################################################################################
|
744
1291
|
|
745
1292
|
if option['설정게시글사용'] == 'true'
|
746
|
-
|
1293
|
+
puts "게시판 list 기반으로 댓글 작업 옵션 진행!!".cyan
|
747
1294
|
|
748
1295
|
@driver.get(board_url) # 해당 URL로 이동
|
749
1296
|
begin
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
1297
|
+
# 아이프레임 요소가 나타날 때까지 기다립니다.
|
1298
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
|
1299
|
+
wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
|
1300
|
+
sleep(1)
|
1301
|
+
@driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
|
755
1302
|
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
1303
|
+
|
1304
|
+
if option['좋아요'] == 'true'
|
1305
|
+
puts "좋아요 클릭 옵션 진행!!".cyan
|
1306
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
|
1307
|
+
wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon"]') }
|
1308
|
+
|
1309
|
+
# 댓글 입력
|
1310
|
+
element = @driver.find_element(:xpath, '//*[@class="u_ico _icon"]')
|
1311
|
+
@driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
|
1312
|
+
sleep(1)
|
1313
|
+
|
1314
|
+
# 좋아요 버튼을 찾기
|
1315
|
+
like_button = @driver.find_element(:xpath, '//div[@class="ReactionLikeIt u_likeit_list_module _cafeReactionModule"]//a[@role="button"]')
|
1316
|
+
|
1317
|
+
# aria-pressed 속성 값 확인
|
1318
|
+
aria_pressed = like_button.attribute('aria-pressed')
|
1319
|
+
|
1320
|
+
if aria_pressed == 'true'
|
1321
|
+
# 이미 좋아요를 누른 상태일 경우
|
1322
|
+
|
1323
|
+
else
|
1324
|
+
# 좋아요를 아직 누르지 않은 상태일 경우 클릭
|
1325
|
+
@driver.find_element(:xpath, '//*[@class="u_ico _icon"]').click
|
1326
|
+
sleep(2)
|
1327
|
+
end
|
763
1328
|
else
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
1329
|
+
end
|
1330
|
+
|
1331
|
+
|
1332
|
+
|
1333
|
+
if option['re_coment'] == 'true' # 대 댓글 작업때
|
1334
|
+
if @data['포스트설정']['전체대댓글'].checked?
|
1335
|
+
begin
|
1336
|
+
comment_items = @driver.find_elements(:css, 'li.CommentItem')
|
1337
|
+
original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
|
1338
|
+
|
1339
|
+
original_comments.each_with_index do |item, index|
|
1340
|
+
|
1341
|
+
begin
|
1342
|
+
|
1343
|
+
if @data['포스트설정']['순서사용2'].checked?
|
1344
|
+
@content_soon ||= 0 # 초기 한 번만 0으로 세팅
|
1345
|
+
|
1346
|
+
if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
|
1347
|
+
content = ''
|
1348
|
+
else
|
1349
|
+
if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
|
1350
|
+
content = @data['내용설정']['내용'].sample[2]
|
1351
|
+
else
|
1352
|
+
content = @data['내용설정']['내용'][@content_soon][2]
|
1353
|
+
@content_soon += 1
|
1354
|
+
@content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
|
1355
|
+
end
|
1356
|
+
end
|
1357
|
+
else
|
1358
|
+
end
|
1359
|
+
|
1360
|
+
# 디엠 자동 변경이 체크된 경우 content를 변환
|
1361
|
+
if @data['포스트설정']['내용자동변경'].checked?
|
1362
|
+
change_memory = {}
|
1363
|
+
@data['포스트설정']['내용자동변경값'].each do |key, v|
|
1364
|
+
change_memory[key] = v.sample
|
1365
|
+
end
|
1366
|
+
@data['포스트설정']['내용자동변경값'].each do |key, _|
|
1367
|
+
if content.include?(key)
|
1368
|
+
content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
|
1369
|
+
else
|
1370
|
+
end
|
1371
|
+
end
|
1372
|
+
end
|
1373
|
+
|
1374
|
+
if option['ChatGPT사용'] == 'true'
|
1375
|
+
pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
|
1376
|
+
sleep(1)
|
1377
|
+
|
1378
|
+
puts "ChatGPT로 댓글을 만드는 중입니다."
|
1379
|
+
@api_key = api_key
|
1380
|
+
url = 'https://api.openai.com/v1/chat/completions'
|
1381
|
+
headers = {
|
1382
|
+
'Content-Type' => 'application/json',
|
1383
|
+
'Authorization' => 'Bearer ' + @api_key
|
1384
|
+
}
|
1385
|
+
data = {
|
1386
|
+
'model' => 'gpt-3.5-turbo',
|
1387
|
+
'messages' => [
|
1388
|
+
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
1389
|
+
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
1390
|
+
]
|
1391
|
+
}
|
1392
|
+
|
1393
|
+
begin
|
1394
|
+
req = HTTP.headers(headers).post(url, json: data)
|
1395
|
+
puts "HTTP Status: #{req.status}" # 상태 코드 확인
|
1396
|
+
response = JSON.parse(req.body.to_s)
|
1397
|
+
puts "API Response: #{response}" # 전체 응답 출력
|
1398
|
+
|
1399
|
+
if req.status == 429
|
1400
|
+
return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
|
1401
|
+
end
|
1402
|
+
|
1403
|
+
# 응답 데이터에서 안전하게 값 추출
|
1404
|
+
raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
|
1405
|
+
content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
|
1406
|
+
|
1407
|
+
rescue => e
|
1408
|
+
puts "Error: #{e.message}"
|
1409
|
+
content = "오류가 발생했습니다."
|
1410
|
+
end
|
1411
|
+
else
|
1412
|
+
end
|
1413
|
+
|
1414
|
+
reply_button = item.find_element(:css, 'a.comment_info_button')
|
1415
|
+
puts "대댓글 #{index + 1} 작성 중..."
|
1416
|
+
reply_button.click
|
1417
|
+
sleep(1.5)
|
1418
|
+
|
1419
|
+
textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
|
1420
|
+
textarea.send_keys(content)
|
1421
|
+
sleep(1)
|
1422
|
+
|
1423
|
+
if option['이모티콘자동삽입'] == 'true'
|
1424
|
+
puts "이모티콘 자동 삽입 옵션 진행!!".cyan
|
1425
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
1426
|
+
reply_comments.each_with_index do |item, index|
|
1427
|
+
begin
|
1428
|
+
|
1429
|
+
|
1430
|
+
# 해당 대댓글 내부의 이모티콘 버튼 찾기
|
1431
|
+
sticker_button = item.find_element(:css, 'a.button_sticker')
|
1432
|
+
sticker_button.click
|
1433
|
+
sleep(1)
|
1434
|
+
|
1435
|
+
rescue
|
1436
|
+
end
|
1437
|
+
end
|
1438
|
+
begin
|
1439
|
+
# 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
|
1440
|
+
sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
|
1441
|
+
|
1442
|
+
# 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
|
1443
|
+
random_li = sticker_list_elements.sample
|
1444
|
+
random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
|
1445
|
+
random_button.click
|
1446
|
+
|
1447
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
1448
|
+
|
1449
|
+
# 첫 번째 클릭한 <li> 내에서 버튼을 찾기
|
1450
|
+
inner_buttons = random_li.find_elements(:tag_name, 'button')
|
1451
|
+
|
1452
|
+
# 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
|
1453
|
+
random_button_in_li = inner_buttons.sample
|
1454
|
+
sleep(1)
|
1455
|
+
random_button_in_li.click
|
1456
|
+
|
1457
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
1458
|
+
|
1459
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
|
1460
|
+
#puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
|
1461
|
+
# 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
|
1462
|
+
# 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
|
1463
|
+
|
1464
|
+
rescue => e
|
1465
|
+
puts "기타 오류로 인해 이모티콘 삽입 안됨"
|
1466
|
+
# 기타 오류 처리
|
1467
|
+
# 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
|
1468
|
+
end
|
1469
|
+
else
|
1470
|
+
puts "이모티콘 자동 삽입 옵션이 비활성화됨."
|
1471
|
+
end
|
1472
|
+
|
1473
|
+
# 이미지 자동 삽입
|
1474
|
+
if option['이미지자동삽입'] == 'true'
|
1475
|
+
puts "이미지 자동 상입 옵션 진행!!".cyan
|
1476
|
+
|
1477
|
+
# 아이프레임 요소가 나타날 때까지 기다립니다.
|
1478
|
+
@image = image
|
1479
|
+
image_path = image
|
1480
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
1481
|
+
|
1482
|
+
reply_comments.each_with_index do |item, index|
|
1483
|
+
begin
|
1484
|
+
|
1485
|
+
|
1486
|
+
# 해당 대댓글 내부에서 for="attach2"인 라벨 클릭
|
1487
|
+
attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
|
1488
|
+
attach_button.click
|
1489
|
+
sleep(1)
|
1490
|
+
|
1491
|
+
rescue
|
1492
|
+
end
|
1493
|
+
end
|
1494
|
+
key_stroke('escape')
|
1495
|
+
# 파일 경로 자동 입력
|
1496
|
+
file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
|
1497
|
+
|
1498
|
+
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
1499
|
+
file_input.send_keys(image_path)
|
1500
|
+
sleep(2)
|
1501
|
+
|
1502
|
+
else
|
1503
|
+
end
|
1504
|
+
|
1505
|
+
register_btn = @driver.find_element(:css, 'a.button.btn_register')
|
1506
|
+
register_btn.click
|
1507
|
+
sleep(2)
|
1508
|
+
|
1509
|
+
rescue => e
|
1510
|
+
puts "대댓글 #{index + 1} 처리 중 오류 발생: #{e.message}"
|
1511
|
+
next
|
1512
|
+
end
|
1513
|
+
end
|
1514
|
+
rescue => e
|
1515
|
+
puts "전체대댓글 처리 중 예외 발생: #{e.message}"
|
775
1516
|
end
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
1517
|
+
|
1518
|
+
elsif @data['포스트설정']['지정대댓글'].checked?
|
1519
|
+
targets = @data['포스트설정']['nik_or_number'].text.to_s.force_encoding('utf-8').split(',').map(&:strip)
|
1520
|
+
targets.each do |target|
|
1521
|
+
if target.match?(/^\d+$/)
|
1522
|
+
index = target.to_i - 1
|
1523
|
+
comment_items = @driver.find_elements(:css, 'li.CommentItem')
|
1524
|
+
original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
|
1525
|
+
|
1526
|
+
if original_comments[index]
|
1527
|
+
begin
|
1528
|
+
|
1529
|
+
if @data['포스트설정']['순서사용2'].checked?
|
1530
|
+
@content_soon ||= 0 # 초기 한 번만 0으로 세팅
|
1531
|
+
|
1532
|
+
if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
|
1533
|
+
content = ''
|
1534
|
+
else
|
1535
|
+
if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
|
1536
|
+
content = @data['내용설정']['내용'].sample[2]
|
1537
|
+
else
|
1538
|
+
content = @data['내용설정']['내용'][@content_soon][2]
|
1539
|
+
@content_soon += 1
|
1540
|
+
@content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
|
1541
|
+
end
|
1542
|
+
end
|
1543
|
+
else
|
1544
|
+
end
|
1545
|
+
|
1546
|
+
# 디엠 자동 변경이 체크된 경우 content를 변환
|
1547
|
+
if @data['포스트설정']['내용자동변경'].checked?
|
1548
|
+
change_memory = {}
|
1549
|
+
@data['포스트설정']['내용자동변경값'].each do |key, v|
|
1550
|
+
change_memory[key] = v.sample
|
1551
|
+
end
|
1552
|
+
@data['포스트설정']['내용자동변경값'].each do |key, _|
|
1553
|
+
if content.include?(key)
|
1554
|
+
content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
|
1555
|
+
else
|
1556
|
+
end
|
1557
|
+
end
|
1558
|
+
end
|
1559
|
+
|
1560
|
+
if option['ChatGPT사용'] == 'true'
|
1561
|
+
pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
|
1562
|
+
sleep(1)
|
1563
|
+
|
1564
|
+
puts "ChatGPT로 댓글을 만드는 중입니다."
|
1565
|
+
@api_key = api_key
|
1566
|
+
url = 'https://api.openai.com/v1/chat/completions'
|
1567
|
+
headers = {
|
1568
|
+
'Content-Type' => 'application/json',
|
1569
|
+
'Authorization' => 'Bearer ' + @api_key
|
1570
|
+
}
|
1571
|
+
data = {
|
1572
|
+
'model' => 'gpt-3.5-turbo',
|
1573
|
+
'messages' => [
|
1574
|
+
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
1575
|
+
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
1576
|
+
]
|
1577
|
+
}
|
1578
|
+
|
1579
|
+
begin
|
1580
|
+
req = HTTP.headers(headers).post(url, json: data)
|
1581
|
+
puts "HTTP Status: #{req.status}" # 상태 코드 확인
|
1582
|
+
response = JSON.parse(req.body.to_s)
|
1583
|
+
puts "API Response: #{response}" # 전체 응답 출력
|
1584
|
+
|
1585
|
+
if req.status == 429
|
1586
|
+
return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
|
1587
|
+
end
|
1588
|
+
|
1589
|
+
# 응답 데이터에서 안전하게 값 추출
|
1590
|
+
raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
|
1591
|
+
content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
|
1592
|
+
|
1593
|
+
rescue => e
|
1594
|
+
puts "Error: #{e.message}"
|
1595
|
+
content = "오류가 발생했습니다."
|
1596
|
+
end
|
1597
|
+
else
|
1598
|
+
end
|
1599
|
+
|
1600
|
+
puts "#{index + 1}번째 댓글에 대댓글 작성 시작"
|
1601
|
+
reply_button = original_comments[index].find_element(:css, 'a.comment_info_button')
|
1602
|
+
reply_button.click
|
1603
|
+
sleep(1.5)
|
1604
|
+
|
1605
|
+
textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
|
1606
|
+
textarea.send_keys(content)
|
1607
|
+
sleep(1)
|
1608
|
+
|
1609
|
+
if option['이모티콘자동삽입'] == 'true'
|
1610
|
+
puts "이모티콘 자동 삽입 옵션 진행!!".cyan
|
1611
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
1612
|
+
reply_comments.each_with_index do |item, index|
|
1613
|
+
begin
|
1614
|
+
|
1615
|
+
|
1616
|
+
# 해당 대댓글 내부의 이모티콘 버튼 찾기
|
1617
|
+
sticker_button = item.find_element(:css, 'a.button_sticker')
|
1618
|
+
sticker_button.click
|
1619
|
+
sleep(1)
|
1620
|
+
|
1621
|
+
rescue
|
1622
|
+
end
|
1623
|
+
end
|
1624
|
+
|
1625
|
+
begin
|
1626
|
+
# 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
|
1627
|
+
sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
|
1628
|
+
|
1629
|
+
# 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
|
1630
|
+
random_li = sticker_list_elements.sample
|
1631
|
+
random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
|
1632
|
+
random_button.click
|
1633
|
+
|
1634
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
1635
|
+
|
1636
|
+
# 첫 번째 클릭한 <li> 내에서 버튼을 찾기
|
1637
|
+
inner_buttons = random_li.find_elements(:tag_name, 'button')
|
1638
|
+
|
1639
|
+
# 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
|
1640
|
+
random_button_in_li = inner_buttons.sample
|
1641
|
+
sleep(1)
|
1642
|
+
random_button_in_li.click
|
1643
|
+
|
1644
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
1645
|
+
|
1646
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
|
1647
|
+
#puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
|
1648
|
+
# 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
|
1649
|
+
# 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
|
1650
|
+
|
1651
|
+
rescue => e
|
1652
|
+
puts "기타 오류로 인해 이모티콘 삽입 안됨"
|
1653
|
+
# 기타 오류 처리
|
1654
|
+
# 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
|
1655
|
+
end
|
1656
|
+
else
|
1657
|
+
puts "이모티콘 자동 삽입 옵션이 비활성화됨."
|
1658
|
+
end
|
1659
|
+
|
1660
|
+
# 이미지 자동 삽입
|
1661
|
+
if option['이미지자동삽입'] == 'true'
|
1662
|
+
puts "이미지 자동 상입 옵션 진행!!".cyan
|
1663
|
+
|
1664
|
+
# 아이프레임 요소가 나타날 때까지 기다립니다.
|
1665
|
+
@image = image
|
1666
|
+
image_path = image
|
1667
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
1668
|
+
|
1669
|
+
reply_comments.each_with_index do |item, index|
|
1670
|
+
begin
|
1671
|
+
|
1672
|
+
|
1673
|
+
# 해당 대댓글 내부에서 for="attach2"인 라벨 클릭
|
1674
|
+
attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
|
1675
|
+
attach_button.click
|
1676
|
+
sleep(1)
|
1677
|
+
|
1678
|
+
rescue
|
1679
|
+
end
|
1680
|
+
end
|
1681
|
+
key_stroke('escape')
|
1682
|
+
# 파일 경로 자동 입력
|
1683
|
+
file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
|
1684
|
+
|
1685
|
+
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
1686
|
+
file_input.send_keys(image_path)
|
1687
|
+
sleep(2)
|
1688
|
+
|
1689
|
+
else
|
1690
|
+
end
|
1691
|
+
|
1692
|
+
register_btn = @driver.find_element(:css, 'a.button.btn_register')
|
1693
|
+
register_btn.click
|
1694
|
+
sleep(2)
|
1695
|
+
|
1696
|
+
puts "#{index + 1}번째 댓글에 대댓글 작성 완료"
|
1697
|
+
rescue => e
|
1698
|
+
puts "댓글 인덱스 #{index + 1} 처리 중 오류 발생: #{e.message}"
|
1699
|
+
end
|
1700
|
+
else
|
1701
|
+
puts "해당 인덱스(#{index + 1})의 답글쓰기 버튼이 없습니다."
|
1702
|
+
end
|
1703
|
+
|
1704
|
+
else # 닉네임으로 찾기
|
1705
|
+
comment_items = @driver.find_elements(:css, 'li.CommentItem')
|
1706
|
+
original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
|
1707
|
+
|
1708
|
+
matched = false
|
1709
|
+
last_matched_item = nil # 마지막에 닉네임이 일치한 댓글 저장
|
1710
|
+
|
1711
|
+
original_comments.each_with_index do |item, idx|
|
1712
|
+
begin
|
1713
|
+
nickname_element = item.find_element(:css, 'a.comment_nickname')
|
1714
|
+
nickname = nickname_element.text.strip
|
1715
|
+
|
1716
|
+
if nickname.include?(target)
|
1717
|
+
puts "#{target} 닉네임이 포함된 댓글 발견 (#{idx + 1}번째)"
|
1718
|
+
last_matched_item = item # 매번 갱신 → 마지막에 발견된 걸 저장
|
1719
|
+
end
|
1720
|
+
rescue => e
|
1721
|
+
puts "닉네임 검사 중 오류 발생: #{e.message}"
|
1722
|
+
next
|
1723
|
+
end
|
1724
|
+
end
|
1725
|
+
|
1726
|
+
# 루프 끝난 뒤 마지막 댓글에만 작업 실행
|
1727
|
+
if last_matched_item
|
1728
|
+
begin
|
1729
|
+
|
1730
|
+
if @data['포스트설정']['순서사용2'].checked?
|
1731
|
+
@content_soon ||= 0 # 초기 한 번만 0으로 세팅
|
1732
|
+
|
1733
|
+
if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
|
1734
|
+
content = ''
|
1735
|
+
else
|
1736
|
+
if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
|
1737
|
+
content = @data['내용설정']['내용'].sample[2]
|
1738
|
+
else
|
1739
|
+
content = @data['내용설정']['내용'][@content_soon][2]
|
1740
|
+
@content_soon += 1
|
1741
|
+
@content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
|
1742
|
+
end
|
1743
|
+
end
|
1744
|
+
else
|
1745
|
+
end
|
1746
|
+
|
1747
|
+
# 디엠 자동 변경이 체크된 경우 content를 변환
|
1748
|
+
if @data['포스트설정']['내용자동변경'].checked?
|
1749
|
+
change_memory = {}
|
1750
|
+
@data['포스트설정']['내용자동변경값'].each do |key, v|
|
1751
|
+
change_memory[key] = v.sample
|
1752
|
+
end
|
1753
|
+
@data['포스트설정']['내용자동변경값'].each do |key, _|
|
1754
|
+
if content.include?(key)
|
1755
|
+
content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
|
1756
|
+
else
|
1757
|
+
end
|
1758
|
+
end
|
1759
|
+
end
|
1760
|
+
|
1761
|
+
if option['ChatGPT사용'] == 'true'
|
1762
|
+
pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
|
1763
|
+
sleep(1)
|
1764
|
+
|
1765
|
+
puts "ChatGPT로 댓글을 만드는 중입니다."
|
1766
|
+
@api_key = api_key
|
1767
|
+
url = 'https://api.openai.com/v1/chat/completions'
|
1768
|
+
headers = {
|
1769
|
+
'Content-Type' => 'application/json',
|
1770
|
+
'Authorization' => 'Bearer ' + @api_key
|
1771
|
+
}
|
1772
|
+
data = {
|
1773
|
+
'model' => 'gpt-3.5-turbo',
|
1774
|
+
'messages' => [
|
1775
|
+
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
1776
|
+
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
1777
|
+
]
|
1778
|
+
}
|
1779
|
+
|
1780
|
+
begin
|
1781
|
+
req = HTTP.headers(headers).post(url, json: data)
|
1782
|
+
puts "HTTP Status: #{req.status}" # 상태 코드 확인
|
1783
|
+
response = JSON.parse(req.body.to_s)
|
1784
|
+
puts "API Response: #{response}" # 전체 응답 출력
|
1785
|
+
|
1786
|
+
if req.status == 429
|
1787
|
+
return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
|
1788
|
+
end
|
1789
|
+
|
1790
|
+
# 응답 데이터에서 안전하게 값 추출
|
1791
|
+
raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
|
1792
|
+
content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
|
1793
|
+
|
1794
|
+
rescue => e
|
1795
|
+
puts "Error: #{e.message}"
|
1796
|
+
content = "오류가 발생했습니다."
|
1797
|
+
end
|
1798
|
+
else
|
1799
|
+
end
|
1800
|
+
|
1801
|
+
reply_button = last_matched_item.find_element(:css, 'a.comment_info_button')
|
1802
|
+
reply_button.click
|
1803
|
+
sleep(1.5)
|
1804
|
+
|
1805
|
+
textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
|
1806
|
+
textarea.send_keys(content)
|
1807
|
+
sleep(1)
|
1808
|
+
|
1809
|
+
if option['이모티콘자동삽입'] == 'true'
|
1810
|
+
puts "이모티콘 자동 삽입 옵션 진행!!".cyan
|
1811
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
1812
|
+
reply_comments.each_with_index do |item, index|
|
1813
|
+
begin
|
1814
|
+
|
1815
|
+
sticker_button = item.find_element(:css, 'a.button_sticker')
|
1816
|
+
sticker_button.click
|
1817
|
+
sleep(1)
|
1818
|
+
rescue
|
1819
|
+
end
|
1820
|
+
end
|
1821
|
+
begin
|
1822
|
+
sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
|
1823
|
+
random_li = sticker_list_elements.sample
|
1824
|
+
random_button = random_li.find_element(:tag_name, 'button')
|
1825
|
+
random_button.click
|
1826
|
+
sleep(1)
|
1827
|
+
inner_buttons = random_li.find_elements(:tag_name, 'button')
|
1828
|
+
random_button_in_li = inner_buttons.sample
|
1829
|
+
sleep(1)
|
1830
|
+
random_button_in_li.click
|
1831
|
+
sleep(1)
|
1832
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError
|
1833
|
+
rescue => e
|
1834
|
+
puts "기타 오류로 인해 이모티콘 삽입 안됨"
|
1835
|
+
end
|
1836
|
+
else
|
1837
|
+
puts "이모티콘 자동 삽입 옵션이 비활성화됨."
|
1838
|
+
end
|
1839
|
+
|
1840
|
+
if option['이미지자동삽입'] == 'true'
|
1841
|
+
puts "이미지 자동 삽입 옵션 진행!!".cyan
|
1842
|
+
@image = image
|
1843
|
+
image_path = image
|
1844
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
1845
|
+
reply_comments.each_with_index do |item, index|
|
1846
|
+
begin
|
1847
|
+
|
1848
|
+
attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
|
1849
|
+
attach_button.click
|
1850
|
+
sleep(1)
|
1851
|
+
rescue
|
1852
|
+
end
|
1853
|
+
end
|
1854
|
+
key_stroke('escape')
|
1855
|
+
file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
|
1856
|
+
file_input.send_keys(image_path)
|
1857
|
+
sleep(2)
|
1858
|
+
end
|
1859
|
+
|
1860
|
+
register_btn = @driver.find_element(:css, 'a.button.btn_register')
|
1861
|
+
register_btn.click
|
1862
|
+
sleep(2)
|
1863
|
+
|
1864
|
+
matched = true
|
1865
|
+
rescue => e
|
1866
|
+
puts "대댓글 등록 중 오류 발생: #{e.message}"
|
1867
|
+
end
|
1868
|
+
end
|
1869
|
+
|
1870
|
+
puts "닉네임 '#{target}'을 포함한 댓글을 찾지 못했습니다." unless matched
|
1871
|
+
|
780
1872
|
end
|
781
1873
|
end
|
782
|
-
end
|
783
1874
|
|
1875
|
+
end
|
784
1876
|
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
1877
|
+
elsif option['re_coment'] == 'false' # 대 댓글 아닐때
|
1878
|
+
if @data['포스트설정']['순서사용2'].checked?
|
1879
|
+
@content_soon ||= 0 # 초기 한 번만 0으로 세팅
|
1880
|
+
|
1881
|
+
if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
|
1882
|
+
content = ''
|
1883
|
+
else
|
1884
|
+
if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
|
1885
|
+
content = @data['내용설정']['내용'].sample[2]
|
1886
|
+
else
|
1887
|
+
content = @data['내용설정']['내용'][@content_soon][2]
|
1888
|
+
@content_soon += 1
|
1889
|
+
@content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
|
1890
|
+
end
|
1891
|
+
end
|
1892
|
+
else
|
1893
|
+
end
|
1894
|
+
|
1895
|
+
# 디엠 자동 변경이 체크된 경우 content를 변환
|
1896
|
+
if @data['포스트설정']['내용자동변경'].checked?
|
1897
|
+
change_memory = {}
|
1898
|
+
@data['포스트설정']['내용자동변경값'].each do |key, v|
|
1899
|
+
change_memory[key] = v.sample
|
1900
|
+
end
|
1901
|
+
@data['포스트설정']['내용자동변경값'].each do |key, _|
|
1902
|
+
if content.include?(key)
|
1903
|
+
content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
|
1904
|
+
else
|
1905
|
+
end
|
1906
|
+
end
|
1907
|
+
end
|
1908
|
+
|
1909
|
+
if option['ChatGPT사용'] == 'true'
|
1910
|
+
pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
|
1911
|
+
sleep(1)
|
1912
|
+
|
1913
|
+
puts "ChatGPT로 댓글을 만드는 중입니다."
|
1914
|
+
@api_key = api_key
|
1915
|
+
url = 'https://api.openai.com/v1/chat/completions'
|
1916
|
+
headers = {
|
1917
|
+
'Content-Type' => 'application/json',
|
1918
|
+
'Authorization' => 'Bearer ' + @api_key
|
1919
|
+
}
|
1920
|
+
data = {
|
1921
|
+
'model' => 'gpt-3.5-turbo',
|
1922
|
+
'messages' => [
|
1923
|
+
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
1924
|
+
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
1925
|
+
]
|
1926
|
+
}
|
1927
|
+
|
1928
|
+
begin
|
1929
|
+
req = HTTP.headers(headers).post(url, json: data)
|
1930
|
+
puts "HTTP Status: #{req.status}" # 상태 코드 확인
|
1931
|
+
response = JSON.parse(req.body.to_s)
|
1932
|
+
puts "API Response: #{response}" # 전체 응답 출력
|
1933
|
+
|
1934
|
+
if req.status == 429
|
1935
|
+
return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
|
1936
|
+
end
|
1937
|
+
|
1938
|
+
# 응답 데이터에서 안전하게 값 추출
|
1939
|
+
raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
|
1940
|
+
content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
|
1941
|
+
|
1942
|
+
rescue => e
|
1943
|
+
puts "Error: #{e.message}"
|
1944
|
+
content = "오류가 발생했습니다."
|
1945
|
+
end
|
804
1946
|
else
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
end
|
809
|
-
else
|
810
|
-
end
|
811
|
-
|
812
|
-
|
813
|
-
begin
|
814
|
-
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
|
1947
|
+
end
|
1948
|
+
|
1949
|
+
wait = Selenium::WebDriver::Wait.new(timeout: 10)
|
815
1950
|
wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
|
816
|
-
|
817
|
-
# 댓글 입력
|
1951
|
+
|
818
1952
|
element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
|
819
|
-
@driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)
|
1953
|
+
@driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)
|
820
1954
|
sleep(1)
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
puts "ChatGPT로 댓글을 만드는 중입니다."
|
826
|
-
@api_key = api_key
|
827
|
-
url = 'https://api.openai.com/v1/chat/completions'
|
828
|
-
headers = {
|
829
|
-
'Content-Type' => 'application/json',
|
830
|
-
'Authorization' => 'Bearer ' + @api_key
|
831
|
-
}
|
832
|
-
data = {
|
833
|
-
'model' => 'gpt-3.5-turbo',
|
834
|
-
'messages' => [
|
835
|
-
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
836
|
-
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
837
|
-
]
|
838
|
-
}
|
839
|
-
|
840
|
-
begin
|
841
|
-
req = HTTP.headers(headers).post(url, json: data)
|
842
|
-
puts "HTTP Status: #{req.status}" # 상태 코드 확인
|
843
|
-
response = JSON.parse(req.body.to_s)
|
844
|
-
puts "API Response: #{response}" # 전체 응답 출력
|
845
|
-
|
846
|
-
if req.status == 429
|
847
|
-
return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
|
848
|
-
end
|
849
|
-
|
850
|
-
# 응답 데이터에서 안전하게 값 추출
|
851
|
-
raw_answer = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
|
852
|
-
answer = raw_answer.gsub(/\. /, ".\n") # 줄바꿈 추가
|
853
|
-
|
854
|
-
rescue => e
|
855
|
-
puts "Error: #{e.message}"
|
856
|
-
answer = "오류가 발생했습니다."
|
857
|
-
end
|
858
|
-
|
859
|
-
# 댓글 입력
|
860
|
-
@driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(answer)
|
861
|
-
sleep(1)
|
862
|
-
else
|
863
|
-
begin
|
864
|
-
puts (content)
|
865
|
-
@driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(content)
|
866
|
-
sleep(1)
|
867
|
-
rescue
|
868
|
-
end
|
869
|
-
end
|
870
|
-
|
1955
|
+
|
1956
|
+
element.send_keys(content)
|
1957
|
+
sleep(1)
|
1958
|
+
|
871
1959
|
# 이모티콘 자동 삽입
|
872
1960
|
if option['이모티콘자동삽입'] == 'true'
|
873
1961
|
puts "이모티콘 자동 삽입 옵션 진행!!".cyan
|
874
|
-
|
1962
|
+
|
875
1963
|
# '이모티콘' 버튼 클릭
|
876
1964
|
@driver.find_element(:xpath, '//*[@class="button_sticker"]').click
|
877
1965
|
sleep(1)
|
878
|
-
|
1966
|
+
|
879
1967
|
begin
|
880
1968
|
# 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
|
881
1969
|
sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
|
882
|
-
|
1970
|
+
|
883
1971
|
# 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
|
884
1972
|
random_li = sticker_list_elements.sample
|
885
1973
|
random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
|
886
1974
|
random_button.click
|
887
|
-
|
888
|
-
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
889
1975
|
|
1976
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
1977
|
+
|
890
1978
|
# 첫 번째 클릭한 <li> 내에서 버튼을 찾기
|
891
1979
|
inner_buttons = random_li.find_elements(:tag_name, 'button')
|
892
|
-
|
1980
|
+
|
893
1981
|
# 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
|
894
1982
|
random_button_in_li = inner_buttons.sample
|
895
1983
|
sleep(1)
|
896
1984
|
random_button_in_li.click
|
897
|
-
|
898
|
-
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
899
1985
|
|
1986
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
1987
|
+
|
900
1988
|
rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
|
901
1989
|
#puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
|
902
1990
|
# 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
|
903
1991
|
# 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
|
904
|
-
|
1992
|
+
|
905
1993
|
rescue => e
|
906
1994
|
puts "기타 오류로 인해 이모티콘 삽입 안됨"
|
907
1995
|
# 기타 오류 처리
|
@@ -910,34 +1998,37 @@ class Naver
|
|
910
1998
|
else
|
911
1999
|
puts "이모티콘 자동 삽입 옵션이 비활성화됨."
|
912
2000
|
end
|
913
|
-
|
2001
|
+
|
914
2002
|
# 이미지 자동 삽입
|
915
2003
|
if option['이미지자동삽입'] == 'true'
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
2004
|
+
puts "이미지 자동 상입 옵션 진행!!".cyan
|
2005
|
+
|
2006
|
+
# 아이프레임 요소가 나타날 때까지 기다립니다.
|
2007
|
+
@image = image
|
2008
|
+
image_path = image
|
2009
|
+
|
2010
|
+
@driver.find_element(:xpath, '//*[@for="attach2"]').click
|
2011
|
+
sleep(1)
|
2012
|
+
key_stroke('escape')
|
2013
|
+
# 파일 경로 자동 입력
|
2014
|
+
file_input = @driver.find_element(:xpath, '//*[@class="button_file"]')
|
2015
|
+
|
2016
|
+
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
2017
|
+
file_input.send_keys(image_path)
|
2018
|
+
sleep(2)
|
2019
|
+
|
932
2020
|
else
|
933
2021
|
end
|
934
2022
|
|
935
|
-
|
2023
|
+
|
936
2024
|
wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
|
937
2025
|
@driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
|
938
2026
|
puts "#{board_url} [댓글 작성 완료 !!]".cyan
|
939
|
-
|
940
2027
|
sleep(2)
|
2028
|
+
end
|
2029
|
+
|
2030
|
+
|
2031
|
+
|
941
2032
|
begin
|
942
2033
|
@driver.switch_to.alert
|
943
2034
|
sleep(1)
|
@@ -978,28 +2069,28 @@ class Naver
|
|
978
2069
|
ff.close()
|
979
2070
|
puts '-[√] 로그 파일 생성 완료.......'.yellow
|
980
2071
|
end
|
981
|
-
end
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
end
|
992
|
-
puts "\n"
|
2072
|
+
end
|
2073
|
+
|
2074
|
+
@driver.switch_to.default_content() # 아이프레임 해제
|
2075
|
+
def sleep_with_progress(sleep_delay)
|
2076
|
+
print "[설정 딜레이 진행 중] "
|
2077
|
+
steps = (sleep_delay.to_f / 0.5).to_i
|
2078
|
+
steps.times do
|
2079
|
+
print "."
|
2080
|
+
STDOUT.flush
|
2081
|
+
sleep(1)
|
993
2082
|
end
|
994
|
-
|
995
|
-
|
2083
|
+
puts "\n"
|
2084
|
+
end
|
996
2085
|
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
end
|
2086
|
+
sleep_with_progress(sleep_delay)
|
2087
|
+
|
2088
|
+
|
2089
|
+
rescue => e
|
2090
|
+
puts "Error: #{e.message}"
|
2091
|
+
end
|
2092
|
+
else
|
2093
|
+
end
|
1003
2094
|
################################################################################ 키워드검색사용 ################################################################################
|
1004
2095
|
if option['키워드검색사용'] == 'true'
|
1005
2096
|
puts "키워드 검색 기반으로 댓글 작업 옵션 진행!!".cyan
|
@@ -1075,216 +2166,760 @@ class Naver
|
|
1075
2166
|
break
|
1076
2167
|
end
|
1077
2168
|
|
1078
|
-
rescue => e
|
1079
|
-
puts "페이지 넘김 중 오류 발생: #{e.message}"
|
1080
|
-
break
|
1081
|
-
end
|
1082
|
-
end
|
1083
|
-
# 수집한 URL 출력
|
1084
|
-
|
1085
|
-
if @in_iframe
|
1086
|
-
@driver.switch_to.default_content
|
1087
|
-
@in_iframe = false
|
1088
|
-
puts "프레임에서 default_content로 자동 복귀"
|
1089
|
-
end
|
1090
|
-
|
1091
|
-
puts "수집한 URL들: #{collected_urls}"
|
2169
|
+
rescue => e
|
2170
|
+
puts "페이지 넘김 중 오류 발생: #{e.message}"
|
2171
|
+
break
|
2172
|
+
end
|
2173
|
+
end
|
2174
|
+
# 수집한 URL 출력
|
2175
|
+
|
2176
|
+
if @in_iframe
|
2177
|
+
@driver.switch_to.default_content
|
2178
|
+
@in_iframe = false
|
2179
|
+
puts "프레임에서 default_content로 자동 복귀"
|
2180
|
+
end
|
2181
|
+
|
2182
|
+
puts "수집한 URL들: #{collected_urls}"
|
2183
|
+
|
2184
|
+
|
2185
|
+
collected_urls.first(counts_number).each do |url|
|
2186
|
+
@driver.get(url) # 해당 URL로 이동
|
2187
|
+
sleep(1)
|
2188
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
|
2189
|
+
wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
|
2190
|
+
sleep(1)
|
2191
|
+
@driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
|
2192
|
+
|
2193
|
+
|
2194
|
+
if option['좋아요'] == 'true'
|
2195
|
+
puts "좋아요 클릭 옵션 진행!!".cyan
|
2196
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
|
2197
|
+
wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon"]') }
|
2198
|
+
|
2199
|
+
# 댓글 입력
|
2200
|
+
element = @driver.find_element(:xpath, '//*[@class="u_ico _icon"]')
|
2201
|
+
@driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
|
2202
|
+
sleep(1)
|
2203
|
+
|
2204
|
+
# 좋아요 버튼을 찾기
|
2205
|
+
like_button = @driver.find_element(:xpath, '//div[@class="ReactionLikeIt u_likeit_list_module _cafeReactionModule"]//a[@role="button"]')
|
2206
|
+
|
2207
|
+
# aria-pressed 속성 값 확인
|
2208
|
+
aria_pressed = like_button.attribute('aria-pressed')
|
2209
|
+
|
2210
|
+
if aria_pressed == 'true'
|
2211
|
+
# 이미 좋아요를 누른 상태일 경우
|
2212
|
+
|
2213
|
+
else
|
2214
|
+
# 좋아요를 아직 누르지 않은 상태일 경우 클릭
|
2215
|
+
@driver.find_element(:xpath, '//*[@class="u_ico _icon"]').click
|
2216
|
+
sleep(2)
|
2217
|
+
end
|
2218
|
+
else
|
2219
|
+
end
|
2220
|
+
|
2221
|
+
|
2222
|
+
|
2223
|
+
if option['re_coment'] == 'true' # 대 댓글 작업때
|
2224
|
+
if @data['포스트설정']['전체대댓글'].checked?
|
2225
|
+
begin
|
2226
|
+
comment_items = @driver.find_elements(:css, 'li.CommentItem')
|
2227
|
+
original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
|
2228
|
+
|
2229
|
+
original_comments.each_with_index do |item, index|
|
2230
|
+
|
2231
|
+
begin
|
2232
|
+
|
2233
|
+
if @data['포스트설정']['순서사용2'].checked?
|
2234
|
+
@content_soon ||= 0 # 초기 한 번만 0으로 세팅
|
2235
|
+
|
2236
|
+
if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
|
2237
|
+
content = ''
|
2238
|
+
else
|
2239
|
+
if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
|
2240
|
+
content = @data['내용설정']['내용'].sample[2]
|
2241
|
+
else
|
2242
|
+
content = @data['내용설정']['내용'][@content_soon][2]
|
2243
|
+
@content_soon += 1
|
2244
|
+
@content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
|
2245
|
+
end
|
2246
|
+
end
|
2247
|
+
else
|
2248
|
+
end
|
2249
|
+
|
2250
|
+
# 디엠 자동 변경이 체크된 경우 content를 변환
|
2251
|
+
if @data['포스트설정']['내용자동변경'].checked?
|
2252
|
+
change_memory = {}
|
2253
|
+
@data['포스트설정']['내용자동변경값'].each do |key, v|
|
2254
|
+
change_memory[key] = v.sample
|
2255
|
+
end
|
2256
|
+
@data['포스트설정']['내용자동변경값'].each do |key, _|
|
2257
|
+
if content.include?(key)
|
2258
|
+
content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
|
2259
|
+
else
|
2260
|
+
end
|
2261
|
+
end
|
2262
|
+
end
|
2263
|
+
|
2264
|
+
if option['ChatGPT사용'] == 'true'
|
2265
|
+
pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
|
2266
|
+
sleep(1)
|
2267
|
+
|
2268
|
+
puts "ChatGPT로 댓글을 만드는 중입니다."
|
2269
|
+
@api_key = api_key
|
2270
|
+
url = 'https://api.openai.com/v1/chat/completions'
|
2271
|
+
headers = {
|
2272
|
+
'Content-Type' => 'application/json',
|
2273
|
+
'Authorization' => 'Bearer ' + @api_key
|
2274
|
+
}
|
2275
|
+
data = {
|
2276
|
+
'model' => 'gpt-3.5-turbo',
|
2277
|
+
'messages' => [
|
2278
|
+
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
2279
|
+
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
2280
|
+
]
|
2281
|
+
}
|
2282
|
+
|
2283
|
+
begin
|
2284
|
+
req = HTTP.headers(headers).post(url, json: data)
|
2285
|
+
puts "HTTP Status: #{req.status}" # 상태 코드 확인
|
2286
|
+
response = JSON.parse(req.body.to_s)
|
2287
|
+
puts "API Response: #{response}" # 전체 응답 출력
|
2288
|
+
|
2289
|
+
if req.status == 429
|
2290
|
+
return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
|
2291
|
+
end
|
2292
|
+
|
2293
|
+
# 응답 데이터에서 안전하게 값 추출
|
2294
|
+
raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
|
2295
|
+
content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
|
2296
|
+
|
2297
|
+
rescue => e
|
2298
|
+
puts "Error: #{e.message}"
|
2299
|
+
content = "오류가 발생했습니다."
|
2300
|
+
end
|
2301
|
+
else
|
2302
|
+
end
|
2303
|
+
|
2304
|
+
reply_button = item.find_element(:css, 'a.comment_info_button')
|
2305
|
+
puts "대댓글 #{index + 1} 작성 중..."
|
2306
|
+
reply_button.click
|
2307
|
+
sleep(1.5)
|
2308
|
+
|
2309
|
+
textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
|
2310
|
+
textarea.send_keys(content)
|
2311
|
+
sleep(1)
|
2312
|
+
|
2313
|
+
if option['이모티콘자동삽입'] == 'true'
|
2314
|
+
puts "이모티콘 자동 삽입 옵션 진행!!".cyan
|
2315
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
2316
|
+
reply_comments.each_with_index do |item, index|
|
2317
|
+
begin
|
2318
|
+
|
2319
|
+
|
2320
|
+
# 해당 대댓글 내부의 이모티콘 버튼 찾기
|
2321
|
+
sticker_button = item.find_element(:css, 'a.button_sticker')
|
2322
|
+
sticker_button.click
|
2323
|
+
sleep(1)
|
2324
|
+
|
2325
|
+
rescue
|
2326
|
+
end
|
2327
|
+
end
|
2328
|
+
begin
|
2329
|
+
# 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
|
2330
|
+
sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
|
2331
|
+
|
2332
|
+
# 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
|
2333
|
+
random_li = sticker_list_elements.sample
|
2334
|
+
random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
|
2335
|
+
random_button.click
|
2336
|
+
|
2337
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
2338
|
+
|
2339
|
+
# 첫 번째 클릭한 <li> 내에서 버튼을 찾기
|
2340
|
+
inner_buttons = random_li.find_elements(:tag_name, 'button')
|
2341
|
+
|
2342
|
+
# 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
|
2343
|
+
random_button_in_li = inner_buttons.sample
|
2344
|
+
sleep(1)
|
2345
|
+
random_button_in_li.click
|
2346
|
+
|
2347
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
2348
|
+
|
2349
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
|
2350
|
+
#puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
|
2351
|
+
# 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
|
2352
|
+
# 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
|
2353
|
+
|
2354
|
+
rescue => e
|
2355
|
+
puts "기타 오류로 인해 이모티콘 삽입 안됨"
|
2356
|
+
# 기타 오류 처리
|
2357
|
+
# 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
|
2358
|
+
end
|
2359
|
+
else
|
2360
|
+
puts "이모티콘 자동 삽입 옵션이 비활성화됨."
|
2361
|
+
end
|
2362
|
+
|
2363
|
+
# 이미지 자동 삽입
|
2364
|
+
if option['이미지자동삽입'] == 'true'
|
2365
|
+
puts "이미지 자동 상입 옵션 진행!!".cyan
|
2366
|
+
|
2367
|
+
# 아이프레임 요소가 나타날 때까지 기다립니다.
|
2368
|
+
@image = image
|
2369
|
+
image_path = image
|
2370
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
2371
|
+
|
2372
|
+
reply_comments.each_with_index do |item, index|
|
2373
|
+
begin
|
2374
|
+
|
2375
|
+
|
2376
|
+
# 해당 대댓글 내부에서 for="attach2"인 라벨 클릭
|
2377
|
+
attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
|
2378
|
+
attach_button.click
|
2379
|
+
sleep(1)
|
2380
|
+
|
2381
|
+
rescue
|
2382
|
+
end
|
2383
|
+
end
|
2384
|
+
key_stroke('escape')
|
2385
|
+
# 파일 경로 자동 입력
|
2386
|
+
file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
|
2387
|
+
|
2388
|
+
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
2389
|
+
file_input.send_keys(image_path)
|
2390
|
+
sleep(2)
|
2391
|
+
|
2392
|
+
else
|
2393
|
+
end
|
2394
|
+
|
2395
|
+
register_btn = @driver.find_element(:css, 'a.button.btn_register')
|
2396
|
+
register_btn.click
|
2397
|
+
sleep(2)
|
2398
|
+
|
2399
|
+
rescue => e
|
2400
|
+
puts "대댓글 #{index + 1} 처리 중 오류 발생: #{e.message}"
|
2401
|
+
next
|
2402
|
+
end
|
2403
|
+
end
|
2404
|
+
rescue => e
|
2405
|
+
puts "전체대댓글 처리 중 예외 발생: #{e.message}"
|
2406
|
+
end
|
2407
|
+
|
2408
|
+
elsif @data['포스트설정']['지정대댓글'].checked?
|
2409
|
+
targets = @data['포스트설정']['nik_or_number'].text.to_s.force_encoding('utf-8').split(',').map(&:strip)
|
2410
|
+
targets.each do |target|
|
2411
|
+
if target.match?(/^\d+$/)
|
2412
|
+
index = target.to_i - 1
|
2413
|
+
comment_items = @driver.find_elements(:css, 'li.CommentItem')
|
2414
|
+
original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
|
2415
|
+
|
2416
|
+
if original_comments[index]
|
2417
|
+
begin
|
2418
|
+
|
2419
|
+
if @data['포스트설정']['순서사용2'].checked?
|
2420
|
+
@content_soon ||= 0 # 초기 한 번만 0으로 세팅
|
2421
|
+
|
2422
|
+
if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
|
2423
|
+
content = ''
|
2424
|
+
else
|
2425
|
+
if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
|
2426
|
+
content = @data['내용설정']['내용'].sample[2]
|
2427
|
+
else
|
2428
|
+
content = @data['내용설정']['내용'][@content_soon][2]
|
2429
|
+
@content_soon += 1
|
2430
|
+
@content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
|
2431
|
+
end
|
2432
|
+
end
|
2433
|
+
else
|
2434
|
+
end
|
2435
|
+
|
2436
|
+
# 디엠 자동 변경이 체크된 경우 content를 변환
|
2437
|
+
if @data['포스트설정']['내용자동변경'].checked?
|
2438
|
+
change_memory = {}
|
2439
|
+
@data['포스트설정']['내용자동변경값'].each do |key, v|
|
2440
|
+
change_memory[key] = v.sample
|
2441
|
+
end
|
2442
|
+
@data['포스트설정']['내용자동변경값'].each do |key, _|
|
2443
|
+
if content.include?(key)
|
2444
|
+
content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
|
2445
|
+
else
|
2446
|
+
end
|
2447
|
+
end
|
2448
|
+
end
|
2449
|
+
|
2450
|
+
if option['ChatGPT사용'] == 'true'
|
2451
|
+
pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
|
2452
|
+
sleep(1)
|
2453
|
+
|
2454
|
+
puts "ChatGPT로 댓글을 만드는 중입니다."
|
2455
|
+
@api_key = api_key
|
2456
|
+
url = 'https://api.openai.com/v1/chat/completions'
|
2457
|
+
headers = {
|
2458
|
+
'Content-Type' => 'application/json',
|
2459
|
+
'Authorization' => 'Bearer ' + @api_key
|
2460
|
+
}
|
2461
|
+
data = {
|
2462
|
+
'model' => 'gpt-3.5-turbo',
|
2463
|
+
'messages' => [
|
2464
|
+
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
2465
|
+
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
2466
|
+
]
|
2467
|
+
}
|
2468
|
+
|
2469
|
+
begin
|
2470
|
+
req = HTTP.headers(headers).post(url, json: data)
|
2471
|
+
puts "HTTP Status: #{req.status}" # 상태 코드 확인
|
2472
|
+
response = JSON.parse(req.body.to_s)
|
2473
|
+
puts "API Response: #{response}" # 전체 응답 출력
|
2474
|
+
|
2475
|
+
if req.status == 429
|
2476
|
+
return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
|
2477
|
+
end
|
2478
|
+
|
2479
|
+
# 응답 데이터에서 안전하게 값 추출
|
2480
|
+
raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
|
2481
|
+
content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
|
2482
|
+
|
2483
|
+
rescue => e
|
2484
|
+
puts "Error: #{e.message}"
|
2485
|
+
content = "오류가 발생했습니다."
|
2486
|
+
end
|
2487
|
+
else
|
2488
|
+
end
|
2489
|
+
|
2490
|
+
puts "#{index + 1}번째 댓글에 대댓글 작성 시작"
|
2491
|
+
reply_button = original_comments[index].find_element(:css, 'a.comment_info_button')
|
2492
|
+
reply_button.click
|
2493
|
+
sleep(1.5)
|
2494
|
+
|
2495
|
+
textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
|
2496
|
+
textarea.send_keys(content)
|
2497
|
+
sleep(1)
|
2498
|
+
|
2499
|
+
if option['이모티콘자동삽입'] == 'true'
|
2500
|
+
puts "이모티콘 자동 삽입 옵션 진행!!".cyan
|
2501
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
2502
|
+
reply_comments.each_with_index do |item, index|
|
2503
|
+
begin
|
2504
|
+
|
2505
|
+
|
2506
|
+
# 해당 대댓글 내부의 이모티콘 버튼 찾기
|
2507
|
+
sticker_button = item.find_element(:css, 'a.button_sticker')
|
2508
|
+
sticker_button.click
|
2509
|
+
sleep(1)
|
2510
|
+
|
2511
|
+
rescue
|
2512
|
+
end
|
2513
|
+
end
|
2514
|
+
|
2515
|
+
begin
|
2516
|
+
# 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
|
2517
|
+
sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
|
2518
|
+
|
2519
|
+
# 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
|
2520
|
+
random_li = sticker_list_elements.sample
|
2521
|
+
random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
|
2522
|
+
random_button.click
|
2523
|
+
|
2524
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
2525
|
+
|
2526
|
+
# 첫 번째 클릭한 <li> 내에서 버튼을 찾기
|
2527
|
+
inner_buttons = random_li.find_elements(:tag_name, 'button')
|
2528
|
+
|
2529
|
+
# 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
|
2530
|
+
random_button_in_li = inner_buttons.sample
|
2531
|
+
sleep(1)
|
2532
|
+
random_button_in_li.click
|
2533
|
+
|
2534
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
2535
|
+
|
2536
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
|
2537
|
+
#puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
|
2538
|
+
# 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
|
2539
|
+
# 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
|
2540
|
+
|
2541
|
+
rescue => e
|
2542
|
+
puts "기타 오류로 인해 이모티콘 삽입 안됨"
|
2543
|
+
# 기타 오류 처리
|
2544
|
+
# 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
|
2545
|
+
end
|
2546
|
+
else
|
2547
|
+
puts "이모티콘 자동 삽입 옵션이 비활성화됨."
|
2548
|
+
end
|
2549
|
+
|
2550
|
+
# 이미지 자동 삽입
|
2551
|
+
if option['이미지자동삽입'] == 'true'
|
2552
|
+
puts "이미지 자동 상입 옵션 진행!!".cyan
|
2553
|
+
|
2554
|
+
# 아이프레임 요소가 나타날 때까지 기다립니다.
|
2555
|
+
@image = image
|
2556
|
+
image_path = image
|
2557
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
2558
|
+
|
2559
|
+
reply_comments.each_with_index do |item, index|
|
2560
|
+
begin
|
2561
|
+
|
2562
|
+
|
2563
|
+
# 해당 대댓글 내부에서 for="attach2"인 라벨 클릭
|
2564
|
+
attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
|
2565
|
+
attach_button.click
|
2566
|
+
sleep(1)
|
2567
|
+
|
2568
|
+
rescue
|
2569
|
+
end
|
2570
|
+
end
|
2571
|
+
key_stroke('escape')
|
2572
|
+
# 파일 경로 자동 입력
|
2573
|
+
file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
|
2574
|
+
|
2575
|
+
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
2576
|
+
file_input.send_keys(image_path)
|
2577
|
+
sleep(2)
|
2578
|
+
|
2579
|
+
else
|
2580
|
+
end
|
2581
|
+
|
2582
|
+
register_btn = @driver.find_element(:css, 'a.button.btn_register')
|
2583
|
+
register_btn.click
|
2584
|
+
sleep(2)
|
2585
|
+
|
2586
|
+
puts "#{index + 1}번째 댓글에 대댓글 작성 완료"
|
2587
|
+
rescue => e
|
2588
|
+
puts "댓글 인덱스 #{index + 1} 처리 중 오류 발생: #{e.message}"
|
2589
|
+
end
|
2590
|
+
else
|
2591
|
+
puts "해당 인덱스(#{index + 1})의 답글쓰기 버튼이 없습니다."
|
2592
|
+
end
|
2593
|
+
|
2594
|
+
else # 닉네임으로 찾기
|
2595
|
+
comment_items = @driver.find_elements(:css, 'li.CommentItem')
|
2596
|
+
original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
|
2597
|
+
|
2598
|
+
matched = false
|
2599
|
+
last_matched_item = nil # 마지막에 닉네임이 일치한 댓글 저장
|
2600
|
+
|
2601
|
+
original_comments.each_with_index do |item, idx|
|
2602
|
+
begin
|
2603
|
+
nickname_element = item.find_element(:css, 'a.comment_nickname')
|
2604
|
+
nickname = nickname_element.text.strip
|
2605
|
+
|
2606
|
+
if nickname.include?(target)
|
2607
|
+
puts "#{target} 닉네임이 포함된 댓글 발견 (#{idx + 1}번째)"
|
2608
|
+
last_matched_item = item # 매번 갱신 → 마지막에 발견된 걸 저장
|
2609
|
+
end
|
2610
|
+
rescue => e
|
2611
|
+
puts "닉네임 검사 중 오류 발생: #{e.message}"
|
2612
|
+
next
|
2613
|
+
end
|
2614
|
+
end
|
2615
|
+
|
2616
|
+
# 루프 끝난 뒤 마지막 댓글에만 작업 실행
|
2617
|
+
if last_matched_item
|
2618
|
+
begin
|
2619
|
+
|
2620
|
+
if @data['포스트설정']['순서사용2'].checked?
|
2621
|
+
@content_soon ||= 0 # 초기 한 번만 0으로 세팅
|
2622
|
+
|
2623
|
+
if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
|
2624
|
+
content = ''
|
2625
|
+
else
|
2626
|
+
if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
|
2627
|
+
content = @data['내용설정']['내용'].sample[2]
|
2628
|
+
else
|
2629
|
+
content = @data['내용설정']['내용'][@content_soon][2]
|
2630
|
+
@content_soon += 1
|
2631
|
+
@content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
|
2632
|
+
end
|
2633
|
+
end
|
2634
|
+
else
|
2635
|
+
end
|
2636
|
+
|
2637
|
+
# 디엠 자동 변경이 체크된 경우 content를 변환
|
2638
|
+
if @data['포스트설정']['내용자동변경'].checked?
|
2639
|
+
change_memory = {}
|
2640
|
+
@data['포스트설정']['내용자동변경값'].each do |key, v|
|
2641
|
+
change_memory[key] = v.sample
|
2642
|
+
end
|
2643
|
+
@data['포스트설정']['내용자동변경값'].each do |key, _|
|
2644
|
+
if content.include?(key)
|
2645
|
+
content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
|
2646
|
+
else
|
2647
|
+
end
|
2648
|
+
end
|
2649
|
+
end
|
2650
|
+
|
2651
|
+
if option['ChatGPT사용'] == 'true'
|
2652
|
+
pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
|
2653
|
+
sleep(1)
|
2654
|
+
|
2655
|
+
puts "ChatGPT로 댓글을 만드는 중입니다."
|
2656
|
+
@api_key = api_key
|
2657
|
+
url = 'https://api.openai.com/v1/chat/completions'
|
2658
|
+
headers = {
|
2659
|
+
'Content-Type' => 'application/json',
|
2660
|
+
'Authorization' => 'Bearer ' + @api_key
|
2661
|
+
}
|
2662
|
+
data = {
|
2663
|
+
'model' => 'gpt-3.5-turbo',
|
2664
|
+
'messages' => [
|
2665
|
+
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
2666
|
+
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
2667
|
+
]
|
2668
|
+
}
|
2669
|
+
|
2670
|
+
begin
|
2671
|
+
req = HTTP.headers(headers).post(url, json: data)
|
2672
|
+
puts "HTTP Status: #{req.status}" # 상태 코드 확인
|
2673
|
+
response = JSON.parse(req.body.to_s)
|
2674
|
+
puts "API Response: #{response}" # 전체 응답 출력
|
2675
|
+
|
2676
|
+
if req.status == 429
|
2677
|
+
return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
|
2678
|
+
end
|
2679
|
+
|
2680
|
+
# 응답 데이터에서 안전하게 값 추출
|
2681
|
+
raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
|
2682
|
+
content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
|
2683
|
+
|
2684
|
+
rescue => e
|
2685
|
+
puts "Error: #{e.message}"
|
2686
|
+
content = "오류가 발생했습니다."
|
2687
|
+
end
|
2688
|
+
else
|
2689
|
+
end
|
2690
|
+
|
2691
|
+
reply_button = last_matched_item.find_element(:css, 'a.comment_info_button')
|
2692
|
+
reply_button.click
|
2693
|
+
sleep(1.5)
|
2694
|
+
|
2695
|
+
textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
|
2696
|
+
textarea.send_keys(content)
|
2697
|
+
sleep(1)
|
2698
|
+
|
2699
|
+
if option['이모티콘자동삽입'] == 'true'
|
2700
|
+
puts "이모티콘 자동 삽입 옵션 진행!!".cyan
|
2701
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
2702
|
+
reply_comments.each_with_index do |item, index|
|
2703
|
+
begin
|
2704
|
+
|
2705
|
+
sticker_button = item.find_element(:css, 'a.button_sticker')
|
2706
|
+
sticker_button.click
|
2707
|
+
sleep(1)
|
2708
|
+
rescue
|
2709
|
+
end
|
2710
|
+
end
|
2711
|
+
begin
|
2712
|
+
sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
|
2713
|
+
random_li = sticker_list_elements.sample
|
2714
|
+
random_button = random_li.find_element(:tag_name, 'button')
|
2715
|
+
random_button.click
|
2716
|
+
sleep(1)
|
2717
|
+
inner_buttons = random_li.find_elements(:tag_name, 'button')
|
2718
|
+
random_button_in_li = inner_buttons.sample
|
2719
|
+
sleep(1)
|
2720
|
+
random_button_in_li.click
|
2721
|
+
sleep(1)
|
2722
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError
|
2723
|
+
rescue => e
|
2724
|
+
puts "기타 오류로 인해 이모티콘 삽입 안됨"
|
2725
|
+
end
|
2726
|
+
else
|
2727
|
+
puts "이모티콘 자동 삽입 옵션이 비활성화됨."
|
2728
|
+
end
|
2729
|
+
|
2730
|
+
if option['이미지자동삽입'] == 'true'
|
2731
|
+
puts "이미지 자동 삽입 옵션 진행!!".cyan
|
2732
|
+
@image = image
|
2733
|
+
image_path = image
|
2734
|
+
reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
|
2735
|
+
reply_comments.each_with_index do |item, index|
|
2736
|
+
begin
|
2737
|
+
|
2738
|
+
attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
|
2739
|
+
attach_button.click
|
2740
|
+
sleep(1)
|
2741
|
+
rescue
|
2742
|
+
end
|
2743
|
+
end
|
2744
|
+
key_stroke('escape')
|
2745
|
+
file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
|
2746
|
+
file_input.send_keys(image_path)
|
2747
|
+
sleep(2)
|
2748
|
+
end
|
1092
2749
|
|
2750
|
+
register_btn = @driver.find_element(:css, 'a.button.btn_register')
|
2751
|
+
register_btn.click
|
2752
|
+
sleep(2)
|
1093
2753
|
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
2754
|
+
matched = true
|
2755
|
+
rescue => e
|
2756
|
+
puts "대댓글 등록 중 오류 발생: #{e.message}"
|
2757
|
+
end
|
2758
|
+
end
|
2759
|
+
|
2760
|
+
puts "닉네임 '#{target}'을 포함한 댓글을 찾지 못했습니다." unless matched
|
1101
2761
|
|
1102
|
-
|
2762
|
+
end
|
2763
|
+
end
|
1103
2764
|
|
1104
|
-
if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
|
1105
|
-
content = ''
|
1106
|
-
else
|
1107
|
-
if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
|
1108
|
-
content = @data['내용설정']['내용'].sample[2]
|
1109
|
-
else
|
1110
|
-
content = @data['내용설정']['내용'][@content_soon][2]
|
1111
|
-
@content_soon += 1
|
1112
|
-
@content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
|
1113
|
-
end
|
1114
|
-
end
|
1115
|
-
|
1116
|
-
# 디엠 자동 변경이 체크된 경우 content를 변환
|
1117
|
-
if @data['포스트설정']['내용자동변경'].checked?
|
1118
|
-
change_memory = {}
|
1119
|
-
@data['포스트설정']['내용자동변경값'].each do |key, v|
|
1120
|
-
change_memory[key] = v.sample
|
1121
|
-
end
|
1122
|
-
@data['포스트설정']['내용자동변경값'].each do |key, _|
|
1123
|
-
if content.include?(key)
|
1124
|
-
content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
|
1125
|
-
else
|
1126
2765
|
end
|
1127
|
-
end
|
1128
|
-
end
|
1129
|
-
|
1130
|
-
if option['좋아요'] == 'true'
|
1131
|
-
puts "좋아요 클릭 옵션 진행!!".cyan
|
1132
|
-
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
|
1133
|
-
wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon"]') }
|
1134
|
-
|
1135
|
-
# 댓글 입력
|
1136
|
-
element = @driver.find_element(:xpath, '//*[@class="u_ico _icon"]')
|
1137
|
-
@driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
|
1138
|
-
sleep(1)
|
1139
2766
|
|
1140
|
-
|
1141
|
-
|
2767
|
+
elsif option['re_coment'] == 'false' # 대 댓글 아닐때
|
2768
|
+
if @data['포스트설정']['순서사용2'].checked?
|
2769
|
+
@content_soon ||= 0 # 초기 한 번만 0으로 세팅
|
1142
2770
|
|
1143
|
-
|
1144
|
-
|
2771
|
+
if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
|
2772
|
+
content = ''
|
2773
|
+
else
|
2774
|
+
if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
|
2775
|
+
content = @data['내용설정']['내용'].sample[2]
|
2776
|
+
else
|
2777
|
+
content = @data['내용설정']['내용'][@content_soon][2]
|
2778
|
+
@content_soon += 1
|
2779
|
+
@content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
|
2780
|
+
end
|
2781
|
+
end
|
2782
|
+
else
|
2783
|
+
end
|
2784
|
+
|
2785
|
+
# 디엠 자동 변경이 체크된 경우 content를 변환
|
2786
|
+
if @data['포스트설정']['내용자동변경'].checked?
|
2787
|
+
change_memory = {}
|
2788
|
+
@data['포스트설정']['내용자동변경값'].each do |key, v|
|
2789
|
+
change_memory[key] = v.sample
|
2790
|
+
end
|
2791
|
+
@data['포스트설정']['내용자동변경값'].each do |key, _|
|
2792
|
+
if content.include?(key)
|
2793
|
+
content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
|
2794
|
+
else
|
2795
|
+
end
|
2796
|
+
end
|
2797
|
+
end
|
1145
2798
|
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
2799
|
+
if option['ChatGPT사용'] == 'true'
|
2800
|
+
pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
|
2801
|
+
sleep(1)
|
2802
|
+
|
2803
|
+
puts "ChatGPT로 댓글을 만드는 중입니다."
|
2804
|
+
@api_key = api_key
|
2805
|
+
url = 'https://api.openai.com/v1/chat/completions'
|
2806
|
+
headers = {
|
2807
|
+
'Content-Type' => 'application/json',
|
2808
|
+
'Authorization' => 'Bearer ' + @api_key
|
2809
|
+
}
|
2810
|
+
data = {
|
2811
|
+
'model' => 'gpt-3.5-turbo',
|
2812
|
+
'messages' => [
|
2813
|
+
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
2814
|
+
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
2815
|
+
]
|
2816
|
+
}
|
2817
|
+
|
2818
|
+
begin
|
2819
|
+
req = HTTP.headers(headers).post(url, json: data)
|
2820
|
+
puts "HTTP Status: #{req.status}" # 상태 코드 확인
|
2821
|
+
response = JSON.parse(req.body.to_s)
|
2822
|
+
puts "API Response: #{response}" # 전체 응답 출력
|
2823
|
+
|
2824
|
+
if req.status == 429
|
2825
|
+
return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
|
2826
|
+
end
|
2827
|
+
|
2828
|
+
# 응답 데이터에서 안전하게 값 추출
|
2829
|
+
raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
|
2830
|
+
content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
|
2831
|
+
|
2832
|
+
rescue => e
|
2833
|
+
puts "Error: #{e.message}"
|
2834
|
+
content = "오류가 발생했습니다."
|
2835
|
+
end
|
2836
|
+
else
|
2837
|
+
end
|
1156
2838
|
|
1157
|
-
|
1158
|
-
|
2839
|
+
wait = Selenium::WebDriver::Wait.new(timeout: 10)
|
2840
|
+
wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
|
1159
2841
|
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
2842
|
+
element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
|
2843
|
+
@driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)
|
2844
|
+
sleep(1)
|
1163
2845
|
|
1164
|
-
|
1165
|
-
element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
|
1166
|
-
@driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
|
1167
|
-
sleep(1)
|
1168
|
-
if option['ChatGPT사용'] == 'true'
|
1169
|
-
pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
|
1170
|
-
sleep(1)
|
1171
|
-
|
1172
|
-
puts "ChatGPT로 댓글을 만드는 중입니다."
|
1173
|
-
@api_key = api_key
|
1174
|
-
url = 'https://api.openai.com/v1/chat/completions'
|
1175
|
-
headers = {
|
1176
|
-
'Content-Type' => 'application/json',
|
1177
|
-
'Authorization' => 'Bearer ' + @api_key
|
1178
|
-
}
|
1179
|
-
data = {
|
1180
|
-
'model' => 'gpt-3.5-turbo',
|
1181
|
-
'messages' => [
|
1182
|
-
{ "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
|
1183
|
-
{ "role" => "user", "content" => pcol1 } # pcol1 직접 사용
|
1184
|
-
]
|
1185
|
-
}
|
1186
|
-
|
1187
|
-
begin
|
1188
|
-
req = HTTP.headers(headers).post(url, json: data)
|
1189
|
-
puts "HTTP Status: #{req.status}" # 상태 코드 확인
|
1190
|
-
response = JSON.parse(req.body.to_s)
|
1191
|
-
puts "API Response: #{response}" # 전체 응답 출력
|
1192
|
-
|
1193
|
-
if req.status == 429
|
1194
|
-
return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
|
1195
|
-
end
|
1196
|
-
|
1197
|
-
# 응답 데이터에서 안전하게 값 추출
|
1198
|
-
raw_answer = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
|
1199
|
-
answer = raw_answer.gsub(/\. /, ".\n") # 줄바꿈 추가
|
1200
|
-
|
1201
|
-
rescue => e
|
1202
|
-
puts "Error: #{e.message}"
|
1203
|
-
answer = "오류가 발생했습니다."
|
1204
|
-
end
|
1205
|
-
|
1206
|
-
# 댓글 입력
|
1207
|
-
@driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(answer)
|
1208
|
-
sleep(1)
|
1209
|
-
else
|
1210
|
-
begin
|
1211
|
-
puts (content)
|
1212
|
-
@driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(content)
|
2846
|
+
element.send_keys(content)
|
1213
2847
|
sleep(1)
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
2848
|
+
|
2849
|
+
# 이모티콘 자동 삽입
|
2850
|
+
if option['이모티콘자동삽입'] == 'true'
|
2851
|
+
puts "이모티콘 자동 삽입 옵션 진행!!".cyan
|
2852
|
+
|
2853
|
+
# '이모티콘' 버튼 클릭
|
2854
|
+
@driver.find_element(:xpath, '//*[@class="button_sticker"]').click
|
2855
|
+
sleep(1)
|
2856
|
+
|
2857
|
+
begin
|
2858
|
+
# 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
|
2859
|
+
sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
|
2860
|
+
|
2861
|
+
# 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
|
2862
|
+
random_li = sticker_list_elements.sample
|
2863
|
+
random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
|
2864
|
+
random_button.click
|
2865
|
+
|
2866
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
2867
|
+
|
2868
|
+
# 첫 번째 클릭한 <li> 내에서 버튼을 찾기
|
2869
|
+
inner_buttons = random_li.find_elements(:tag_name, 'button')
|
2870
|
+
|
2871
|
+
# 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
|
2872
|
+
random_button_in_li = inner_buttons.sample
|
2873
|
+
sleep(1)
|
2874
|
+
random_button_in_li.click
|
2875
|
+
|
2876
|
+
sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
|
2877
|
+
|
2878
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
|
2879
|
+
#puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
|
2880
|
+
# 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
|
2881
|
+
# 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
|
2882
|
+
|
2883
|
+
rescue => e
|
2884
|
+
puts "기타 오류로 인해 이모티콘 삽입 안됨"
|
2885
|
+
# 기타 오류 처리
|
2886
|
+
# 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
|
2887
|
+
end
|
2888
|
+
else
|
2889
|
+
puts "이모티콘 자동 삽입 옵션이 비활성화됨."
|
2890
|
+
end
|
1234
2891
|
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
inner_buttons = random_li.find_elements(:tag_name, 'button')
|
2892
|
+
# 이미지 자동 삽입
|
2893
|
+
if option['이미지자동삽입'] == 'true'
|
2894
|
+
puts "이미지 자동 상입 옵션 진행!!".cyan
|
1239
2895
|
|
1240
|
-
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
2896
|
+
# 아이프레임 요소가 나타날 때까지 기다립니다.
|
2897
|
+
@image = image
|
2898
|
+
image_path = image
|
2899
|
+
|
2900
|
+
@driver.find_element(:xpath, '//*[@for="attach2"]').click
|
2901
|
+
sleep(1)
|
2902
|
+
key_stroke('escape')
|
2903
|
+
# 파일 경로 자동 입력
|
2904
|
+
file_input = @driver.find_element(:xpath, '//*[@class="button_file"]')
|
1244
2905
|
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
rescue => e
|
1253
|
-
puts "기타 오류로 인해 이모티콘 삽입 안됨"
|
1254
|
-
# 기타 오류 처리
|
1255
|
-
# 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
|
1256
|
-
end
|
1257
|
-
else
|
1258
|
-
puts "이모티콘 자동 삽입 옵션이 비활성화됨."
|
1259
|
-
end
|
1260
|
-
|
1261
|
-
# 이미지 자동 삽입
|
1262
|
-
if option['이미지자동삽입'] == 'true'
|
1263
|
-
puts "이미지 자동 상입 옵션 진행!!".cyan
|
2906
|
+
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
2907
|
+
file_input.send_keys(image_path)
|
2908
|
+
sleep(2)
|
2909
|
+
|
2910
|
+
else
|
2911
|
+
end
|
1264
2912
|
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
# 파일 경로 자동 입력
|
1273
|
-
file_input = @driver.find_element(:xpath, '//*[@id="attach2"]')
|
2913
|
+
|
2914
|
+
wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
|
2915
|
+
@driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
|
2916
|
+
sleep(2)
|
2917
|
+
posting_url = @driver.current_url
|
2918
|
+
puts "#{posting_url} [댓글 진행 완료 !!]".cyan
|
2919
|
+
end
|
1274
2920
|
|
1275
|
-
# send_keys로 파일 경로를 입력하여 이미지 업로드
|
1276
|
-
file_input.send_keys(image_path)
|
1277
|
-
sleep(2)
|
1278
2921
|
|
1279
|
-
else
|
1280
|
-
end
|
1281
2922
|
|
1282
|
-
|
1283
|
-
|
1284
|
-
wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
|
1285
|
-
@driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
|
1286
|
-
puts "#{board_url} [댓글 작성 완료 !!]".cyan
|
1287
|
-
sleep(2)
|
1288
2923
|
begin
|
1289
2924
|
@driver.switch_to.alert
|
1290
2925
|
sleep(1)
|
@@ -1325,26 +2960,28 @@ class Naver
|
|
1325
2960
|
ff.close()
|
1326
2961
|
puts '-[√] 로그 파일 생성 완료.......'.yellow
|
1327
2962
|
end
|
1328
|
-
end
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
2963
|
+
end
|
2964
|
+
|
2965
|
+
|
2966
|
+
@driver.switch_to.default_content() # 아이프레임 해제
|
2967
|
+
def sleep_with_progress(sleep_delay)
|
2968
|
+
print "[설정 딜레이 진행 중] "
|
2969
|
+
steps = (sleep_delay.to_f / 0.5).to_i
|
2970
|
+
steps.times do
|
2971
|
+
print "."
|
2972
|
+
STDOUT.flush
|
2973
|
+
sleep(1)
|
2974
|
+
end
|
2975
|
+
puts "\n"
|
1338
2976
|
end
|
1339
|
-
puts "\n"
|
1340
|
-
end
|
1341
|
-
sleep_with_progress(sleep_delay)
|
1342
|
-
|
1343
2977
|
|
1344
|
-
|
2978
|
+
sleep_with_progress(sleep_delay)
|
2979
|
+
|
2980
|
+
|
2981
|
+
rescue => e
|
1345
2982
|
puts "Error: #{e.message}"
|
1346
|
-
|
1347
|
-
end
|
2983
|
+
end
|
2984
|
+
end
|
1348
2985
|
else
|
1349
2986
|
end
|
1350
2987
|
|
@@ -1491,7 +3128,7 @@ end
|
|
1491
3128
|
# 상태 표시 퍼샌테이지 아래 [7]넘버는 게이지바에 맞게 넘버를 넣어줘야 작동됨
|
1492
3129
|
while true
|
1493
3130
|
for n in 0..@data['table'].length-1
|
1494
|
-
@data['table'][n][
|
3131
|
+
@data['table'][n][8] = 0
|
1495
3132
|
end
|
1496
3133
|
|
1497
3134
|
while true
|
@@ -1504,7 +3141,18 @@ end
|
|
1504
3141
|
next
|
1505
3142
|
end
|
1506
3143
|
|
1507
|
-
|
3144
|
+
if table[4] == true
|
3145
|
+
option['re_coment'] = 'true'
|
3146
|
+
if @data['포스트설정']['전체대댓글'].checked?
|
3147
|
+
|
3148
|
+
elsif @data['포스트설정']['지정대댓글'].checked?
|
3149
|
+
nik_or_number = @data['포스트설정']['nik_or_number'].text.to_s.force_encoding('utf-8')
|
3150
|
+
puts nik_or_number
|
3151
|
+
else
|
3152
|
+
end
|
3153
|
+
else
|
3154
|
+
option['re_coment'] = 'false'
|
3155
|
+
end
|
1508
3156
|
|
1509
3157
|
|
1510
3158
|
option['proxy'] = ''
|
@@ -1516,7 +3164,7 @@ end
|
|
1516
3164
|
end
|
1517
3165
|
end
|
1518
3166
|
|
1519
|
-
if table[
|
3167
|
+
if table[7].to_i > table[8].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
|
1520
3168
|
#if table[6].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
|
1521
3169
|
|
1522
3170
|
if @data['포스트설정']['테더링'].checked?
|
@@ -1707,7 +3355,14 @@ end
|
|
1707
3355
|
@data['table'] << []
|
1708
3356
|
@data['table'].pop
|
1709
3357
|
|
1710
|
-
|
3358
|
+
if @data['포스트설정']['순서사용2'].checked?
|
3359
|
+
option['순서사용2'] = 'true'
|
3360
|
+
else
|
3361
|
+
option['순서사용2'] = 'false'
|
3362
|
+
end
|
3363
|
+
@data['table'][index][-1] = 35
|
3364
|
+
@data['table'] << []
|
3365
|
+
@data['table'].pop
|
1711
3366
|
|
1712
3367
|
#네이버로그인
|
1713
3368
|
login_check = naver.login(user_id, user_pw, option['proxy'])
|
@@ -1844,15 +3499,15 @@ end
|
|
1844
3499
|
# p option
|
1845
3500
|
|
1846
3501
|
# 댓글 설정 수 카운트
|
1847
|
-
counts_number = @data['table'][index][
|
3502
|
+
counts_number = @data['table'][index][6].to_i
|
1848
3503
|
api_key = @data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8')
|
1849
|
-
sleep_delay = @data['table'][index][
|
3504
|
+
sleep_delay = @data['table'][index][5].to_i
|
1850
3505
|
naver.update(content,board_url,nickname,image,option,counts_number,keyword,api_key,sleep_delay)
|
1851
3506
|
|
1852
3507
|
|
1853
3508
|
|
1854
3509
|
#완료했으니 수량 카운터
|
1855
|
-
@data['table'][index][
|
3510
|
+
@data['table'][index][8] = @data['table'][index][8].to_i + 1
|
1856
3511
|
@data['table'][index][-1] = 100
|
1857
3512
|
@data['table'] << []
|
1858
3513
|
@data['table'].pop
|
@@ -2227,8 +3882,8 @@ end
|
|
2227
3882
|
button(' 댓글 등록 ID 추가 '){
|
2228
3883
|
|
2229
3884
|
on_clicked {
|
2230
|
-
@data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['proxy'].text, 1, 2, 1,0,0]
|
2231
|
-
@data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['proxy'].text, 1, 2, 1,0,0]
|
3885
|
+
@data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['proxy'].text,false, 1, 2, 1,0,0]
|
3886
|
+
@data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['proxy'].text,false, 1, 2, 1,0,0]
|
2232
3887
|
@data['table'].pop
|
2233
3888
|
}
|
2234
3889
|
}
|
@@ -2241,8 +3896,8 @@ end
|
|
2241
3896
|
file_data.split("\n").each do |i|
|
2242
3897
|
i3 = i.to_s.force_encoding('utf-8').to_s
|
2243
3898
|
i2 = i3.split(',')
|
2244
|
-
@data['table'] << [false, i2[0].to_s, i2[1].to_s,i2[2].to_s, 1,2,1,0,0]
|
2245
|
-
@data['table'] << [false, i2[0].to_s, i2[1].to_s, 1,2,1,0,0]
|
3899
|
+
@data['table'] << [false, i2[0].to_s, i2[1].to_s,i2[2].to_s,['1', 'true'].include?(i2[3].to_s.strip.downcase), 1,2,1,0,0]
|
3900
|
+
@data['table'] << [false, i2[0].to_s, i2[1].to_s, false, 1,2,1,0,0]
|
2246
3901
|
@data['table'].pop
|
2247
3902
|
end
|
2248
3903
|
end
|
@@ -2268,6 +3923,10 @@ end
|
|
2268
3923
|
text_column('프록시'){
|
2269
3924
|
editable true
|
2270
3925
|
}
|
3926
|
+
|
3927
|
+
checkbox_column('대댓글작업') {
|
3928
|
+
editable true
|
3929
|
+
}
|
2271
3930
|
|
2272
3931
|
text_column('딜레이'){
|
2273
3932
|
editable true
|
@@ -2362,9 +4021,9 @@ end
|
|
2362
4021
|
table_counter_again = @data['table_counter_again'].text.to_i
|
2363
4022
|
# @data['table']의 각 항목을 업데이트
|
2364
4023
|
@data['table'].map! do |row|
|
2365
|
-
row[
|
2366
|
-
row[
|
2367
|
-
row[
|
4024
|
+
row[5] = table_delay_input
|
4025
|
+
row[6] = table_counter_input
|
4026
|
+
row[7] = table_counter_again
|
2368
4027
|
row # 수정된 row를 반환
|
2369
4028
|
end
|
2370
4029
|
}
|
@@ -2895,11 +4554,21 @@ end
|
|
2895
4554
|
|
2896
4555
|
horizontal_box{
|
2897
4556
|
stretchy false
|
2898
|
-
@data['내용설정']['순서사용'] = checkbox('순서사용'){
|
4557
|
+
@data['내용설정']['순서사용'] = checkbox('계정마다 순서사용'){
|
2899
4558
|
stretchy false
|
2900
4559
|
on_toggled{ |c|
|
2901
4560
|
if c.checked?
|
2902
4561
|
@data['내용설정']['랜덤사용'].checked = false
|
4562
|
+
@data['포스트설정']['순서사용2'].checked = false
|
4563
|
+
end
|
4564
|
+
}
|
4565
|
+
}
|
4566
|
+
@data['포스트설정']['순서사용2'] = checkbox('게시글마다 순서사용'){
|
4567
|
+
stretchy false
|
4568
|
+
on_toggled{ |c|
|
4569
|
+
if c.checked?
|
4570
|
+
@data['내용설정']['랜덤사용'].checked = false
|
4571
|
+
@data['내용설정']['순서사용'].checked = false
|
2903
4572
|
end
|
2904
4573
|
}
|
2905
4574
|
}
|
@@ -2908,6 +4577,7 @@ end
|
|
2908
4577
|
on_toggled{ |c|
|
2909
4578
|
if c.checked?
|
2910
4579
|
@data['내용설정']['순서사용'].checked = false
|
4580
|
+
@data['포스트설정']['순서사용2'].checked = false
|
2911
4581
|
end
|
2912
4582
|
}
|
2913
4583
|
}
|
@@ -3145,6 +4815,33 @@ end
|
|
3145
4815
|
end
|
3146
4816
|
}
|
3147
4817
|
}
|
4818
|
+
@data['포스트설정']['전체대댓글'] = checkbox('대 댓글 전체 타겟(옵션1) '){
|
4819
|
+
top 1
|
4820
|
+
left 3
|
4821
|
+
on_toggled{
|
4822
|
+
if @data['포스트설정']['전체대댓글'].checked?
|
4823
|
+
@data['포스트설정']['지정대댓글'].checked = false
|
4824
|
+
end
|
4825
|
+
}
|
4826
|
+
}
|
4827
|
+
@data['포스트설정']['지정대댓글'] = checkbox('대 댓글 지정 타겟(옵션2)'){
|
4828
|
+
top 1
|
4829
|
+
left 4
|
4830
|
+
on_toggled{
|
4831
|
+
if @data['포스트설정']['지정대댓글'].checked?
|
4832
|
+
@data['포스트설정']['전체대댓글'].checked = false
|
4833
|
+
end
|
4834
|
+
}
|
4835
|
+
}
|
4836
|
+
@data['포스트설정']['nik_or_number'] = entry(){
|
4837
|
+
top 1
|
4838
|
+
left 5
|
4839
|
+
text '예)마루 or 예)1(댓글넘버)'
|
4840
|
+
}
|
4841
|
+
label('콤마로 추가 가능 예)마루,강쥐 or 예)1,3'){
|
4842
|
+
top 1
|
4843
|
+
left 6
|
4844
|
+
}
|
3148
4845
|
|
3149
4846
|
}
|
3150
4847
|
}
|