본문 바로가기

송송 DEV

송송은 뚠뚠 오늘도 뚠뚠 열심히 ~ 코딩 하네 뚠뚠

카카오 링크 API로 카카오톡 공유하기

현재 웹 페이지의 내용을 카카오톡으로 공유할 수 있는 카카오 링크 API 사용법에 대해 알아봅시다.

개요


웬만한 홈페이지에는 다 들어가있는 공유기능. API 이용이 익숙하지 않으면 무슨 소리인지 모르겠고 헤매기 십상이다. 혹시나 도움이 될까 해서 작성해본다.

 

관련 문서 링크 모음

카카오 API에서 제공하는 기능이 너무 많아 헷갈릴 수 있는데, 오늘 다룰 부분은 어플 등이 아니라 일반 홈페이지에서 사용할 것으로 Kakao SDK for JavaScript에서 제공하는 기능 중 카카오 메시지 > 카카오링크(JavaScript)를 이용할 것이다.

 

요렇게 진행해보려 한다.

  1. 카카오 개발자 사이트에서 카카오 링크를 위해 애플리케이션을 만들고
  2. 카카오톡으로 피드 형태로, 메시지 템플릿을 이용해 공유
  3. 카카오톡으로 리스트 형태로, 스크립트로 공유

공식 문서를 참고하면 보낼 수 있는 옵션이 여러 개가 있는데, 개인적으로 나중에 커스텀하기 가장 쉽다고 생각하는 형태로 작업해보려고 한다. 공식 문서도 잘 되어 있으니, 한번 연습해보고 여러가지 옵션을 테스트해보면 좋을 것 같다.

 


애플리케이션 등록


애플리케이션 추가하기

📌 Kakao Developers > 로그인 > 내 애플리케이션 > 애플리케이션 추가하기

정보 입력 후 저장

설정에서 모두 변경할 수 있다. 적당히 적어주고 저장해도 무방

생성하면 앱 키 영역에 키가 생성된 것을 확인할 수 있다. JavaScript 키를 이용할 것이다.

 

생성한 앱 설정하기

📌 내 애플리케이션 > 앱 설정 > 일반

기본정보는 공유한 메시지 하단에 노출된다. 잘 적어준다.

 

플랫폼 등록하기

web상에서 사용할 것이므로 Web 플랫폼을 등록해준다.

📌 내 애플리케이션 > 앱 설정 > 플랫폼 > Web 플랫폼 등록

등록된 도메인에서 실행해야 오류가 나지 않기 때문에 테스트용 http://localhost:3000도 같이 등록해주었다. 이렇게 애플리케이션을 등록했다면 카카오 링크 기능을 활용할 수 있다.

다양한 방법으로 카카오톡 공유를 구현할 수 있는데, 크게 메시지 템플릿을 만들어서 보내는 방법, 스크립트로 보내는 방법 두 가지를 알아보려 한다.

템플릿으로 보내기 vs 스크립트로 보내기

코드 상으로 바로 보내는 스크립트로 보내기와 카카오 개발자 사이트에서 템플릿을 만들고 그 템플릿을 이용해 보내는 템플릿 보내기 두 가지 방법이 있다.

두 가지 방법 결과물은 거의 동일하다. 그러나 스크립트로 보내기에서는 공유 시 기본으로 들어가는 ‘자세히보기’ 버튼을 없애는 옵션이 따로 없다. 때문에 해당 버튼이 필요 없다면 메시지 템플릿을 만들어 사용하는 것을 추천한다.


메시지 템플릿을 이용해 공유하기


 

1. 메시지 템플릿 만들기

📌 (왼쪽 목록에서)메시지 > 메시지 템플릿 > 메시지 템플릿 빌더 바로가기 혹은 도구 > 메시지 템플릿

템플릿 형태 선택 화면
012345678
탭 별로 작성하고 상단의 저장버튼을 꼭 눌러준다!

위 이미지 슬라이드를 참고하여 템플릿을 만들어준다.

