ãã®èšäºã§ã¯ããã®ããããäœæããŠGoogle APIãšå¯Ÿè©±ããæ©èœã«ã€ããŠèª¬æããŸãã ç§ã¯ç°¡æœãã倧奜ããªã®ã§ãèšäºã«ã¯ãæ°Žãã¯ã»ãšãã©ãããŸããã
èšäºã¯ã©ã®ãããªè³ªåã«çããŸããïŒ
- Webhookã®å€éšãµã€ãã¢ãã¬ã¹ãååŸããå Žæ
- HTTPS蚌ææžãååŸããå ŽæãTelegramãä¿¡é Œã§ããããã«äœ¿çšããæ¹æ³
- ããŒã¿ã転éããã€ã³ã©ã€ã³ãã¿ã³ã®ã¯ãªãã¯ãåŠçããæ¹æ³
- Google APIã®æ°žé ã®OAuthããŒã¯ã³ãååŸããæ¹æ³
- OAuthã³ãŒã«ããã¯URLãä»ããŠãŠãŒã¶ãŒããŒã¿ãæž¡ãæ¹æ³
- ç¡æã®ã¬ãã«3ãã¡ã€ã³ãååŸããæ¹æ³
ã¹ã¿ã㯠ïŒ
- ããã¯ãšã³ãïŒNode.js + Express.js
- DBïŒMongo.js + mongoose
- ããã±ãŒãžãããŒãžã£ãŒïŒ ã€ãŒã³ ïŒåœŒã¯æ¬åœã«éãïŒ
- ãã¬ã°ã©ã ããããã¬ãŒã ã¯ãŒã¯ïŒ Telegraf
- æ¬çªïŒDocker + Docker Compose + Vscale.io
ãããéçºæã®æ©èœ
ãã³ã°ããŒãªã³ã°ãšWebhookã䜿çšããŠãTelegramããã³ãã³ããåä¿¡ã§ããŸãã ã€ã³ã¿ãŒãããã§ã®ã¬ãã¥ãŒããå€æãããšããã³ã°ããŒãªã³ã°ã¯ãã°ãããããšåäœããªããªããŸã-Telegramã¯500ãšã©ãŒãè¿ãã®ã§ãç§ã¯ããã«Webhookã§ãããè¡ãããšã«ããŸããã
Webhookã®å€éšWebãµã€ãã¢ãã¬ã¹ãå¿ èŠã§ã
Webhookã¯ãTelegramããŠãŒã¶ãŒããã³ãã³ããšã¡ãã»ãŒãžãéä¿¡ããã¢ãã¬ã¹ãªã®ã§ãå€éšã«ããå¿ èŠããããŸãããããŒã«ã«ã§éçºããæ¹æ³ã¯ïŒ
ããã§ã¯ã ngrokãLocaltunnelãªã©ã®ãµãŒãã¹ãå©ãã«ãªããŸãïŒ ãªã³ã¯1 ã ãªã³ã¯2 ïŒã
ãããã®ãµãŒãã¹ã¯äž¡æ¹ãšããã©ã³ãã ãªã¬ãã«3ãã¡ã€ã³ãçæããŸãã éçãªãã®ãå¿ èŠãªå Žåã¯ãngrokã§æ¯æãå¿ èŠããããŸãããLocaltunnelã§ã¯ãããŸããã
Google APIã§OAuth 2.0ã¯ã©ã€ã¢ã³ãIDã«ãã€ã³ããããOAuthã³ãŒã«ããã¯URLãæ§æããå¿ èŠããã£ãã®ã§ãéçã§ããã°ãã䟿å©ã§ãã ãã®ãããLocaltunnelã䜿çšããŸããã
ãããã®ãµãŒãã¹ã¯ã©ã¡ããHTTPSã«éåžžã®æå¹ãªèšŒææžãæäŸãããããTelegramã«åé¡ã¯ãããŸããã
æ¬çªã§ã¯ãHTTPSãå¿ èŠã§ã
Telegramã§ã¯ãèªå·±çœ²å蚌ææžã䜿çšã§ããŸãã æé ã¯å ¬åŒãŠã§ããµã€ãã«ãããŸãã ãã ãããã©ãŠã¶ã¯åœŒãä¿¡é Œãããåã蚌ææžãOAuthã³ãŒã«ããã¯URLã«äœ¿çšããããããæå¹ãªèšŒææžãå¿ èŠã§ããã Let's Encryptãå©ãã«ãªããŸãã
蚌ææžãçæããããšã¯ãã€ã³ã¿ãŒãããäžã®åé¡ã§ã¯ãããŸããã ç§ãç解ããŠããå¯äžã®ããšã¯ãããã䜿çšããããµãŒããŒäžã§çæãããå¿ èŠããããšããããšã§ãïŒããã§ãªãå Žåã¯æ£ããã§ãïŒã
ubunteã§ã¯ã letsencryptããã±ãŒãžã䜿çšããŠã³ãã³ããå®è¡ããŸãã ã
letsencrypt certonly -n -d domain1.com -d domain2.ru --email admin@domain.ru --standalone --noninteractive --agree-tos
ã©ã®èšŒææžãšãããTelegramã«è»¢éããæ¹æ³
Webhook Telegramãæ©èœããã«ã¯ãCA蚌ææžã転éããŠTelegramãä¿¡é Œãéå§ããå¿ èŠããããŸãã
èªå·±çœ²å蚌ææžã®å Žå-ãããå®è¡ããå ¬ééµã転éããå¿ èŠããããŸãã
Let's Encryptã®å Žåãäœã転éããå¿ èŠã¯ãããŸããããWebãµãŒããŒã§HTTPSãæ£ããæ§æããå¿ èŠããããŸãã
Let's Encryptã¯4ã€ã®èšŒææžãçæããŸãïŒ
- cert.pem-å ¬éããŒ
- chain.pem-CA蚌ææž
- fullchain.pem-å ¬ééµ+ CA蚌ææž
- privkey.pem-ç§å¯éµ
HAProxyã䜿çšããå Žåã«HTTPSã«å¿ èŠãªã®ã¯privkey.pem + fullchain.pemã§ãïŒä»ã®ãŠãŒã¶ãŒã«ãåãããã«æ§æããå¿ èŠããããŸãïŒãããã«ãããTelegramãããããä¿¡é Œãå§ããŸãã
ãã®èšŒææžã¯ã次ã®ããã«Telegrafçµç±ã§è»¢éã§ããŸãã
let cert = { source: '/path/public.pem' }; app.telegram.setWebhook(config.webHookUrl + '/' + config.webHookSecretPath, cert);
ã€ã³ã©ã€ã³ãã¿ã³ãæŒãããšã«ããããŒã¿è»¢é
ãã¿ã³ã䜿çšããŠã¡ãã»ãŒãžãéä¿¡ããŠãåé¡ã¯ãããŸããïŒ Telegraf MarkupïŒExtraã䜿çšã§ããŸãïŒã å°é£ã¯ãããŒã¿ã®è»¢éãšãã®ãã¿ã³ãã¯ãªãã¯ãããã£ããã£ããå§ãŸããŸãã
InlineKeyboardButtonã®ããã¥ã¡ã³ãã«ãããšãæ倧ããŒã¿ãµã€ãºã¯64ãã€ãã®ã¿ã§ãã ã»ãšãã©ã®å Žåãããã§ååã§ããããããéçºãããšãã«æ€èšããŠãã ããã
次ã«ããã®ããŒã¿ãåŠçããå¿ èŠããããŸãããã¹ãŠã®ã³ãŒã«ããã¯ã¯1ã€ã®é¢æ°ã«å«ãŸãããããã¯ãªãã¯ãããã¿ã³ã®ã¿ã€ããéã¢ã»ã³ãã«ããå¿ èŠããããŸãã ãã®ãããããŒã¿ãšãšãã«ããã®ã¿ã€ãã転éããå¿ èŠããããŸãã ã«ãŒã¿ãŒãé Œã¿ãŸãã Telegrafã§ã¯ããã®ã«ãŒã¿ãŒã¯ãã§ã«éšåçã«å®è£ ãããŠããŸã-ããã¯ã«ãŒã¿ãŒã¯ã©ã¹ã§ãã äœæããããšã¯ã§ããŸãããã³ãã³ããšãã©ã¡ãŒã¿ãŒãèªåã§è§£æããå¿ èŠããããŸãïŒ äŸ ïŒã ãã©ã¡ãŒã¿ã»ãã¬ãŒã¿ãèªåã§çºæããå¿ èŠããããŸãã ç§ã®æèŠã§ã¯ãããã¯æåŸã®äžçŽã§ãããããªãã¯ãããšå ±ã«çããããšãã§ããŸãã
Google APIãšã®çžäºäœçš
ãããã¯ãŠãŒã¶ãŒãã£ã³ãã«ã®ãªã¹ããååŸããå¿ èŠãããããã®ããã«ã¯ããŒã¯ã³ãå¿ èŠã§ãã ã ããããªãã¯ãããåŸãããšãã§ããŸãïŒ
- Google Developers Consoleã䜿çšããŠãããžã§ã¯ããäœæãã
- ç®çã®APIãéžæããŸãã ç§ã®å Žåãããã¯Youtube Data APIã§ã
- OAuth 2.0ã¯ã©ã€ã¢ã³ãIDãäœæããŸãã [ãªãã€ã¬ã¯ãURIãèš±å¯]ãã£ãŒã«ãã§ãç®çã®ããŒãã§localhostãæå®ã§ããŸã
- ãã®çµæãClientIdãšClientSecretãäžããããŸã
- Google API Node.jsã¯ã©ã€ã¢ã³ããé 眮ããŸã
- ãã®ãã¢ã«åºã¥ããŠã googleapis .auth.OAuth2.generateAuthUrlã¡ãœããã䜿çšããŠãŠãŒã¶ãŒã®ãªã³ã¯ãçæããŸãã ããã«ã€ããŠè©³ããã¯ã ããã±ãŒãžã®èª¬æã«äŸã瀺ããŸã ã
- ãŠãŒã¶ãŒããªã³ã¯ãã¯ãªãã¯ããŠèš±å¯ãäžããåŸãã¢ã¯ã»ã¹ããŒã¯ã³ãååŸããŸã
ã¢ã¯ã»ã¹ããŒã¯ã³ã1æéããåç¶ããªãçç±
çè«çã«ã¯ã access_typeããofflineãã® Googleã¯æŽæ°ããŒã¯ã³ãæäŸããå¿ èŠããããŸãããããã§ã¯ãããŸããã ããã¯ã°ã©ãŠã³ãã§ãŠãŒã¶ãŒãã£ã³ãã«ã®ãªã¹ããæŽæ°ããå¿ èŠããã£ããããgoogleã§ãã®ãªãã·ã§ã³ãèŠã€ãããŸãããgenerate_authUrlã¡ãœããã«authorization_promptïŒ 'force'ãªãã·ã§ã³ãæž¡ããŸãã 次ã«ãGoogleã¯ãŠãŒã¶ãŒã«ã¢ã«ãŠã³ããžã®ãªãã©ã€ã³ã¢ã¯ã»ã¹ãèŠæ±ãããŠãŒã¶ãŒãåæããå Žåã¯ãåžæã®æŽæ°ããŒã¯ã³ãæäŸããŸãã ããã䜿çšããŠããã€ã§ãã¢ã¯ã»ã¹ããŒã¯ã³ãæŽæ°ãããã£ãã«ã®ãªã¹ããååŸã§ããŸãã
ã³ãŒã«ããã¯URLãä»ããŠãŠãŒã¶ãŒããŒã¿ã転éããæ¹æ³
ãããè¡ãã«ã¯ã stateãªãã·ã§ã³ãgenerateAuthUrlã¡ãœããã«æž¡ãããšãã§ããŸãã æååã®ã¿ãéä¿¡ã§ããããããã¹ãŠã®ãªããžã§ã¯ããã·ãªã¢ã«å/ãšã³ã³ãŒã/æå·åããå¿ èŠããããŸãã
転éãããããŒã¿ã«å¿ããŠãããŒã¿ããŒã¹ã«ããŒã¯ã³ãä¿åãããŠãŒã¶ãŒIDã§ããŒã¯ã³ãåä¿¡ã§ããŸãã
ã³ãŒã«ããã¯URLãIPã®å ŽåãGoogleã¯ããŒã¯ã³ãæäŸããŸãã
2ã€ã®æ¹æ³ããããŸãïŒãã¡ã€ã³ãè³Œå ¥ããããç¡æã§ç»é²ããŠã¿ãŠãã ããã
æåã¯ç¡æãæ¢ããŠããã®ã§ããããã®4nmvãµãŒãã¹ã®1 ã€ãžã®ãªã³ã¯ãå ±æããŸã-ã¬ãã«3ãã¡ã€ã³ãç¡æã§æäŸããnsã¬ã³ãŒããèšå®ã§ããŸãã 確ãã«ä»ã®ãµãŒãã¹ããããŸãïŒãªã³ã¯ãå ±æããŠãã ããïŒãããããç§ã®ããã«åããŸããã
ããããããã§ãç§ã¯GoDaddyã§69ã«ãŒãã«ã®å ç¢æ§ã®ããã«.comã¬ãã«2ãã¡ã€ã³ãè³Œå ¥ããŸããã
çç£
å®çšŒåç°å¢ã§ã¯ãDockerããã³Docker Composeã䜿çšããŸãã å¿ èŠã«å¿ããŠãç°ãªããã¹ãã£ã³ã°ãµã€ãã§ããããè¿ éã«çºçããã³æŽæ°ã§ããŸãã
Docker Logger
Node.jsã§ã®éçºäžã«ããšã©ãŒãšãããã°ã¡ãã»ãŒãžãã³ã³ãœãŒã«ã«æžã蟌ã¿ãŸãããããããdockerã«ãããã€ãããšãããããèŠãã®ãäžäŸ¿ã«ãªããŸããã
PapertrailãµãŒãã¹ãå©çšãããšãsyslog圢åŒãªã©ãã©ãããã§ãã¡ãã»ãŒãžãä¿åã§ããŸãã
ãã¹ãŠã®ã³ã³ãããããã¹ãŠã®ã¡ãã»ãŒãžãæž¡ãã«ã¯ã gliderlabs / logspout imageã䜿çšã§ããŸãã éåžžã«ç°¡åã«æ§æãããŸãã ããã¯docker-compose.ymlããã®ã¯ãªããã³ã°ã§ã
logger: image: gliderlabs/logspout:latest volumes: - /var/run/docker.sock:/var/run/docker.sock command: 'syslog+tls://logsX.papertrailapp.com:PORT' restart: always
ããã«ãŒã³ã³ãããŒã§Yarnãå®è¡ããæ¹æ³
... RUN curl -o- -L https://yarnpkg.com/install.sh | bash RUN $HOME/.yarn/bin/yarn install ...
çµæ
ãããã¯2016幎12ææ«ã«çºå£²ããã @ youtube_subs_watcher_botãšããååã§å ¥æã§ããŸã
â GitHubã®ãœãŒã¹