[프로젝트] 카카오톡 공유 기능 기반 위치 공유

ljk4268·2023년 8월 3일
0

프로젝트 투입시 고도화 작업 중 카카오톡 공유 기능 기반 위치 공유 서비스를 구현해야 했다.
개발일정을 맞추기 위해 미리 선작업을 했는데
나중에 해당 코드를 사용할 일이 많을거 같아 개인 블로그에 코드 남겨둔다!


사용한 언어 : Vue3

✅ 카카오톡 위치 공유를 위해 적용했던 선작업 코드

위치공유 서비스다 보니 지도서비스와 카카오톡 공유서비스 코드가 같이 포함되어 있다.

<template>
  <div> 위치공유 외의 작업코드는 지움! </div>
</template>

<script>
import { ref, reactive, watch } from 'vue';

export default {
  name: 'mapModal',
  props: {
    state: Object,
    isShared: {
      type: Boolean,
      default: true,
    },
  },
  setup(props, { emit }) {
    const paramObj = props.state;
    let map = null;
    let marker = null;
    let defaultMapLevel = 5;
    let mapDivRef = ref(null);
    let placeId = ref(null);
    let placeName = ref('');
    
    watch(props.state, (newData) => {
      if(newData.visible){
        fn_importMapScript()
      }
    })

    // 지도 스크립트 임포트
    const fn_importMapScript = () => {
      if (!window.kakao || !window.kakao.maps || map == null) {
        let mapScript = document.createElement('script');
        mapScript.setAttribute(
          'src',
          '//dapi.kakao.com/v2/maps/sdk.js?autoload=false&libraries=services&appkey=' +
            process.env.VUE_APP_KAKAOMAP_KEY
        );
        document.head.appendChild(mapScript);
        mapScript.addEventListener('load', () => {
          kakao.maps.load(() => {
            // 지도 스크립트 받은적 없으면 지도 초기화
            fn_initMap();
          });
        });
      } else {
        // 지도 스크립트가 있으면 사용자가 원하는 위치로 지도 이동
        fn_moveMap();
      }
    };

    // 지도 초기화
    const fn_initMap = () => {
      const position = new kakao.maps.LatLng(37.5666805, 126.9784147);

      const container = mapDivRef.value;
      const options = {
        center: position,
        level: defaultMapLevel,
      };
      map = new kakao.maps.Map(container, options);

      const mapTypeControl = new kakao.maps.MapTypeControl();
      map.addControl(mapTypeControl, kakao.maps.ControlPosition.TOPRIGHT);

      const zoomControl = new kakao.maps.ZoomControl();
      map.addControl(zoomControl, kakao.maps.ControlPosition.RIGHT);

      fn_moveMap();
    };

    // 지도 이동하기
    const fn_moveMap = () => {
      if (marker != null) {
        marker.setMap(null);
        map.setLevel(defaultMapLevel);
      }

      const geocoder = new kakao.maps.services.Geocoder();

      // 주소로 좌표 조회
      geocoder.addressSearch(paramObj.address, function (result, status) {
        placeName = result[0]?.road_address.building_name;
        if (status === kakao.maps.services.Status.OK) {
          const coords = new kakao.maps.LatLng(result[0].y, result[0].x);

          // 결과값으로 받은 위치를 마커로 표시합니다
          marker = new kakao.maps.Marker({
            position: coords,
          });

          marker.setMap(map);

          // 좌표로 지도이동
          map.setCenter(coords);

          if (props.isShared) {
            // 지도 마커 위 인포메이션 생성
            createMapLabel(placeName, coords);

            // 카카오톡 위치 공유를 위한 장소 ID 구하기
            getAddressId(coords);
          }
          
        }
      });
    };

    // 카카오톡 위치공유 스크립트 임포트
    const fn_importKakaoSharingScript = () => {
      let kakaoShareScript = document.createElement('script');
      kakaoShareScript.setAttribute(
        'src',
        'https://t1.kakaocdn.net/kakao_js_sdk/2.2.0/kakao.min.js'
      );
      kakaoShareScript.setAttribute(
        'integrity',
        'sha384-x+WG2i7pOR+oWb6O5GV5f1KN2Ko6N7PTGPS7UlasYWNxZMKQA63Cj/B2lbUmUfuC'
      );
      kakaoShareScript.setAttribute('crossorigin', 'anonymous');
      document.head.appendChild(kakaoShareScript);

      kakaoShareScript.addEventListener('load', () => {
        Kakao.init(process.env.VUE_APP_KAKAOSHARE_KEY);
      });
    };

    // 카카오톡 위치공유 기능
    const locationSharing = (placeId) => {
      const address = props.state.address;
      const addressTitle = placeName;
      const addressUrl = `https://place.map.kakao.com/${placeId}`;

      if (!Kakao.isInitialized()) {
        Kakao.init(process.env.VUE_APP_KAKAOSHARE_KEY);
      } else {
        Kakao.Share.sendDefault({
          objectType: 'location',
          address: address,
          addressTitle: addressTitle,
          content: {
            title: addressTitle,
            description: address,
            imageUrl:
              'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/markerStar.png',
            link: {
              mobileWebUrl: addressUrl,
              webUrl: addressUrl,
            },
          },
          buttons: [
            {
              title: '웹으로 보기',
              link: {
                mobileWebUrl: addressUrl,
                webUrl: addressUrl,
              },
            },
          ],
        });
      }
    };

    // 지도에 표시된 마커 위 라벨 추가
    const createMapLabel = (buildingName, position) => {
      const mLabelContent = `<div style="padding:5px; font-weight: bold;">${buildingName}</div>`;

      const mLable = new kakao.maps.InfoWindow({
        position: position,
        content: mLabelContent,
        removable: true,
      });

      mLable.open(map, marker);
    };

    // 카카오톡 위치 공유를 위한 장소 ID 구하기
    const getAddressId = ({ La: x, Ma: y }) => {
      const places = new kakao.maps.services.Places();
      const placesCallback = (result, status) => {
        if (status === kakao.maps.services.Status.OK) {
          placeId.value = result[0].id;
        }
      };
      const placesOptions = { x, y };
      places.keywordSearch(placeName, placesCallback, placesOptions);
    };

    const fn_close = () => {
      emit('close');
    };

    return {
      fn_close,
      paramObj,
      fn_importMapScript,
      fn_importKakaoSharingScript,
      mapDivRef,
      locationSharing,
    };
  },
};
</script>

✅ 작업하면서 힘들었던 점

위치 공유 기능이다보니 지도에서 여러 위치를 공유할 수 있어야 했는데,
무슨 이유에서인지 내가 등록한 개발환경이랑 프로젝트 해당 웹사이트로만 공유가 되고, 카카오톡 지도 위치는 공유가 안되더라!

https://place.map.kakao.com/${placeId}

딱 저 주소로 장소id만 바껴서 해당 장소 위치가 지도로 공유가 되어야 하는데..!!

알고보니 https://place.map.kakao.com < 이것도 도메인으로 등록을 해놔야 공유가 가능한 것이였다 ㅎㅎ..
https://place.map.kakao.com 만 등록해놔도 장소id에 따라 여러 위치가 다 공유 가능하다!

profile
적응중

0개의 댓글