왼쪽 하단의 User Agent 박스가 보이는데, 여기서 지정한 변수로 넘겨주면 원하는 내용이 해당 부분에 들어오게 된다. 만들고 나서 왼쪽 템플릿 목록을 보면 ID 12345가 보인다. 이 번호가 템플릿 ID로, 이 번호를 이용해 템플릿과 소스를 연결한다.

 

2. 카카오 메시지 템플릿 사용하기

1) init

// init 체크
if (!Kakao.isInitialized()) {
  Kakao.init('[APP_ID]');
}
  • 위에서 애플리케이션을 만들며 생성한 JavaScript 키를 [APP_ID]여기에 넣어준다. (대괄호까지 삭제하고 키를 붙여넣기 해주세요.)
  • api 자체에서 initialized되었는지 체크하는 함수가 있다. 생성되지 않았으면 false 반환, 생성 되었으면 true를 반환 한다. false일 때 init함수를 실행한다.

 

2) 메시지 구성하기

var sendKakao = function() {
    // 메시지 공유 함수
  Kakao.Link.sendScrap({
    requestUrl: 'http://localhost:3000/', // 페이지 url
    templateId: 12345, // 메시지템플릿 번호
    templateArgs: {
            PROFILE : '프로필 이미지 주소' // 프로필 이미지 주소 ${PROFILE}
      THUMB: '썸네일 주소', // 썸네일 주소 ${THUMB}
      TITLE: '제목 텍스트입니다', // 제목 텍스트 ${TITLE}
      DESC: '설명 텍스트입니다', // 설명 텍스트 ${DESC}
    },
  });
};
  • requestUrl은 애플리케이션에서 등록한 url 중 하나여야 한다.
    (여기서 등록되지 않은 url을 넣으면 4002 오류가 나므로 주의)
  • 페이지 내부에 1개만 들어간다면 이벤트를 따로 연결하지 않아도 되는 createScrapButton를 사용해도 괜찮지만, 한 페이지 내에 버튼이 2개 이상 있다면 sendScrap을 써서 따로 연결하는 것을 추천
  • templateArgs에서는 앞 단계 템플릿에서 설정한 User Agent변수 이름과 동일하게 만들고 값을 적어준다.
// head에서 정보 가져오기(JQuery)
var thumbImg = $('meta[property="og:image"]').attr('content'); //og이미지 주소
var thumbTitle = $('meta[property="og:title"]').attr('content'); //og타이틀
var thumbDesc = $('meta[property="og:description"]').attr('content'); //og설명
var linkUrl = $('meta[property="og:url"]').attr('content'); //url

var sendKakao = function() {
    // 메시지 공유 함수
  Kakao.Link.sendScrap({
    requestUrl: linkUrl, // 페이지 url
    templateId: 12345, // 메시지템플릿 번호
    templateArgs: {
      THUMB: thumbImg, // 썸네일 주소
      TITLE: thumbTitle, // 제목 텍스트
      DESC: thumbDesc, // 설명 텍스트
    },
  });
};
  • 직접 텍스트를 쓰지 않고 다른 html요소에서 값을 가져오려면 이런 식으로 할 수 있다. (예시는 head의 메타태그를 활용했다.)

 

3) 버튼에 함수 연결하기

// onclick으로 연결
<button onclick="shareKakao()">
  <img src="/img/icon_kakao.png" alt="카카오톡 공유" />
</button>
// 이벤트 리스너로 연결
<button class="kakao-share">
  <img src="/img/icon_kakao.png" alt="카카오톡 공유" />
</button>

<script>
    var kakaoShareBtn = document.querySelector('.kakao-share');
    kakaoShareBtn.addEventListener('click', function() {
        shareKakao();
    });
</script>

물론addEventListener등 다른 방법으로 연결해도 문제 없다.


템플릿 없이 보내기


메시지 템플릿을 사용하지 않고 코드에서 바로 만들어서 보낼 수도 있다. init과 버튼 연결 함수는 동일하므로 메시지 구성부분만 떼어서 살펴보겠다. 둘 다 큰 차이 없으므로 상황에 따라 적절하게 취사선택해보자.

 

