일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- ReactJS
- 프론트엔드
- yarn classic
- node
- 채널톡
- 세팅
- mysql설정
- nextjs
- yarn berry
- shaka
- MAC
- Yarn
- brew
- homebrew
- Next.js
- DRM
- shaka player
- 환경설정
- VirtualBox
- 개발세팅
- 커스텀훅
- Video
- 버추어박스
- react
- React.js
- npm
- 비디오플레이어
Archives
- Today
- Total
코딩 요정 버터링
next.js (react.js) 에서 채널톡 커스텀 훅으로 만들어 사용하기 본문
회사에서 맡아 운영하는 서비스에서 채널톡을 도입하였다.
공식문서에 보면 자바스크립트로 밖에 되어있지 않아서 도입을 하려면 커스텀훅을 사용해서 도입해야했다.
구글링을 했지만 딱히 뭔가 확 오는 방법이 없어서 직접 커스텀훅을 만들기로 결정!
ts 파일을 hook 디랙토리에 생성 후 일단 공식 문서에 있는 인터페이스들을 긁어왔다.
그 후 스크립트를 function으로 작성 후 채널톡에서 제공하는 기본 함수들을 타입스크립트로 변경하여 적용하였다.
declare global {
interface Window {
ChannelIO?: IChannelIO;
ChannelIOInitialized?: boolean;
}
}
interface IChannelIO {
c?: (...args: any) => void;
q?: [methodName: string, ...args: any[]][];
(...args: any): void;
}
interface BootOption {
appearance?: string;
customLauncherSelector?: string;
hideChannelButtonOnBoot?: boolean;
hidePopup?: boolean;
language?: string;
memberHash?: string;
memberId?: string;
mobileMessengerMode?: string;
pluginKey: string;
profile?: Profile;
trackDefaultEvent?: boolean;
trackUtmSource?: boolean;
unsubscribe?: boolean;
unsubscribeEmail?: boolean;
unsubscribeTexting?: boolean;
zIndex?: number;
}
interface Callback {
(error: Error | null, user: CallbackUser | null): void;
}
interface CallbackUser {
alert: number;
avatarUrl: string;
id: string;
language: string;
memberId: string;
name?: string;
profile?: Profile | null;
tags?: string[] | null;
unsubscribeEmail: boolean;
unsubscribeTexting: boolean;
}
interface UpdateUserInfo {
language?: string;
profile?: Profile | null;
profileOnce?: Profile;
tags?: string[] | null;
unsubscribeEmail?: boolean;
unsubscribeTexting?: boolean;
}
interface Profile {
[key: string]: string | number | boolean | null;
}
interface FollowUpProfile {
name?: string | null;
mobileNumber?: string | null;
email?: string | null;
}
interface EventProperty {
[key: string]: string | number | boolean | null;
}
type Appearance = 'light' | 'dark' | 'system' | null;
export default function UseChannelService() {
const loadScript = () => {
let w = window;
if (w.ChannelIO) {
return (window.console.error || window.console.log || function () {})('ChannelIO script included twice.');
}
const ch: IChannelIO = function () {
ch.c?.(arguments);
};
ch.q = [];
ch.c = function (args) {
ch.q?.push(args);
};
w.ChannelIO = ch;
function l() {
if (w.ChannelIOInitialized) {
return;
}
w.ChannelIOInitialized = true;
let s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = 'https://cdn.channel.io/plugin/ch-plugin-web.js';
let x = document.getElementsByTagName('script')[0];
if (x.parentNode) {
x.parentNode.insertBefore(s, x);
}
}
if (document.readyState === 'complete') {
l();
} else {
w.addEventListener('DOMContentLoaded', l);
w.addEventListener('load', l);
}
};
loadScript();
return () => {
window.ChannelIO?.('clearCallbacks');
};
}
export const ChannelTalk = {
boot: (option: BootOption, callback?: Callback) => {
window.ChannelIO?.('boot', option, callback);
},
shutdown: () => {
window.ChannelIO?.('shutdown');
},
showMessenger: () => {
window.ChannelIO?.('showMessenger');
},
hideMessenger: () => {
window.ChannelIO?.('hideMessenger');
},
openChat: (chatId?: string | number, message?: string) => {
window.ChannelIO?.('openChat', chatId, message);
},
track: (eventName: string, eventProperty?: EventProperty) => {
window.ChannelIO?.('track', eventName, eventProperty);
},
onShowMessenger: (callback: () => void) => {
window.ChannelIO?.('onShowMessenger', callback);
},
onHideMessenger: (callback: () => void) => {
window.ChannelIO?.('onHideMessenger', callback);
},
onBadgeChanged: (callback: (alert: number) => void) => {
window.ChannelIO?.('onBadgeChanged', callback);
},
onChatCreated: (callback: () => void) => {
window.ChannelIO?.('onChatCreated', callback);
},
onFollowUpChanged: (callback: (profile: FollowUpProfile) => void) => {
window.ChannelIO?.('onFollowUpChanged', callback);
},
onUrlClicked: (callback: (url: string) => void) => {
window.ChannelIO?.('onUrlClicked', callback);
},
updateUser: (userInfo: UpdateUserInfo, callback?: Callback) => {
window.ChannelIO?.('updateUser', userInfo, callback);
},
addTags: (tags: string[], callback?: Callback) => {
window.ChannelIO?.('addTags', tags, callback);
},
removeTags: (tags: string[], callback?: Callback) => {
window.ChannelIO?.('removeTags', tags, callback);
},
setPage: (page: string) => {
window.ChannelIO?.('setPage', page);
},
resetPage: () => {
window.ChannelIO?.('resetPage');
},
showChannelButton: () => {
window.ChannelIO?.('showChannelButton');
},
hideChannelButton: () => {
window.ChannelIO?.('hideChannelButton');
},
setAppearance: (appearance: Appearance) => {
window.ChannelIO?.('setAppearance', appearance);
},
};
처음엔 nav에서 채널톡을 실행하였지만 그러다 보니 유저의 정보를 업데이트 할 때 채널톡을 두번 호출하는 에러가 있었다.
채널톡을 사용하고 서비스를 운영하는데 크리티컬한 에러는 아니였지만 맘에 들지 않았기 때문에
_app.ts 에 useEffect로 웹 어플리케이션 실행 시 딱 한번만 커스텀 훅이 실행되게 코드를 작성하였다.
const MyApp = (props: MyAppProps) => {
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
useEffect(() => {
UseChannelService();
}, []);
return (
<>
<Meta />
<CacheProvider value={emotionCache}>
<ThemeProvider theme={theme}>
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline />
<GlobalStyles
styles={{
body: { backgroundColor: '#1E1E1E' },
}}
/>
<Layout>
<Component {...pageProps} />
</Layout>
</ThemeProvider>
</CacheProvider>
</>
);
};
export default appWithTranslation(MyApp);
사용자가 웹 페이지에 접속했을때 커스텀 훅을 실행시켜 채널톡에 연동한 후 각 함수가 필요한 페이지나 컴포넌트에서
호출하여 쓰니 오류가 해결~~!!!
내가 사용한 방식이 옳은 방식인진 잘 모르겠지만 혹시라도 필요한 분들이 계시면....
'프론트엔드 개발' 카테고리의 다른 글
next.js 에서 샤카플레이어 (shaka player) 사용하기 (drm 적용) (1) | 2023.12.22 |
---|---|
yarn classic(v1) 에서 yarn berrey(v4) 마이그레이션 하기 (0) | 2023.12.22 |
Mac 에서 Homebrew 를 통해 node, npm, yarn 설치하기 (3) | 2020.01.01 |
Comments