메시지 구성하기

templateId가 없고, templateArgs를 사용하는 대신 content에서 직접 바로 내용을 작성한다

Kakao.Link.sendDefault({
    objectType: 'feed',
    content: {
      title: '제목을 여기에 씁니다.',
      description: '내용을 여기에 씁니다',
      imageUrl:
        'https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeB1Yj7%2Fbtrn8HKdp01%2FlZMtAuvo986os4dCkVoAOk%2Fimg.png',
      imageWidth: 1200,
      imageHeight: 630,
      link: {
        mobileWebUrl: 'https://developers.kakao.com',
        androidExecutionParams: 'test',
      },
    },
    itemContent: {
      profileText: '송송',
      profileImageUrl:
        'https://tistory1.daumcdn.net/tistory/373748/attach/af0ef0205e234b4f9f09d7bce27dd237',
    },
    buttons: [
      {
        title: '블로그 둘러보기',
        link: {
          mobileWebUrl: 'https://songsong.dev',
          webUrl: 'https://songsong.dev',
        },
      },
    ],
  });

피드 형태

실제 공유 화면

Kakao.Link.sendDefault({
    objectType: 'list',
    headerTitle: '송송 DEV 글 목록',
    headerLink: {
      mobileWebUrl: 'https://songsong.dev',
      webUrl: 'https://songsong.dev',
    },
    contents: [
      {
        title: 'swiperjs 슬라이더 기본 사용법 알아보기',
        description: 'TIL/JS',
        imageUrl:
          'https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeB1Yj7%2Fbtrn8HKdp01%2FlZMtAuvo986os4dCkVoAOk%2Fimg.png',
        link: {
          mobileWebUrl:
            'https://songsong.dev/entry/swiperjs-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%8D%94-%EA%B8%B0%EB%B3%B8-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0',
          webUrl:
            'https://songsong.dev/entry/swiperjs-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%8D%94-%EA%B8%B0%EB%B3%B8-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0',
        },
      },
      {
        title: '자바스크립트로 달력 만들기',
        description: 'TIL/JS',
        imageUrl:
          'https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmPXhd%2FbtrnbWuI91J%2Fv4zoKoLl1sH0IjhKSk6e4k%2Fimg.png',
        link: {
          mobileWebUrl:
            'https://songsong.dev/entry/Javascript%EB%A1%9C-%EB%8B%AC%EB%A0%A5-%EB%A7%8C%EB%93%A4%EA%B8%B0',
          webUrl:
            'https://songsong.dev/entry/Javascript%EB%A1%9C-%EB%8B%AC%EB%A0%A5-%EB%A7%8C%EB%93%A4%EA%B8%B0',
        },
      },
      {
        title: '자바스크립트로 문자메시지 보내기',
        description: 'TIL/JS',
        imageUrl:
          'https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmPXhd%2FbtrnbWuI91J%2Fv4zoKoLl1sH0IjhKSk6e4k%2Fimg.png',
        link: {
          mobileWebUrl:
            'https://songsong.dev/entry/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%A1%9C-%EB%AC%B8%EC%9E%90%EB%A9%94%EC%8B%9C%EC%A7%80-%EB%B3%B4%EB%82%B4%EA%B8%B0',
          webUrl:
            'https://songsong.dev/entry/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%A1%9C-%EB%AC%B8%EC%9E%90%EB%A9%94%EC%8B%9C%EC%A7%80-%EB%B3%B4%EB%82%B4%EA%B8%B0',
        },
      },
    ],
    buttons: [
      {
        title: '블로그 둘러보기',
        link: {
          mobileWebUrl: 'https://songsong.dev',
          webUrl: 'https://songsong.dev',
        },
      },
    ],
  });

리스트 형태

실제 공유 화면

리스트 썸네일 사이즈는 정사각형 고정이다. 내 썸네일은 좌우가 잘린다. 안타깝다...

공유 기능 자체는 이런 식으로 작업하면 되는데, 실제로 어떻게 적용하는지는 현재 페이지에 적용한 걸 예시로 들어보겠다.


티스토리에 적용하기


문제

티스토리에는 기본적으로 게시글 하단의 공유 버튼을 눌러 카카오톡으로 공유할 수 있다. 그러나 2차 도메인을 사용하고 있는 티스토리 페이지는 버튼을 누르면 아래와 같은 오류가 발생한다.

ErrorCode(4002) UUID(776f94df-8ed3-463c-a1b8-7530dfdfca1a)

 

원인

이유는 앞서 말했듯이 애플리케이션에 등록되어 있는 도메인과 공유 이벤트가 발생하는 url이 달라서 그렇다.

쉽게 말해 등록된 카카오 개발자 사이트에 등록된 url은 tistory.com인데, 현재 홈페이지의 도메인은 songsong.dev이기 때문에 4002에러가 난다. 따라서 현재 도메인을 위한 애플리케이션을 새로 만들어 주고 이벤트를 다시 연결해주면 해결할 수 있다.

 

해결

기존 소스를 건드리지 않기 위해 조금 복잡해졌다. 클릭 이벤트가 기존 버튼에 직접 걸려있는 것이 아니었기 때문에 새로 html 엘리먼트를 만들었다. 데이터는 공유할 헤더에서 따로 가져와 새로운 버튼에 이벤트를 걸고 기존 버튼과 바꿔치기 하여 수정했다.

$(document).ready(function () {
  // 게시글 페이지에서만 동작
  if ($("#tt-body-page").length == 1) {
    kakaoShareFix();
  }
});

function kakaoShareFix() {
  // 포스트 하단 공유 기능 fix
  // 기존 카카오 클린업
  Kakao.Link.cleanup();
  Kakao.cleanup();

  // 새로운 키를 이용하여 init
  Kakao.init("97f86710c1661d48252b0b2cffc5d05b");

  // 버튼 요소 생성 및 변경
  var kakaoBtnNew = document.createElement("button");
  var kakaoIco = document.createElement("span");
  var kakaoBtnTxt = document.createTextNode("카카오톡으로 공유");
  kakaoIco.classList.add("ico_sns");
  kakaoIco.classList.add("ico_kt");
  kakaoBtnNew.appendChild(kakaoIco);
  kakaoBtnNew.appendChild(kakaoBtnTxt);
  kakaoBtnNew.classList.add("btn_mark");

  var kakaoBtnOld = document.querySelector('a[data-service="kakaotalk"]');
  var kakaoBtnWrap = document.querySelector(".bundle_post");

  // 공유 정보 가져오기
  var shareContent = {
    title: document.querySelector('[property="og:title"]').attributes.content
      .value,
    desc: document.querySelector('[property="og:description"]').attributes
      .content.value,
    image: document.querySelector('[property="og:image"]').attributes.content
      .value,
    url: document.querySelector('[property="og:url"]').attributes.content.value,
  };

  // 카카오 공유
  var kakaoShareFunc = function (shareContent) {
    Kakao.Link.sendDefault({
      objectType: "feed",
      content: {
        title: shareContent.title,
        description: shareContent.desc,
        imageUrl: shareContent.image,
        imageWidth: 1200,
        imageHeight: 630,
        link: {
          webUrl: shareContent.url,
        },
      },
      buttons: [
        {
          title: "자세히 보기",
          link: {
            webUrl: "https://songsong.dev",
          },
        },
      ],
    });
  };

  // 공유 함수 연결
  kakaoBtnNew.addEventListener("click", function () {
    kakaoShareFunc(shareContent);
  });

  // 기존 버튼과 새로 만든 버튼 바꿔치기
  kakaoBtnWrap.replaceChild(kakaoBtnNew, kakaoBtnOld);
}

현재 페이지에도 적용되어 있다. 게시글 하단의 공유 기능을 이용해 확인해보자.