ã¯ãããŸããŠãã¡ãã¬ãŒã®ãšã³ãžãã¢çæ¬ã§ããæ°åã§å
¥ç€Ÿãä»å¹Žã§ 3 幎ç®ã«ãªããŸããŠã 2019 幎床ãšã³ãžãã¢æ°åã®ç ä¿® ãçµããŠããæ© 2 幎ãçµãšããšããŠããŸãã ãããªç§ã§ããå»å¹Žã® 11 æé ããå
æãŸã§ã®éããšãããããžã§ã¯ãã®ãªãŒããŒãä»»ããŠããã£ãŠããã®ã§ããã®ã話ããããŠããã ããŸãã ã¯ããã« ç§ã¯æ°åç ä¿®ãçµããŠããå»çä»è·æ±äººãµã€ã ãžã§ãã¡ãã¬ãŒ ã®ããŒã ã§éçºãããŠããŸãããããã®ãžã§ãã¡ãã¬ãŒãæ¯ãã瀟å
管çã·ã¹ãã ã®ãªãã¥ãŒã¢ã«ãããžã§ã¯ãã«åæããæºãã£ãŠããŸããã ãã¡ãã®ãããžã§ã¯ãã«ã€ããŸããŠã¯ãåŒç€Ÿãã¶ã€ããŒã®é
äºã ãã¶ã€ããŒããã¶ã€ã³ããŒã«ã䜿ããã«ãReact ã䜿ã£ãŠãã¶ã€ã³ãã話 ããåŒç€Ÿãšã³ãžãã¢ã®å±±ç°ã GraphQL, TypeScript, React ãçšããŠåå®å
šã«ç€Ÿå
ã·ã¹ãã ããªãã¥ãŒã¢ã«ãã話 ã以åããã°ã«ããŠããŸãã®ã§ããããããã°ããããŠã芧ãã ããã ãã®ç€Ÿå
管çã·ã¹ãã ãã©ã®ãããªæµãã§ãªãã¥ãŒã¢ã«ãããã®äžã§èªåã®åœ¹å²ãã©ãå€åãã©ã察å¿ããã®ããªã©ã«ã€ããŠã次ã®ç« ããã話ãããŠãããŸãã ãããžã§ã¯ãã«ã€ã㊠ãªãã¥ãŒã¢ã«ã®èæ¯ãã·ã¹ãã ã®æŠèŠã«ã€ããŠã¯äžã«ç޹ä»ããèšäºã§ã説æããŠãããã岿ããŸãããæ±è·è
ãæ±äººãæ²èŒãã顧客ã«é¢ããæ¥åãè¡ã£ãŠããã·ã¹ãã ãããã 1 幎åãããŠå·æ°ãããšãã倧ããªãããžã§ã¯ãã§ããã ã·ã¹ãã ã®äžã§ãæ±è·è
é¢é£ããPhase1ãã顧客é¢é£ããPhase2ããšããŠåå²ãããªãã¥ãŒã¢ã«ãé²ããŸããã ãããžã§ã¯ãå
ã§ã®èªåã®åœ¹å²ã®å€é· Phase1 ã®æåæã¯å
茩æ¹ãã¢ãŒããã¯ãã£ã®èšèšãã¹ã±ãžã¥ãŒãªã³ã°ãããŠããŸãããåœæãŸã æ°å 1 幎ç®ã§æªçãªç§ã§ããããæš©é管çã®ããŒãã«èšèšãããã¿ã¹ã¯ãã¢ãµã€ã³ããŠããããŸãããããã§ã¯è©³çްãçããŸãããåããŠã®ããŒãã«èšèšã§å³ãå·Šãåãããªãç¶æ
ãã責任æãæã£ãŠäœãšã圢ã«ããããšãã§ããïŒãã¡ãããªãã¥ãŒã¢ã«äžã«å€å°ã®èŠçŽãã¯ãããŸãããïŒå€§ããªéææãåŸãããšãèŠããŠããŸãã åçš®èšèšãæè¡éžå®ãéçºã®é²ãæ¹ãªã©ã倧æ¹åºãŸãæ¬æ Œçã«éçºãå§ãŸãããã§ãããPhase1 ã®éã¯å
茩瀟å¡ããããžã§ã¯ããªãŒããŒãšããŠåŒã£åŒµã£ãŠããã ããèªåã¯éçºã¡ã³ããŒã®äžå¡ãšã㊠API ã®äœæãªã©ã«å¥®éããŠããŸããã GraphQL ãšãã£ãæè¡ãã¹ã±ãžã¥ãŒã«ãå³å¯ã«åŒããããããžã§ã¯ãã§ã®éçºãªã©åããŠçµéšããããšãå€ã
ãããŸããããå
茩æ¹ã«ãµããŒããããã ããããåæãšåç£ç¢ç£šããªããåãçµãããããã§ãPhase1 ãä¹ãåãããšãã§ããŸããã ããŠããããããæ¬é¡ã«ãªããŸãããPhase2 ã«ãªããšãããžã§ã¯ãã¡ã³ããŒã®å
¥ãæ¿ããç§èªèº«ã®ç®æšèšå®ãéãªãããããžã§ã¯ããªãŒããŒãä»»ããŠãããããšã«ãªããŸãããŸãã¯ãããžã§ã¯ããªãŒããŒã«ä»»åœãããŠãããã©ããã£ãä»äºãããŠããã®ãã玹ä»ããŸãã ãããžã§ã¯ããªãŒããŒã®ä»äº ãããžã§ã¯ããªãŒããŒãšããŠæåŸ
ãããŠããããšã¯ä»¥äžã®éãã§ãã ãããžã§ã¯ã管ç ã·ã¹ãã èšèš éçº ããŒã ãããžã¡ã³ã ãããæŽã«çްååããç§ã®å®æ¥åãšç
§ããåãããªãã䞊ã¹ãŠã¿ããšãå€å°ç²åºŠã«ã°ãã€ãããããããããŸããã以äžã®ãããªããšãæããããŸãã èŠä»¶å®çŸ©ã»ç»é¢èšèšïŒãã£ã¬ã¯ã¿ãŒãšãã¶ã€ããŒäž»å°ã§é²ãã€ã€ããšã³ãžãã¢ãå®ããŒã¿ãæ¢åããžãã¯ãèžãŸãã芳ç¹ãæã¡åãããŠåå ããŸããïŒ éçºæ¹éã®æ€èš éçºã¿ã¹ã¯ãžã®èœãšã蟌㿠æè¡èª¿æ»ã»éžå® API èšèš å·¥æ°ç®åºã»ã¹ã±ãžã¥ãŒãªã³ã° å®è£
ã»ã¬ãã¥ãŒ QAïŒQuality AssuranceïŒãã¹ã ãªãªãŒã¹ãããžã¡ã³ã Phase2 ã¯æ®µéçã«ãªãªãŒã¹ãè¡ã£ãããããã®åºŠã« 1 ãã 9 ãŸã§ãç¹°ãè¿ããŠãããããªæµãã«ãªããŸãããŸããäžèšã«å ããå®äŸããŒãã£ã³ã°ã§ã®å ±åãéçºã¡ã³ããŒã®ã¿ã¹ã¯ãããžã¡ã³ããéæè¡ã£ãŠããŸããã ãã¡ããèŠåŽããããšã¯å€ããå
šéšãæããããšãããšããªããªãã®ã§ããããã®äžã§ãããã€ãã«çµã£ãäžã§ç޹ä»ããããšæããŸãã èŠåŽãšå·¥å€« 1. ãããããäœãããã°ããã®ãã ãŸãæåã«èŠåŽããããšã¯ãããããäœãããã°ããã®ãããããªãããšããããšã§ãããåãããå
ã»ã©æãããããªåããã€ã¡ãŒãžã§ããŠããããã§ã¯ãªããèšäºãæ¬ãèªã¿æŒã£ããå
茩ãšã® 1on1 ã§è³ªåæ»ãã«ããããšåºæ¬çãªç¥èãå©ã蟌ãããã§ãããå®éã«ãšã£ãæåã®åããšããŠã¯ãã§ããéšåãèŠã€ããŠãã£ãŠããããšããããšã ã£ããšæããŸãã èªåããªãŒããŒã«ä»»åœãããæç¹ã§ã®ãããžã§ã¯ãã®ç¶æ³ãšããŠã¯èŠä»¶å®çŸ©ãç»é¢èšèšãé²ãã§ããæäžã§ãããããããããŸãšãŸãã®ãåŸ
ã€ã®ã§ã¯ãªããå
šéšæ±ºãŸããªããšãããªãããšããšãçŸæç¹ã§ãããããšããåãåããŠåããŸããããããããšããããå°ããã€ãªãºã ãäœããæçµçã«å
ã»ã©åæãããããªäžéãã®ããšãã€ã¡ãŒãžã»å®è¡ã§ããããã«ãªã£ãã®ã ãšæããŸãã 2. å·¥æ°èŠç©ãã äžè¬çã«å·¥æ°èŠç©ããã«é¢ããèšäºã¯äžã®äžã«å€ãååšããŸãããç§ã®å Žåã¯å·¥æ°èŠç©ããã®æ¹æ³ãããããªãã£ããšãããããããã©ãããææ³ã§èŠç©ãã£ãã®ããã©ãããéžæè¢ãããã®ãããææ§ã«ããŠããããšãåœåã®åé¡ã§ããã åããŠèŠç©ãã£ãæã¯åã«éçºã¿ã¹ã¯ãç©ã¿äžããå·¥æ°ãå ±åããŠæºè¶³ããŠããŸããŸããããæ§ã
ãªæ¹ã®ãã£ãŒãããã¯ãåããããã¯ã䟡å€ãé«ããããã«ã©ãããåããã§ããã®ããèããå¿
èŠããã£ãããšãçæããŸãããåçŽã«å·¥æ°ãç©ã¿äžããå Žåãäºæ¥çãªéœåãèžãŸããŠãããã ã§éçºããå Žåãªã©ãããã€ãã®éžæè¢ãããããã®è»žã§èããå¿
èŠããã£ãããšãåŠã³ãŸããïŒãã®ææã¯å€ãªå€ãªå€¢ã®äžã§å·¥æ°èŠç©ãããããŠããã®ãä»ã§ã¯ããæãåºã§ãïŒã 3. æææ±ºå® ããã¯ãã€ã«ãªã£ãŠãæ£è§£ãååšããé¡ã®ãã®ã§ã¯ãªãã®ã§ãããç¹ã«æææ±ºå®ã«ã¯èŠåŽããŸãããæææ±ºå®ãšãã£ãŠãéçºæ¹éããæè¡éžå®ãŸã§æ§ã
ãªç²åºŠã®ãã®ããããŸãããç¹ã«æåããèŠåŽããã®ã¯æè¡çãªæ±ºå®ã§ããã ãããŸã§å
茩ã«é Œãããšã®å€ãã£ãç§ããããžã§ã¯ããªãŒããŒã«ãªã£ãçŽåŸããäœãããã§ããããã«ãªãããã§ã¯ãªãããšã¯æã
çœã
ã§ããããèªåãæ±ºããªããšããšçŠã£ãŠããŸã£ãŠããææããã£ããšæããŸãã ããã§äžåºŠç«ã¡æ¢ãŸã£ãŠæèããããšã¯ããäœãã§ããŠäœãã§ããªãã®ããä»è
ã«æç€ºãããããšã§ãããã¯ã£ãããšèªåã«è¶³ããŠããªãããšãä»è
ã«äŒããããšã§ãåšãããµããŒããããããªããšæããŸãããèªåèªèº«ãªã«ããããããšãªã®ãæç¢ºã«ãªãã®ã§åçŽãªããšã§ãã广çã§ãã£ããšæããŸããä»ã«ãéçºã¡ã³ããŒã®ææ¡ã§ãã€ã³ã»ãã·ã§ã³ããããåãå
¥ããŠã¿ãããšã广çã§ããã ãŸããæææ±ºå®ãšã¯æèãå°ãå€ãã£ãŠããŸãããã¢ãããããã¢ããã宿œããŠããŒã åãé«ãå±äººåããªããã€ã€éçºå¹çãåäžãããåãçµã¿ããæéãçµãŠã°çµã€ã»ã©å¹æã宿ã§ããŠè¯ãã£ããšæããŸãããã®ããã«ã¢ãžã£ã€ã«éçºã®ææ³ããããŒã ã«ãã£ããããææ³ãããã€ãåãå
¥ããããšãã§ããŸããã ãããžã§ã¯ããéããŠæé·ããããš ãããŸã§å°åºãã§è²ã
ãšã話ããããŠããã ããŸããããèªåãç¹ã«æé·ãããšæããŠããããšããŸãšããããŠããã ããŸãã äžéãã®çµéšãéããŠåŸããããªãŒãå ãAPI èšèšã ããã§ã¯ãªãäžéãå
šãŠãä»»ããŠããã ããããšã¯ãšãŠã倧ããªçµéšã«ãªããŸãããåããŠå人ã§ã¯ãªãããŒã ã»ãããžã§ã¯ãå
šäœãšããŠå¹çãè¯ããªãåããèããçµéšãã§ãããšæããŸãã æè¡å ãã¡ããå®è£
ãéããŠåŸãæè¡ã¯æ°ããããªãã»ã©ãããŸããããã®äžã§ãç¹ã«è²¬ä»»ãæã£ãŠä»è
ã®ã³ãŒããã¬ãã¥ãŒããããèªåãæžãã³ãŒãã®åœ±é¿ç¯å²ãã¹ã³ãŒããæèãç¶ããããšã倧ããªç³§ã«ãªã£ãŠããæ°ãããŸãã ãªã¹ã¯ç®¡çå ã¹ã±ãžã¥ãŒã«é
å»¶ã®ãªã¹ã¯ãæ¹åæ§ããããŠããŸããªã¹ã¯ãæè¡çãªãªã¹ã¯ãæ§ã
ãããŸãããããã®ãªã¹ã¯ãããžãèããåããããžã§ã¯ããªãŒããŒã«ã¯å¿
èŠã§ãã ãªã¹ã¯ç®¡çã«ãããŠãå
èªã¿ã倧åããšããèšãããŸãããç§ã®å Žåã¯ããå
茩瀟å¡ãããåžžã« 2 é±éå
ãèŠæ®ããŠããããšããå
·äœçãªæ¥æ°ã®ã¢ããã€ã¹ãããã ããŸãããå
·äœçã«ããããšã§ããããããšãæ³åãããããªããŸããããããã 1 å¹Žä»¥äžæ¯æ¥æèãå®è¡ãç¶ããããšãããããžã§ã¯ããããåãããšãã§ããèŠå ã«ããªã£ãŠãããšæããŸãããã¡ãããã®èšèã¯å®¶å®ã«ããããšæã£ãŠããŸãã 䟡å€ã«å¯ŸããèŠé äœãããããããã¯ãã®ãŠãŒã¶ãŒã«äŸ¡å€ãæäŸããããšãã®æå³ãçè§£ããŸããããããŸã§ã«æžããŠãããããªã¹ã±ãžã¥ãŒã«ç®¡çããªã¹ã¯ç®¡çãªã©ã¯ããããŸã§ãããžã§ã¯ããéè¡ããäžã§å¿
èŠãªä»äºã®äžã€ã§ãããªãã¯ãã§ãããããžã§ã¯ããéããŠã·ã¹ãã ã䜿ã£ãŠãã瀟å¡ãæŽã«ã¯ãã®å
ã®é¡§å®¢ã»æ±è·è
ãžåŠäœã«äŸ¡å€ãæäŸã§ãããèããã¹ãã§ãããäžææã¯ãã©ãããã®ãã»ãªã«ãããã®ãããšãããããžã§ã¯ãèªäœãå®éãããããšããèããããŠããªãææããããŸããã èŠéãçããªã£ãŠããããšã«åšãããã®ææã§æ°ã¥ãããšãã§ãããã以éã¯ãããããæ¬åœã«ãã®æ©èœã¯ããã®ãããªã©ãŠãŒã¶ãŒã®ç«å Žããã®èгç¹ãåŸã
ã«èº«ã«ä»ããããšãã§ããŸãããããããã£ãããšãªããåšããšãé »ç¹ã«ããªãããã®ãããè°è«ã§ããããã«ãªã£ããšæããŸããæ°å 1 幎ç®ã§å£é
žã£ã±ãèšãããŠãããç®çæèããããããè
¹èœã¡ããäœçŸããããšãã§ããŸããã æåŸã« æåŸãšãªããŸããããããžã§ã¯ããªãŒããŒã«ã€ããŠèªã£ãŠããç§ã§ãããå
¥ç€ŸãããŸã§ã¯ Web éçºæªçµéšã§ããŠãã¡ãã¬ãŒã§ã®æé·ãéåžžã«å®æããŠããŸãããããªã¡ãã¬ãŒã§ã¯ãšã³ãžãã¢ã»ãã¶ã€ããŒãã¯ããå€ãã®ããžã·ã§ã³ã§æ°ããªã¡ã³ããŒãåéããŠããŸãã®ã§ãå°ãã§ããèå³ããæã¡ããã ããæ¹ã¯ãæ¯éãæ°è»œã«ã話ããããŠããã ããã°ãšæããŸãïŒ ãããŸã§ãä»ãåãããã ããããããšãããããŸããã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
äºæ¥æ¬éš ãããã¯ãéçºå®€ãšã³ãžãã¢ã®æ¥äžã§ãã ãªã³ã©ã€ã³èšºçã»æè¬æå°ã»ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãCLINICSã ã®ãæ£è
ã»å»çæ©é¢ã«åããã¢ããªã±ãŒã·ã§ã³ã®æ©èœéçºãéçºåºç€ãã€ã³ãã©åšããæ
åœããŠãããŸãã ä»å CLINICS ãæäŸãããªã³ã©ã€ã³èšºçæ©èœã«ãç»é¢å
±ææ©èœãã远å ããŸããã®ã§ããã®èæ¯ã»æè¡çãªè©±ããŸãšããŸãã ç»é¢å
±ææ©èœå®è£
ã®èæ¯ CLINICS ãšãªã³ã©ã€ã³èšºç æ®æ®µçãããç
é¢ã«ããããšããå€ãã®å Žåã¯ç
é¢ã«è¡ããå»åž«ã®èšºå¯ã察é¢ã§åããäŒèšãããŠåž°ããšãã£ãæµãã«ãªãããšæããŸãã CLINICS ã®ãªã³ã©ã€ã³èšºçã¯ãã®æµããã€ã³ã¿ãŒããããéããŠæäŸãããµãŒãã¹ã§ãã â» ãªã³ã©ã€ã³èšºçã¯ãäžåºŠãå蚺çã§å¯Ÿé¢èšºçãåããéã«å»åž«ãå¯èœãšå€æããå Žåãæ¬¡å以éã®èšºå¯ã«ãããŠå¯èœã«ãªããŸãããŸããçŸåšã¯æ°åã³ãããŠã€ã«ã¹ææç察çæéæªçœ®ãšããŠãå蚺ãããªã³ã©ã€ã³èšºçãåããããšãå¯èœãšãªã£ãŠããŸãã CLINICS ãå©çšããå Žåãäºåã«äºçŽããæéã«ã¹ãããŸã㯠PC ã§åŸ
æ©ããããå»åž«ã®èšºå¯ããããªãã£ããã§åããäŒèšã¯ã¯ã¬ãžããã«ãŒãã§è¡ããããšããæµããšãªã£ãŠããŸãã ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãšããŠã® CLINICS 㯠2016 幎ã«ããªã³ã©ã€ã³èšºçã®ããã®ã·ã¹ãã ããšããŠããŒã³ã ããã 2018 幎ã«ã¯ã¯ã©ãŠãåé»åã«ã«ãæ©èœã ã 2019 幎ã«ã¯äºçŽç®¡çã·ã¹ãã æ©èœã ã 2020 幎ã«ã¯ãããã€ãè¬å±æ¯æŽã·ã¹ãã Pharms ãšã®é£æºæ©èœã远å ã ãæ£è
åãã¢ããªãããªã³ã©ã€ã³æè¬æå°ãã·ãŒã ã¬ã¹ã«åããããšãã§ããããã«ãªããŸããã ãããã¯ãéçºå®€ã§ã¯ããããªã³ã©ã€ã³èšºçæ©èœã»é»åã«ã«ãæ©èœã»äºçŽç®¡çæ©èœã»é£æºæ©èœã®æ¹åãæ¥ã
è¡ã£ãŠããŸãã ç»é¢å
±ææ©èœã®éèŠã®é«ãŸããå®è£
ã®æ±ºå® ãã®ããã« CLINICS ã®æ¹åãæ¥ã
è¡ãªã£ãŠããäžãæšå¹Žããå§ãŸã£ã æ°åã³ãããŠã€ã«ã¹ææçïŒCOVID-19ïŒ ã®æµè¡ã«äŒŽã£ãéèŠã®å¢å ã«ããããªã³ã©ã€ã³èšºçã®ä»¶æ°ãæ¥å¢ããŸããã CLINICS ãæ°å€ãã®å»çæ©é¢ã«ãå©çšããã ãäžã§ããªã³ã©ã€ã³èšºçã«é¢ããããŸããŸãªãèŠæãããã ãããã«ãªããŸããããã®äžã§ãç¹ã«å€ãã£ããã®ããä»å玹ä»ããç»é¢å
±ææ©èœã§ãã 察é¢ã§ã®èšºå¯ã®éã«å»åž«ãæ€æ»çµæãªã©ãæ£è
ã«èŠããªãã説æããããã«ããªã³ã©ã€ã³ã§èšºå¯ããå Žåã§ãè³æããªã¢ã«ã¿ã€ã ã§å
±æããªãã説æãã§ããããã«ãªãã°ãä»ãŸã§ä»¥äžã«ãªã³ã©ã€ã³ã§ã質ã®é«ã蚺å¯ãè¡ããããã«ãªããŸãã ãããã£ããŠãŒã¹ã±ãŒã¹ãèŠæãªã©ãæ€èšããçµæãCLINICS ãå©çšãããã¹ãŠã®å»çæ©é¢åã³æ£è
ã«ãšã£ãŠå€§ããªæ©æµãèŠèŸŒãŸããããããªã³ã©ã€ã³èšºå¯ïŒãããªãã£ããïŒäžã«å»åž«ã® PC ç»é¢ããªã¢ã«ã¿ã€ã ã§æ£è
ã«å
±æããæ©èœãšããŠå®è£
ãããããšã«ããŸããã ç»é¢å
±ææ©èœã®å®è£
ç»é¢å
±æãããå»åž«åŽåãã®ã³ãŒãã§ã©ããã£ãå®è£
æ¹æ³ãããã®ãã倧ãŸããªæµãããŸãšããŸãã ⻠以äžã«èšèŒããŠããã³ãŒãã¯èª¬æã®ããã®ç䌌ã³ãŒãã§ãã®ã§ããã®ãŸãŸã§ã¯åäœããªãããšã«ã泚æãã ããããŸããå»åž«åŽã®å®è£
äŸãæ²èŒããŠãããããæ£è
åŽïŒç»é¢å
±æãåããåŽïŒã®å®è£
ã¯å¥éå¿
èŠã«ãªããŸãã ãªã³ã©ã€ã³èšºå¯éå§ãŸã§ã®åŠç ãªã³ã©ã€ã³èšºå¯ãéå§ããã«ã¯å»åž«åŽã®ãã€ã¯ãšã«ã¡ã©ã§ååŸããæ
å ±ãæ£è
åŽã«éä»ããå¿
èŠããããŸããããã§ã¯ãããŸã§ã®å®è£
ã®æµããèŠãŠãããŸãã ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ã®ååŸ ãªã³ã©ã€ã³èšºå¯éå§æç¹ã§å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã®æ
å ±ãå
±æããããããŸãã¯ãããã®ã¹ããªãŒã ãååŸããå¿
èŠããããŸãããããã£ãã¡ãã£ã¢ã³ã³ãã³ãã®ã¹ããªãŒã ãåžãã€ã³ã¿ãŒãã§ã€ã¹ãšã㊠MediaStream ãå®çŸ©ãããŠããŸãã ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã¯ãäŸãã° MediaDevices.getUserMedia() ãå©çšããŠååŸã§ããŸãã const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); SkyWay çµç±ã§ãªã³ã©ã€ã³èšºå¯ãå§ãã WebRTC ã§ P2P ã®ãããªãã£ãããå©çšããããã«ã¯ãåæã®æ¥ç¶ã®ããã®åŠçåã³æ¥ç¶ã®ç¶æãªã©ã®åŠçãè¡ãå¿
èŠããããŸããåŒç€Ÿã§ã¯ãã®ãããã®åŠçã WebRTC SaaS ã® SkyWay åã³ãã® SDK ãå©çšããããšã§ç°¡ç¥åããŠããŸãã ãªã³ã©ã€ã³èšºå¯éå§æã«ã¯ãå
çšååŸããå»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã SkyWay ã® SDK ã«æž¡ãããšã§ãäžå¯Ÿäžã§ã®ãªã¢ã«ã¿ã€ã ãããªãã£ãããå®çŸã§ããŸãã import Peer , { MediaConnection } from "skyway-js" ; const peer = new Peer ({ key: "your-api-key" }); // äºåã«æ£è
ãšå
±æããŠããã peer id ã«å¯Ÿã㊠call ã¡ãœãããš MediaStream ãæž¡ãããšã§èšºå¯ãéå§ã§ããã const mediaConnection : MediaConnection = peer . call ( "shared-peer-id" , userMediaStream ); // 泚: æ£è
åŽã¯éä»ãããåŠçããã³ããªã³ã°ããæ©èœãå®è£
ããå¿
èŠããã ãããŸã§ããªã³ã©ã€ã³èšºå¯ãéå§ãããŸã§ã®åŠçã§ãã ⻠詳现㯠SkyWay å
¬åŒã® ãã¥ãŒããªã¢ã« ãªã©ãåç
§ãã ããã ç»é¢å
±æã®åŠç ãããŸã§ã§æ£è
ã«å¯ŸããŠå»åž«åŽã®ã«ã¡ã©ã»ãã€ã¯ã§ååŸãããæ åã»é³å£°ã衚瀺ãããŠããç¶æ
ã®ããããããåãæ¿ããåŠçãå¿
èŠã«ãªããŸããä»åã¯çŸåšæ¥ç¶ã«å©çšããŠãã MediaStream ããç»é¢å
±æçšã® MediaStream ã«å
¥ãæ¿ããããšã§å®çŸããŸããã ç»é¢ã® MediaStream ã®ååŸ ãŸãã¯å
±æããç»é¢ã® MediaStream ãååŸããå¿
èŠããããŸãããã㯠MediaDevices.getDisplayMedia() ã䜿ãããšã§å®çŸã§ããŸãã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); ç»é¢å
±æçšã® MediaStream ãäœã getDisplayMedia() ããå
±æããç»é¢ã® MediaStream ãååŸã§ãããã®ã®ããã®ãŸãŸå©çšãããšãã€ã¯ã®é³å£°ãå
¥ããŸããã ãã㯠getDisplayMedia() ããåãã MediaStream ã«ãã€ã¯ã®é³å£°ãå«ãŸããŠããªãããšãåå ãªã®ã§ãå¿
èŠãªç»åã»é³å£°ã®çµã¿åãããæã£ãç»é¢å
±æçšã® MediaStream ãäœæããããšã§å¯ŸåŠãã§ããŸãã MediaStreamTrack ãçµã¿ããããŠç»é¢å
±æçšã® MediaStream ãäœã ç»é¢å
±æçšã® MediaStream ãäœæããåã«ãŸããMediaStreamTrack ãš MediaStream ã®é¢ä¿ãçè§£ããå¿
èŠããããŸãã MediaStreamTrack ã¯ã¹ããªãŒã ã«å«ãŸããäžã€ã®ã¡ãã£ã¢ãã©ãã¯ã衚çŸãããã®ã§ãã kind ãšããèªã¿åãå°çšããããã£ãããããªãŒãã£ãªãã©ãã¯ã§ããã° "audio" ãããããªãã©ãã¯ã§ããã° "video" ãèšå®ãããŠããŸãã ãŸãã MediaStream ã¯è€æ°ã® MediaStreamTrack ããæãããªãŒãã£ãªãã©ãã¯ã»ãããªãã©ãã¯ãåãåºãã¡ãœããããããã MediaStream.getAudioTracks() ã» MediaStream.getVideoTracks() ãšããŠå®è£
ãããŠããŸãã ããããçµã¿åãããããšã§ããã€ã¯ãšç»é¢ã® MediaStreamTrack ãæã€ MediaStream ãäœãããšãã§ããããã SkyWay ã® SDK ã«æž¡ãããšã§ãç»é¢å
±æãå®çŸã§ããŸãã const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingMediaStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); MediaStream ã®å
¥ãæ¿ã æåŸã«ç»é¢å
±æç¶æ
ãžã®åãæ¿ãã§ãããã€ã¯ã»ã«ã¡ã©ãå
±æãããŠããç¶æ
ããã®åãæ¿ãã«ã¯ããã€ãã®æ¹æ³ãèããããŸãã äŸãã°ãå€éåã§ããã° MediaConnectionïŒ Skyway ã® SDK ã®åäœã§ããæ¥ç¶å
Peer ãžã®ã¡ãã£ã¢ãã£ãã«æ¥ç¶ãã管çããïŒã®å€éåãMediaStream ã®å€éåãMediaStreamTrack ã®å€éåãããããèããããŸãããããã®æ¹æ³ã¯ãã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ãæå¶ãªã©å®è£
äžã®éžæè¢ãå¢ããã¡ãªãããããäžæ¹ã§ãéä¿¡éãå€ããªã£ãŠããŸãç¹ããã¡ãªãããšèšããŸãã ä»åã¯å€éåãããã«æ¢åã® MediaStream ãåãæ¿ããå®è£
ã玹ä»ããŸãããã®æ¹æ³ã®ã¡ãªããã¯ãå€éåã«æ¯ã¹ããšéä¿¡éãå°ãªãããŸããã§ã« MediaStream ãäžã€ã§ããåæã§äœãããŠããå Žåã¯ãç»é¢å
±æãåããåŽã®å®è£
ã®å€æŽãäžèŠãšããç¹ã§ãã ãã®æ¹æ³ã¯ã SkyWay ã® SDK ã§ããã° MediaConnection ã® replaceStream ãšããã¡ãœãã ã«å¯ŸããŠæ°ãã MediaStream ãæž¡ãããšã§å®çŸãã§ããŸãã // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã // MediaConnection ã¯å
çš `peer.call` ããéã®è¿ãå€ãšããŠåããŠããããããããå©çšãã mediaConnection . replaceStream ( sharingMediaStream ); å®è£
åã«æžå¿µããŠãããã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ããªã©ãæ°ã«ãªãã»ã©ã¯ãªããå®çšã«è¶³ããããªå質ãä¿ã€ããšãã§ããããšã確èªããŠããŸãã å®è£
ã®å
šäœæŠèР以äžã®æµããå®è£
ãããšã次ã®ãããªã³ãŒãã«ãªããŸãã import Peer , { MediaConnection } from "skyway-js" ; /** å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ãå
±æããŠãªã³ã©ã€ã³èšºå¯éå§ãããšãããŸã§ **/ // getUserMedia()ã§ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ãååŸ const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); // Skyway sdk ã®åæååŠç const peer = new Peer ({ key: "your-api-key" }); // ãªã³ã©ã€ã³èšºå¯ã®éå§ const mediaConnection : MediaConnection = peer . call ( "peerId" , userMediaStream ); /** ç»é¢å
±æãéå§ããåŠç **/ // ç»é¢å
±æããç»é¢ã® stream ãåã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã mediaConnection . replaceStream ( sharingStream ); éçºäžã«ééããåé¡ãžã®å¯Ÿå¿ ã¹ãªãŒãã¢ãŒãã»å
±æã忢ãã¿ã³ãæŒãããšãã®å¯Ÿå¿ Google Chrome ã§ç»é¢å
±æã®éã«è¡šç€ºããããå
±æã忢ããã¿ã³ãæŒäžããããPC ãã¹ãªãŒãã¢ãŒãã«ãããšãç»é¢ã® MediaStreamTrack ãéåããŠããŸããŸãã ããã¯è©²åœã® MediaStreamTrack ã« "ended" ã®ã€ãã³ããªã¹ããç»é²ããŠããããšã§ãã³ããªã³ã°ã§ããŸãã displayVideoTrack . addEventListener ( "ended" , handleEndedEvent , { once: true }); TypeScript ã®åã®å¯Ÿå¿ çŸç¶ TypeScript ã®åã getDisplayMedia() ã«å¯Ÿå¿ããŠããªãã£ããããä»åã¯å®è£
ã®åèã«ããŠãã skyway-conf ã§å©çšãããŠããå ãæµçšãã圢ã§å¯Ÿå¿ãããŸããã declare global { interface MediaDevices { getDisplayMedia ( constraints : MediaStreamConstraints ): Promise < MediaStream >; } } ããã¯æ ¹æ¬çã«ã¯ TypeScript ã® dom.d.ts ã«åå®çŸ©ãå
¥ã£ãŠããªãããšãèµ·å ããŠããŸããã TypeScript4.4 ã§å¯Ÿå¿ããããããã§ã ã ãŸãšã æšä»ã®ç¶æ³ã«ããããªã³ã©ã€ã³èšºå¯ã®ããŒãºãé«ãŸããç»é¢å
±ææ©èœã®éèŠæ§ãé«ãŸããŸããã 蚺å¯äžã®ç»é¢å
±ææ©èœã¯ä»¥äžã® api ãçµã¿åãããããšã§å®çŸããããšãã§ããŸãã PC ç»é¢ã® MediaStream 㯠getDisplayMedia() ã䜿ãããšã§ååŸ MediaStream ã«å«ããé³å£°ã»ç»åã¹ããªãŒã ã倿Žãããå Žå㯠MediaStreamTrack ã®çµã¿åãããå€ããããšã§äœæ æ¥ç¶äžã® MediaStream ã®å€æŽã¯ SkyWay ã® SDK ã® MediaConnection.replaceStream() ãäœ¿ã æåŸã« CLINICS ã§ã¯æ¬çš¿ã§ç޹ä»ããç»é¢å
±æãªã©ã®æ°èŠæ©èœã®å°å
¥ãæ¥ã
ã®æ¹åãéããŠãå»çæ©é¢ã»æ£è
åæ¹ã«æ¯æããããããã¯ããç®æãéçºãè¡ã£ãŠããŸããèå³ãæããããšã³ãžãã¢ã®æ¹ãããã£ããããŸããããã² ãã¡ã ã«ãé£çµ¡ããã ããã°ãšæããŸãã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
äºæ¥æ¬éš ãããã¯ãéçºå®€ãšã³ãžãã¢ã®æ¥äžã§ãã ãªã³ã©ã€ã³èšºçã»æè¬æå°ã»ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãCLINICSã ã®ãæ£è
ã»å»çæ©é¢ã«åããã¢ããªã±ãŒã·ã§ã³ã®æ©èœéçºãéçºåºç€ãã€ã³ãã©åšããæ
åœããŠãããŸãã ä»å CLINICS ãæäŸãããªã³ã©ã€ã³èšºçæ©èœã«ãç»é¢å
±ææ©èœãã远å ããŸããã®ã§ããã®èæ¯ã»æè¡çãªè©±ããŸãšããŸãã ç»é¢å
±ææ©èœå®è£
ã®èæ¯ CLINICS ãšãªã³ã©ã€ã³èšºç æ®æ®µçãããç
é¢ã«ããããšããå€ãã®å Žåã¯ç
é¢ã«è¡ããå»åž«ã®èšºå¯ã察é¢ã§åããäŒèšãããŠåž°ããšãã£ãæµãã«ãªãããšæããŸãã CLINICS ã®ãªã³ã©ã€ã³èšºçã¯ãã®æµããã€ã³ã¿ãŒããããéããŠæäŸãããµãŒãã¹ã§ãã â» ãªã³ã©ã€ã³èšºçã¯ãäžåºŠãå蚺çã§å¯Ÿé¢èšºçãåããéã«å»åž«ãå¯èœãšå€æããå Žåãæ¬¡å以éã®èšºå¯ã«ãããŠå¯èœã«ãªããŸãããŸããçŸåšã¯æ°åã³ãããŠã€ã«ã¹ææç察çæéæªçœ®ãšããŠãå蚺ãããªã³ã©ã€ã³èšºçãåããããšãå¯èœãšãªã£ãŠããŸãã CLINICS ãå©çšããå Žåãäºåã«äºçŽããæéã«ã¹ãããŸã㯠PC ã§åŸ
æ©ããããå»åž«ã®èšºå¯ããããªãã£ããã§åããäŒèšã¯ã¯ã¬ãžããã«ãŒãã§è¡ããããšããæµããšãªã£ãŠããŸãã ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãšããŠã® CLINICS 㯠2016 幎ã«ããªã³ã©ã€ã³èšºçã®ããã®ã·ã¹ãã ããšããŠããŒã³ã ããã 2018 幎ã«ã¯ã¯ã©ãŠãåé»åã«ã«ãæ©èœã ã 2019 幎ã«ã¯äºçŽç®¡çã·ã¹ãã æ©èœã ã 2020 幎ã«ã¯ãããã€ãè¬å±æ¯æŽã·ã¹ãã Pharms ãšã®é£æºæ©èœã远å ã ãæ£è
åãã¢ããªãããªã³ã©ã€ã³æè¬æå°ãã·ãŒã ã¬ã¹ã«åããããšãã§ããããã«ãªããŸããã ãããã¯ãéçºå®€ã§ã¯ããããªã³ã©ã€ã³èšºçæ©èœã»é»åã«ã«ãæ©èœã»äºçŽç®¡çæ©èœã»é£æºæ©èœã®æ¹åãæ¥ã
è¡ã£ãŠããŸãã ç»é¢å
±ææ©èœã®éèŠã®é«ãŸããå®è£
ã®æ±ºå® ãã®ããã« CLINICS ã®æ¹åãæ¥ã
è¡ãªã£ãŠããäžãæšå¹Žããå§ãŸã£ã æ°åã³ãããŠã€ã«ã¹ææçïŒCOVID-19ïŒ ã®æµè¡ã«äŒŽã£ãéèŠã®å¢å ã«ããããªã³ã©ã€ã³èšºçã®ä»¶æ°ãæ¥å¢ããŸããã CLINICS ãæ°å€ãã®å»çæ©é¢ã«ãå©çšããã ãäžã§ããªã³ã©ã€ã³èšºçã«é¢ããããŸããŸãªãèŠæãããã ãããã«ãªããŸããããã®äžã§ãç¹ã«å€ãã£ããã®ããä»å玹ä»ããç»é¢å
±ææ©èœã§ãã 察é¢ã§ã®èšºå¯ã®éã«å»åž«ãæ€æ»çµæãªã©ãæ£è
ã«èŠããªãã説æããããã«ããªã³ã©ã€ã³ã§èšºå¯ããå Žåã§ãè³æããªã¢ã«ã¿ã€ã ã§å
±æããªãã説æãã§ããããã«ãªãã°ãä»ãŸã§ä»¥äžã«ãªã³ã©ã€ã³ã§ã質ã®é«ã蚺å¯ãè¡ããããã«ãªããŸãã ãããã£ããŠãŒã¹ã±ãŒã¹ãèŠæãªã©ãæ€èšããçµæãCLINICS ãå©çšãããã¹ãŠã®å»çæ©é¢åã³æ£è
ã«ãšã£ãŠå€§ããªæ©æµãèŠèŸŒãŸããããããªã³ã©ã€ã³èšºå¯ïŒãããªãã£ããïŒäžã«å»åž«ã® PC ç»é¢ããªã¢ã«ã¿ã€ã ã§æ£è
ã«å
±æããæ©èœãšããŠå®è£
ãããããšã«ããŸããã ç»é¢å
±ææ©èœã®å®è£
ç»é¢å
±æãããå»åž«åŽåãã®ã³ãŒãã§ã©ããã£ãå®è£
æ¹æ³ãããã®ãã倧ãŸããªæµãããŸãšããŸãã ⻠以äžã«èšèŒããŠããã³ãŒãã¯èª¬æã®ããã®ç䌌ã³ãŒãã§ãã®ã§ããã®ãŸãŸã§ã¯åäœããªãããšã«ã泚æãã ããããŸããå»åž«åŽã®å®è£
äŸãæ²èŒããŠãããããæ£è
åŽïŒç»é¢å
±æãåããåŽïŒã®å®è£
ã¯å¥éå¿
èŠã«ãªããŸãã ãªã³ã©ã€ã³èšºå¯éå§ãŸã§ã®åŠç ãªã³ã©ã€ã³èšºå¯ãéå§ããã«ã¯å»åž«åŽã®ãã€ã¯ãšã«ã¡ã©ã§ååŸããæ
å ±ãæ£è
åŽã«éä»ããå¿
èŠããããŸããããã§ã¯ãããŸã§ã®å®è£
ã®æµããèŠãŠãããŸãã ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ã®ååŸ ãªã³ã©ã€ã³èšºå¯éå§æç¹ã§å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã®æ
å ±ãå
±æããããããŸãã¯ãããã®ã¹ããªãŒã ãååŸããå¿
èŠããããŸãããããã£ãã¡ãã£ã¢ã³ã³ãã³ãã®ã¹ããªãŒã ãåžãã€ã³ã¿ãŒãã§ã€ã¹ãšã㊠MediaStream ãå®çŸ©ãããŠããŸãã ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã¯ãäŸãã° MediaDevices.getUserMedia() ãå©çšããŠååŸã§ããŸãã const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); SkyWay çµç±ã§ãªã³ã©ã€ã³èšºå¯ãå§ãã WebRTC ã§ P2P ã®ãããªãã£ãããå©çšããããã«ã¯ãåæã®æ¥ç¶ã®ããã®åŠçåã³æ¥ç¶ã®ç¶æãªã©ã®åŠçãè¡ãå¿
èŠããããŸããåŒç€Ÿã§ã¯ãã®ãããã®åŠçã WebRTC SaaS ã® SkyWay åã³ãã® SDK ãå©çšããããšã§ç°¡ç¥åããŠããŸãã ãªã³ã©ã€ã³èšºå¯éå§æã«ã¯ãå
çšååŸããå»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã SkyWay ã® SDK ã«æž¡ãããšã§ãäžå¯Ÿäžã§ã®ãªã¢ã«ã¿ã€ã ãããªãã£ãããå®çŸã§ããŸãã import Peer , { MediaConnection } from "skyway-js" ; const peer = new Peer ({ key: "your-api-key" }); // äºåã«æ£è
ãšå
±æããŠããã peer id ã«å¯Ÿã㊠call ã¡ãœãããš MediaStream ãæž¡ãããšã§èšºå¯ãéå§ã§ããã const mediaConnection : MediaConnection = peer . call ( "shared-peer-id" , userMediaStream ); // 泚: æ£è
åŽã¯éä»ãããåŠçããã³ããªã³ã°ããæ©èœãå®è£
ããå¿
èŠããã ãããŸã§ããªã³ã©ã€ã³èšºå¯ãéå§ãããŸã§ã®åŠçã§ãã ⻠詳现㯠SkyWay å
¬åŒã® ãã¥ãŒããªã¢ã« ãªã©ãåç
§ãã ããã ç»é¢å
±æã®åŠç ãããŸã§ã§æ£è
ã«å¯ŸããŠå»åž«åŽã®ã«ã¡ã©ã»ãã€ã¯ã§ååŸãããæ åã»é³å£°ã衚瀺ãããŠããç¶æ
ã®ããããããåãæ¿ããåŠçãå¿
èŠã«ãªããŸããä»åã¯çŸåšæ¥ç¶ã«å©çšããŠãã MediaStream ããç»é¢å
±æçšã® MediaStream ã«å
¥ãæ¿ããããšã§å®çŸããŸããã ç»é¢ã® MediaStream ã®ååŸ ãŸãã¯å
±æããç»é¢ã® MediaStream ãååŸããå¿
èŠããããŸãããã㯠MediaDevices.getDisplayMedia() ã䜿ãããšã§å®çŸã§ããŸãã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); ç»é¢å
±æçšã® MediaStream ãäœã getDisplayMedia() ããå
±æããç»é¢ã® MediaStream ãååŸã§ãããã®ã®ããã®ãŸãŸå©çšãããšãã€ã¯ã®é³å£°ãå
¥ããŸããã ãã㯠getDisplayMedia() ããåãã MediaStream ã«ãã€ã¯ã®é³å£°ãå«ãŸããŠããªãããšãåå ãªã®ã§ãå¿
èŠãªç»åã»é³å£°ã®çµã¿åãããæã£ãç»é¢å
±æçšã® MediaStream ãäœæããããšã§å¯ŸåŠãã§ããŸãã MediaStreamTrack ãçµã¿ããããŠç»é¢å
±æçšã® MediaStream ãäœã ç»é¢å
±æçšã® MediaStream ãäœæããåã«ãŸããMediaStreamTrack ãš MediaStream ã®é¢ä¿ãçè§£ããå¿
èŠããããŸãã MediaStreamTrack ã¯ã¹ããªãŒã ã«å«ãŸããäžã€ã®ã¡ãã£ã¢ãã©ãã¯ã衚çŸãããã®ã§ãã kind ãšããèªã¿åãå°çšããããã£ãããããªãŒãã£ãªãã©ãã¯ã§ããã° "audio" ãããããªãã©ãã¯ã§ããã° "video" ãèšå®ãããŠããŸãã ãŸãã MediaStream ã¯è€æ°ã® MediaStreamTrack ããæãããªãŒãã£ãªãã©ãã¯ã»ãããªãã©ãã¯ãåãåºãã¡ãœããããããã MediaStream.getAudioTracks() ã» MediaStream.getVideoTracks() ãšããŠå®è£
ãããŠããŸãã ããããçµã¿åãããããšã§ããã€ã¯ãšç»é¢ã® MediaStreamTrack ãæã€ MediaStream ãäœãããšãã§ããããã SkyWay ã® SDK ã«æž¡ãããšã§ãç»é¢å
±æãå®çŸã§ããŸãã const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingMediaStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); MediaStream ã®å
¥ãæ¿ã æåŸã«ç»é¢å
±æç¶æ
ãžã®åãæ¿ãã§ãããã€ã¯ã»ã«ã¡ã©ãå
±æãããŠããç¶æ
ããã®åãæ¿ãã«ã¯ããã€ãã®æ¹æ³ãèããããŸãã äŸãã°ãå€éåã§ããã° MediaConnectionïŒ Skyway ã® SDK ã®åäœã§ããæ¥ç¶å
Peer ãžã®ã¡ãã£ã¢ãã£ãã«æ¥ç¶ãã管çããïŒã®å€éåãMediaStream ã®å€éåãMediaStreamTrack ã®å€éåãããããèããããŸãããããã®æ¹æ³ã¯ãã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ãæå¶ãªã©å®è£
äžã®éžæè¢ãå¢ããã¡ãªãããããäžæ¹ã§ãéä¿¡éãå€ããªã£ãŠããŸãç¹ããã¡ãªãããšèšããŸãã ä»åã¯å€éåãããã«æ¢åã® MediaStream ãåãæ¿ããå®è£
ã玹ä»ããŸãããã®æ¹æ³ã®ã¡ãªããã¯ãå€éåã«æ¯ã¹ããšéä¿¡éãå°ãªãããŸããã§ã« MediaStream ãäžã€ã§ããåæã§äœãããŠããå Žåã¯ãç»é¢å
±æãåããåŽã®å®è£
ã®å€æŽãäžèŠãšããç¹ã§ãã ãã®æ¹æ³ã¯ã SkyWay ã® SDK ã§ããã° MediaConnection ã® replaceStream ãšããã¡ãœãã ã«å¯ŸããŠæ°ãã MediaStream ãæž¡ãããšã§å®çŸãã§ããŸãã // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã // MediaConnection ã¯å
çš `peer.call` ããéã®è¿ãå€ãšããŠåããŠããããããããå©çšãã mediaConnection . replaceStream ( sharingMediaStream ); å®è£
åã«æžå¿µããŠãããã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ããªã©ãæ°ã«ãªãã»ã©ã¯ãªããå®çšã«è¶³ããããªå質ãä¿ã€ããšãã§ããããšã確èªããŠããŸãã å®è£
ã®å
šäœæŠèР以äžã®æµããå®è£
ãããšã次ã®ãããªã³ãŒãã«ãªããŸãã import Peer , { MediaConnection } from "skyway-js" ; /** å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ãå
±æããŠãªã³ã©ã€ã³èšºå¯éå§ãããšãããŸã§ **/ // getUserMedia()ã§ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ãååŸ const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); // Skyway sdk ã®åæååŠç const peer = new Peer ({ key: "your-api-key" }); // ãªã³ã©ã€ã³èšºå¯ã®éå§ const mediaConnection : MediaConnection = peer . call ( "peerId" , userMediaStream ); /** ç»é¢å
±æãéå§ããåŠç **/ // ç»é¢å
±æããç»é¢ã® stream ãåã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã mediaConnection . replaceStream ( sharingStream ); éçºäžã«ééããåé¡ãžã®å¯Ÿå¿ ã¹ãªãŒãã¢ãŒãã»å
±æã忢ãã¿ã³ãæŒãããšãã®å¯Ÿå¿ Google Chrome ã§ç»é¢å
±æã®éã«è¡šç€ºããããå
±æã忢ããã¿ã³ãæŒäžããããPC ãã¹ãªãŒãã¢ãŒãã«ãããšãç»é¢ã® MediaStreamTrack ãéåããŠããŸããŸãã ããã¯è©²åœã® MediaStreamTrack ã« "ended" ã®ã€ãã³ããªã¹ããç»é²ããŠããããšã§ãã³ããªã³ã°ã§ããŸãã displayVideoTrack . addEventListener ( "ended" , handleEndedEvent , { once: true }); TypeScript ã®åã®å¯Ÿå¿ çŸç¶ TypeScript ã®åã getDisplayMedia() ã«å¯Ÿå¿ããŠããªãã£ããããä»åã¯å®è£
ã®åèã«ããŠãã skyway-conf ã§å©çšãããŠããå ãæµçšãã圢ã§å¯Ÿå¿ãããŸããã declare global { interface MediaDevices { getDisplayMedia ( constraints : MediaStreamConstraints ): Promise < MediaStream >; } } ããã¯æ ¹æ¬çã«ã¯ TypeScript ã® dom.d.ts ã«åå®çŸ©ãå
¥ã£ãŠããªãããšãèµ·å ããŠããŸããã TypeScript4.4 ã§å¯Ÿå¿ããããããã§ã ã ãŸãšã æšä»ã®ç¶æ³ã«ããããªã³ã©ã€ã³èšºå¯ã®ããŒãºãé«ãŸããç»é¢å
±ææ©èœã®éèŠæ§ãé«ãŸããŸããã 蚺å¯äžã®ç»é¢å
±ææ©èœã¯ä»¥äžã® api ãçµã¿åãããããšã§å®çŸããããšãã§ããŸãã PC ç»é¢ã® MediaStream 㯠getDisplayMedia() ã䜿ãããšã§ååŸ MediaStream ã«å«ããé³å£°ã»ç»åã¹ããªãŒã ã倿Žãããå Žå㯠MediaStreamTrack ã®çµã¿åãããå€ããããšã§äœæ æ¥ç¶äžã® MediaStream ã®å€æŽã¯ SkyWay ã® SDK ã® MediaConnection.replaceStream() ãäœ¿ã æåŸã« CLINICS ã§ã¯æ¬çš¿ã§ç޹ä»ããç»é¢å
±æãªã©ã®æ°èŠæ©èœã®å°å
¥ãæ¥ã
ã®æ¹åãéããŠãå»çæ©é¢ã»æ£è
åæ¹ã«æ¯æããããããã¯ããç®æãéçºãè¡ã£ãŠããŸããèå³ãæããããšã³ãžãã¢ã®æ¹ãããã£ããããŸããããã² ãã¡ã ã«ãé£çµ¡ããã ããã°ãšæããŸãã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
äºæ¥æ¬éš ãããã¯ãéçºå®€ãšã³ãžãã¢ã®æ¥äžã§ãã ãªã³ã©ã€ã³èšºçã»æè¬æå°ã»ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãCLINICSã ã®ãæ£è
ã»å»çæ©é¢ã«åããã¢ããªã±ãŒã·ã§ã³ã®æ©èœéçºãéçºåºç€ãã€ã³ãã©åšããæ
åœããŠãããŸãã ä»å CLINICS ãæäŸãããªã³ã©ã€ã³èšºçæ©èœã«ãç»é¢å
±ææ©èœãã远å ããŸããã®ã§ããã®èæ¯ã»æè¡çãªè©±ããŸãšããŸãã ç»é¢å
±ææ©èœå®è£
ã®èæ¯ CLINICS ãšãªã³ã©ã€ã³èšºç æ®æ®µçãããç
é¢ã«ããããšããå€ãã®å Žåã¯ç
é¢ã«è¡ããå»åž«ã®èšºå¯ã察é¢ã§åããäŒèšãããŠåž°ããšãã£ãæµãã«ãªãããšæããŸãã CLINICS ã®ãªã³ã©ã€ã³èšºçã¯ãã®æµããã€ã³ã¿ãŒããããéããŠæäŸãããµãŒãã¹ã§ãã â» ãªã³ã©ã€ã³èšºçã¯ãäžåºŠãå蚺çã§å¯Ÿé¢èšºçãåããéã«å»åž«ãå¯èœãšå€æããå Žåãæ¬¡å以éã®èšºå¯ã«ãããŠå¯èœã«ãªããŸãããŸããçŸåšã¯æ°åã³ãããŠã€ã«ã¹ææç察çæéæªçœ®ãšããŠãå蚺ãããªã³ã©ã€ã³èšºçãåããããšãå¯èœãšãªã£ãŠããŸãã CLINICS ãå©çšããå Žåãäºåã«äºçŽããæéã«ã¹ãããŸã㯠PC ã§åŸ
æ©ããããå»åž«ã®èšºå¯ããããªãã£ããã§åããäŒèšã¯ã¯ã¬ãžããã«ãŒãã§è¡ããããšããæµããšãªã£ãŠããŸãã ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãšããŠã® CLINICS 㯠2016 幎ã«ããªã³ã©ã€ã³èšºçã®ããã®ã·ã¹ãã ããšããŠããŒã³ã ããã 2018 幎ã«ã¯ã¯ã©ãŠãåé»åã«ã«ãæ©èœã ã 2019 幎ã«ã¯äºçŽç®¡çã·ã¹ãã æ©èœã ã 2020 幎ã«ã¯ãããã€ãè¬å±æ¯æŽã·ã¹ãã Pharms ãšã®é£æºæ©èœã远å ã ãæ£è
åãã¢ããªãããªã³ã©ã€ã³æè¬æå°ãã·ãŒã ã¬ã¹ã«åããããšãã§ããããã«ãªããŸããã ãããã¯ãéçºå®€ã§ã¯ããããªã³ã©ã€ã³èšºçæ©èœã»é»åã«ã«ãæ©èœã»äºçŽç®¡çæ©èœã»é£æºæ©èœã®æ¹åãæ¥ã
è¡ã£ãŠããŸãã ç»é¢å
±ææ©èœã®éèŠã®é«ãŸããå®è£
ã®æ±ºå® ãã®ããã« CLINICS ã®æ¹åãæ¥ã
è¡ãªã£ãŠããäžãæšå¹Žããå§ãŸã£ã æ°åã³ãããŠã€ã«ã¹ææçïŒCOVID-19ïŒ ã®æµè¡ã«äŒŽã£ãéèŠã®å¢å ã«ããããªã³ã©ã€ã³èšºçã®ä»¶æ°ãæ¥å¢ããŸããã CLINICS ãæ°å€ãã®å»çæ©é¢ã«ãå©çšããã ãäžã§ããªã³ã©ã€ã³èšºçã«é¢ããããŸããŸãªãèŠæãããã ãããã«ãªããŸããããã®äžã§ãç¹ã«å€ãã£ããã®ããä»å玹ä»ããç»é¢å
±ææ©èœã§ãã 察é¢ã§ã®èšºå¯ã®éã«å»åž«ãæ€æ»çµæãªã©ãæ£è
ã«èŠããªãã説æããããã«ããªã³ã©ã€ã³ã§èšºå¯ããå Žåã§ãè³æããªã¢ã«ã¿ã€ã ã§å
±æããªãã説æãã§ããããã«ãªãã°ãä»ãŸã§ä»¥äžã«ãªã³ã©ã€ã³ã§ã質ã®é«ã蚺å¯ãè¡ããããã«ãªããŸãã ãããã£ããŠãŒã¹ã±ãŒã¹ãèŠæãªã©ãæ€èšããçµæãCLINICS ãå©çšãããã¹ãŠã®å»çæ©é¢åã³æ£è
ã«ãšã£ãŠå€§ããªæ©æµãèŠèŸŒãŸããããããªã³ã©ã€ã³èšºå¯ïŒãããªãã£ããïŒäžã«å»åž«ã® PC ç»é¢ããªã¢ã«ã¿ã€ã ã§æ£è
ã«å
±æããæ©èœãšããŠå®è£
ãããããšã«ããŸããã ç»é¢å
±ææ©èœã®å®è£
ç»é¢å
±æãããå»åž«åŽåãã®ã³ãŒãã§ã©ããã£ãå®è£
æ¹æ³ãããã®ãã倧ãŸããªæµãããŸãšããŸãã ⻠以äžã«èšèŒããŠããã³ãŒãã¯èª¬æã®ããã®ç䌌ã³ãŒãã§ãã®ã§ããã®ãŸãŸã§ã¯åäœããªãããšã«ã泚æãã ããããŸããå»åž«åŽã®å®è£
äŸãæ²èŒããŠãããããæ£è
åŽïŒç»é¢å
±æãåããåŽïŒã®å®è£
ã¯å¥éå¿
èŠã«ãªããŸãã ãªã³ã©ã€ã³èšºå¯éå§ãŸã§ã®åŠç ãªã³ã©ã€ã³èšºå¯ãéå§ããã«ã¯å»åž«åŽã®ãã€ã¯ãšã«ã¡ã©ã§ååŸããæ
å ±ãæ£è
åŽã«éä»ããå¿
èŠããããŸããããã§ã¯ãããŸã§ã®å®è£
ã®æµããèŠãŠãããŸãã ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ã®ååŸ ãªã³ã©ã€ã³èšºå¯éå§æç¹ã§å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã®æ
å ±ãå
±æããããããŸãã¯ãããã®ã¹ããªãŒã ãååŸããå¿
èŠããããŸãããããã£ãã¡ãã£ã¢ã³ã³ãã³ãã®ã¹ããªãŒã ãåžãã€ã³ã¿ãŒãã§ã€ã¹ãšã㊠MediaStream ãå®çŸ©ãããŠããŸãã ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã¯ãäŸãã° MediaDevices.getUserMedia() ãå©çšããŠååŸã§ããŸãã const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); SkyWay çµç±ã§ãªã³ã©ã€ã³èšºå¯ãå§ãã WebRTC ã§ P2P ã®ãããªãã£ãããå©çšããããã«ã¯ãåæã®æ¥ç¶ã®ããã®åŠçåã³æ¥ç¶ã®ç¶æãªã©ã®åŠçãè¡ãå¿
èŠããããŸããåŒç€Ÿã§ã¯ãã®ãããã®åŠçã WebRTC SaaS ã® SkyWay åã³ãã® SDK ãå©çšããããšã§ç°¡ç¥åããŠããŸãã ãªã³ã©ã€ã³èšºå¯éå§æã«ã¯ãå
çšååŸããå»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã SkyWay ã® SDK ã«æž¡ãããšã§ãäžå¯Ÿäžã§ã®ãªã¢ã«ã¿ã€ã ãããªãã£ãããå®çŸã§ããŸãã import Peer , { MediaConnection } from "skyway-js" ; const peer = new Peer ({ key: "your-api-key" }); // äºåã«æ£è
ãšå
±æããŠããã peer id ã«å¯Ÿã㊠call ã¡ãœãããš MediaStream ãæž¡ãããšã§èšºå¯ãéå§ã§ããã const mediaConnection : MediaConnection = peer . call ( "shared-peer-id" , userMediaStream ); // 泚: æ£è
åŽã¯éä»ãããåŠçããã³ããªã³ã°ããæ©èœãå®è£
ããå¿
èŠããã ãããŸã§ããªã³ã©ã€ã³èšºå¯ãéå§ãããŸã§ã®åŠçã§ãã ⻠詳现㯠SkyWay å
¬åŒã® ãã¥ãŒããªã¢ã« ãªã©ãåç
§ãã ããã ç»é¢å
±æã®åŠç ãããŸã§ã§æ£è
ã«å¯ŸããŠå»åž«åŽã®ã«ã¡ã©ã»ãã€ã¯ã§ååŸãããæ åã»é³å£°ã衚瀺ãããŠããç¶æ
ã®ããããããåãæ¿ããåŠçãå¿
èŠã«ãªããŸããä»åã¯çŸåšæ¥ç¶ã«å©çšããŠãã MediaStream ããç»é¢å
±æçšã® MediaStream ã«å
¥ãæ¿ããããšã§å®çŸããŸããã ç»é¢ã® MediaStream ã®ååŸ ãŸãã¯å
±æããç»é¢ã® MediaStream ãååŸããå¿
èŠããããŸãããã㯠MediaDevices.getDisplayMedia() ã䜿ãããšã§å®çŸã§ããŸãã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); ç»é¢å
±æçšã® MediaStream ãäœã getDisplayMedia() ããå
±æããç»é¢ã® MediaStream ãååŸã§ãããã®ã®ããã®ãŸãŸå©çšãããšãã€ã¯ã®é³å£°ãå
¥ããŸããã ãã㯠getDisplayMedia() ããåãã MediaStream ã«ãã€ã¯ã®é³å£°ãå«ãŸããŠããªãããšãåå ãªã®ã§ãå¿
èŠãªç»åã»é³å£°ã®çµã¿åãããæã£ãç»é¢å
±æçšã® MediaStream ãäœæããããšã§å¯ŸåŠãã§ããŸãã MediaStreamTrack ãçµã¿ããããŠç»é¢å
±æçšã® MediaStream ãäœã ç»é¢å
±æçšã® MediaStream ãäœæããåã«ãŸããMediaStreamTrack ãš MediaStream ã®é¢ä¿ãçè§£ããå¿
èŠããããŸãã MediaStreamTrack ã¯ã¹ããªãŒã ã«å«ãŸããäžã€ã®ã¡ãã£ã¢ãã©ãã¯ã衚çŸãããã®ã§ãã kind ãšããèªã¿åãå°çšããããã£ãããããªãŒãã£ãªãã©ãã¯ã§ããã° "audio" ãããããªãã©ãã¯ã§ããã° "video" ãèšå®ãããŠããŸãã ãŸãã MediaStream ã¯è€æ°ã® MediaStreamTrack ããæãããªãŒãã£ãªãã©ãã¯ã»ãããªãã©ãã¯ãåãåºãã¡ãœããããããã MediaStream.getAudioTracks() ã» MediaStream.getVideoTracks() ãšããŠå®è£
ãããŠããŸãã ããããçµã¿åãããããšã§ããã€ã¯ãšç»é¢ã® MediaStreamTrack ãæã€ MediaStream ãäœãããšãã§ããããã SkyWay ã® SDK ã«æž¡ãããšã§ãç»é¢å
±æãå®çŸã§ããŸãã const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingMediaStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); MediaStream ã®å
¥ãæ¿ã æåŸã«ç»é¢å
±æç¶æ
ãžã®åãæ¿ãã§ãããã€ã¯ã»ã«ã¡ã©ãå
±æãããŠããç¶æ
ããã®åãæ¿ãã«ã¯ããã€ãã®æ¹æ³ãèããããŸãã äŸãã°ãå€éåã§ããã° MediaConnectionïŒ Skyway ã® SDK ã®åäœã§ããæ¥ç¶å
Peer ãžã®ã¡ãã£ã¢ãã£ãã«æ¥ç¶ãã管çããïŒã®å€éåãMediaStream ã®å€éåãMediaStreamTrack ã®å€éåãããããèããããŸãããããã®æ¹æ³ã¯ãã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ãæå¶ãªã©å®è£
äžã®éžæè¢ãå¢ããã¡ãªãããããäžæ¹ã§ãéä¿¡éãå€ããªã£ãŠããŸãç¹ããã¡ãªãããšèšããŸãã ä»åã¯å€éåãããã«æ¢åã® MediaStream ãåãæ¿ããå®è£
ã玹ä»ããŸãããã®æ¹æ³ã®ã¡ãªããã¯ãå€éåã«æ¯ã¹ããšéä¿¡éãå°ãªãããŸããã§ã« MediaStream ãäžã€ã§ããåæã§äœãããŠããå Žåã¯ãç»é¢å
±æãåããåŽã®å®è£
ã®å€æŽãäžèŠãšããç¹ã§ãã ãã®æ¹æ³ã¯ã SkyWay ã® SDK ã§ããã° MediaConnection ã® replaceStream ãšããã¡ãœãã ã«å¯ŸããŠæ°ãã MediaStream ãæž¡ãããšã§å®çŸãã§ããŸãã // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã // MediaConnection ã¯å
çš `peer.call` ããéã®è¿ãå€ãšããŠåããŠããããããããå©çšãã mediaConnection . replaceStream ( sharingMediaStream ); å®è£
åã«æžå¿µããŠãããã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ããªã©ãæ°ã«ãªãã»ã©ã¯ãªããå®çšã«è¶³ããããªå質ãä¿ã€ããšãã§ããããšã確èªããŠããŸãã å®è£
ã®å
šäœæŠèР以äžã®æµããå®è£
ãããšã次ã®ãããªã³ãŒãã«ãªããŸãã import Peer , { MediaConnection } from "skyway-js" ; /** å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ãå
±æããŠãªã³ã©ã€ã³èšºå¯éå§ãããšãããŸã§ **/ // getUserMedia()ã§ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ãååŸ const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); // Skyway sdk ã®åæååŠç const peer = new Peer ({ key: "your-api-key" }); // ãªã³ã©ã€ã³èšºå¯ã®éå§ const mediaConnection : MediaConnection = peer . call ( "peerId" , userMediaStream ); /** ç»é¢å
±æãéå§ããåŠç **/ // ç»é¢å
±æããç»é¢ã® stream ãåã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã mediaConnection . replaceStream ( sharingStream ); éçºäžã«ééããåé¡ãžã®å¯Ÿå¿ ã¹ãªãŒãã¢ãŒãã»å
±æã忢ãã¿ã³ãæŒãããšãã®å¯Ÿå¿ Google Chrome ã§ç»é¢å
±æã®éã«è¡šç€ºããããå
±æã忢ããã¿ã³ãæŒäžããããPC ãã¹ãªãŒãã¢ãŒãã«ãããšãç»é¢ã® MediaStreamTrack ãéåããŠããŸããŸãã ããã¯è©²åœã® MediaStreamTrack ã« "ended" ã®ã€ãã³ããªã¹ããç»é²ããŠããããšã§ãã³ããªã³ã°ã§ããŸãã displayVideoTrack . addEventListener ( "ended" , handleEndedEvent , { once: true }); TypeScript ã®åã®å¯Ÿå¿ çŸç¶ TypeScript ã®åã getDisplayMedia() ã«å¯Ÿå¿ããŠããªãã£ããããä»åã¯å®è£
ã®åèã«ããŠãã skyway-conf ã§å©çšãããŠããå ãæµçšãã圢ã§å¯Ÿå¿ãããŸããã declare global { interface MediaDevices { getDisplayMedia ( constraints : MediaStreamConstraints ): Promise < MediaStream >; } } ããã¯æ ¹æ¬çã«ã¯ TypeScript ã® dom.d.ts ã«åå®çŸ©ãå
¥ã£ãŠããªãããšãèµ·å ããŠããŸããã TypeScript4.4 ã§å¯Ÿå¿ããããããã§ã ã ãŸãšã æšä»ã®ç¶æ³ã«ããããªã³ã©ã€ã³èšºå¯ã®ããŒãºãé«ãŸããç»é¢å
±ææ©èœã®éèŠæ§ãé«ãŸããŸããã 蚺å¯äžã®ç»é¢å
±ææ©èœã¯ä»¥äžã® api ãçµã¿åãããããšã§å®çŸããããšãã§ããŸãã PC ç»é¢ã® MediaStream 㯠getDisplayMedia() ã䜿ãããšã§ååŸ MediaStream ã«å«ããé³å£°ã»ç»åã¹ããªãŒã ã倿Žãããå Žå㯠MediaStreamTrack ã®çµã¿åãããå€ããããšã§äœæ æ¥ç¶äžã® MediaStream ã®å€æŽã¯ SkyWay ã® SDK ã® MediaConnection.replaceStream() ãäœ¿ã æåŸã« CLINICS ã§ã¯æ¬çš¿ã§ç޹ä»ããç»é¢å
±æãªã©ã®æ°èŠæ©èœã®å°å
¥ãæ¥ã
ã®æ¹åãéããŠãå»çæ©é¢ã»æ£è
åæ¹ã«æ¯æããããããã¯ããç®æãéçºãè¡ã£ãŠããŸããèå³ãæããããšã³ãžãã¢ã®æ¹ãããã£ããããŸããããã² ãã¡ã ã«ãé£çµ¡ããã ããã°ãšæããŸãã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
äºæ¥æ¬éš ãããã¯ãéçºå®€ãšã³ãžãã¢ã®æ¥äžã§ãã ãªã³ã©ã€ã³èšºçã»æè¬æå°ã»ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãCLINICSã ã®ãæ£è
ã»å»çæ©é¢ã«åããã¢ããªã±ãŒã·ã§ã³ã®æ©èœéçºãéçºåºç€ãã€ã³ãã©åšããæ
åœããŠãããŸãã ä»å CLINICS ãæäŸãããªã³ã©ã€ã³èšºçæ©èœã«ãç»é¢å
±ææ©èœãã远å ããŸããã®ã§ããã®èæ¯ã»æè¡çãªè©±ããŸãšããŸãã ç»é¢å
±ææ©èœå®è£
ã®èæ¯ CLINICS ãšãªã³ã©ã€ã³èšºç æ®æ®µçãããç
é¢ã«ããããšããå€ãã®å Žåã¯ç
é¢ã«è¡ããå»åž«ã®èšºå¯ã察é¢ã§åããäŒèšãããŠåž°ããšãã£ãæµãã«ãªãããšæããŸãã CLINICS ã®ãªã³ã©ã€ã³èšºçã¯ãã®æµããã€ã³ã¿ãŒããããéããŠæäŸãããµãŒãã¹ã§ãã â» ãªã³ã©ã€ã³èšºçã¯ãäžåºŠãå蚺çã§å¯Ÿé¢èšºçãåããéã«å»åž«ãå¯èœãšå€æããå Žåãæ¬¡å以éã®èšºå¯ã«ãããŠå¯èœã«ãªããŸãããŸããçŸåšã¯æ°åã³ãããŠã€ã«ã¹ææç察çæéæªçœ®ãšããŠãå蚺ãããªã³ã©ã€ã³èšºçãåããããšãå¯èœãšãªã£ãŠããŸãã CLINICS ãå©çšããå Žåãäºåã«äºçŽããæéã«ã¹ãããŸã㯠PC ã§åŸ
æ©ããããå»åž«ã®èšºå¯ããããªãã£ããã§åããäŒèšã¯ã¯ã¬ãžããã«ãŒãã§è¡ããããšããæµããšãªã£ãŠããŸãã ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãšããŠã® CLINICS 㯠2016 幎ã«ããªã³ã©ã€ã³èšºçã®ããã®ã·ã¹ãã ããšããŠããŒã³ã ããã 2018 幎ã«ã¯ã¯ã©ãŠãåé»åã«ã«ãæ©èœã ã 2019 幎ã«ã¯äºçŽç®¡çã·ã¹ãã æ©èœã ã 2020 幎ã«ã¯ãããã€ãè¬å±æ¯æŽã·ã¹ãã Pharms ãšã®é£æºæ©èœã远å ã ãæ£è
åãã¢ããªãããªã³ã©ã€ã³æè¬æå°ãã·ãŒã ã¬ã¹ã«åããããšãã§ããããã«ãªããŸããã ãããã¯ãéçºå®€ã§ã¯ããããªã³ã©ã€ã³èšºçæ©èœã»é»åã«ã«ãæ©èœã»äºçŽç®¡çæ©èœã»é£æºæ©èœã®æ¹åãæ¥ã
è¡ã£ãŠããŸãã ç»é¢å
±ææ©èœã®éèŠã®é«ãŸããå®è£
ã®æ±ºå® ãã®ããã« CLINICS ã®æ¹åãæ¥ã
è¡ãªã£ãŠããäžãæšå¹Žããå§ãŸã£ã æ°åã³ãããŠã€ã«ã¹ææçïŒCOVID-19ïŒ ã®æµè¡ã«äŒŽã£ãéèŠã®å¢å ã«ããããªã³ã©ã€ã³èšºçã®ä»¶æ°ãæ¥å¢ããŸããã CLINICS ãæ°å€ãã®å»çæ©é¢ã«ãå©çšããã ãäžã§ããªã³ã©ã€ã³èšºçã«é¢ããããŸããŸãªãèŠæãããã ãããã«ãªããŸããããã®äžã§ãç¹ã«å€ãã£ããã®ããä»å玹ä»ããç»é¢å
±ææ©èœã§ãã 察é¢ã§ã®èšºå¯ã®éã«å»åž«ãæ€æ»çµæãªã©ãæ£è
ã«èŠããªãã説æããããã«ããªã³ã©ã€ã³ã§èšºå¯ããå Žåã§ãè³æããªã¢ã«ã¿ã€ã ã§å
±æããªãã説æãã§ããããã«ãªãã°ãä»ãŸã§ä»¥äžã«ãªã³ã©ã€ã³ã§ã質ã®é«ã蚺å¯ãè¡ããããã«ãªããŸãã ãããã£ããŠãŒã¹ã±ãŒã¹ãèŠæãªã©ãæ€èšããçµæãCLINICS ãå©çšãããã¹ãŠã®å»çæ©é¢åã³æ£è
ã«ãšã£ãŠå€§ããªæ©æµãèŠèŸŒãŸããããããªã³ã©ã€ã³èšºå¯ïŒãããªãã£ããïŒäžã«å»åž«ã® PC ç»é¢ããªã¢ã«ã¿ã€ã ã§æ£è
ã«å
±æããæ©èœãšããŠå®è£
ãããããšã«ããŸããã ç»é¢å
±ææ©èœã®å®è£
ç»é¢å
±æãããå»åž«åŽåãã®ã³ãŒãã§ã©ããã£ãå®è£
æ¹æ³ãããã®ãã倧ãŸããªæµãããŸãšããŸãã ⻠以äžã«èšèŒããŠããã³ãŒãã¯èª¬æã®ããã®ç䌌ã³ãŒãã§ãã®ã§ããã®ãŸãŸã§ã¯åäœããªãããšã«ã泚æãã ããããŸããå»åž«åŽã®å®è£
äŸãæ²èŒããŠãããããæ£è
åŽïŒç»é¢å
±æãåããåŽïŒã®å®è£
ã¯å¥éå¿
èŠã«ãªããŸãã ãªã³ã©ã€ã³èšºå¯éå§ãŸã§ã®åŠç ãªã³ã©ã€ã³èšºå¯ãéå§ããã«ã¯å»åž«åŽã®ãã€ã¯ãšã«ã¡ã©ã§ååŸããæ
å ±ãæ£è
åŽã«éä»ããå¿
èŠããããŸããããã§ã¯ãããŸã§ã®å®è£
ã®æµããèŠãŠãããŸãã ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ã®ååŸ ãªã³ã©ã€ã³èšºå¯éå§æç¹ã§å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã®æ
å ±ãå
±æããããããŸãã¯ãããã®ã¹ããªãŒã ãååŸããå¿
èŠããããŸãããããã£ãã¡ãã£ã¢ã³ã³ãã³ãã®ã¹ããªãŒã ãåžãã€ã³ã¿ãŒãã§ã€ã¹ãšã㊠MediaStream ãå®çŸ©ãããŠããŸãã ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã¯ãäŸãã° MediaDevices.getUserMedia() ãå©çšããŠååŸã§ããŸãã const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); SkyWay çµç±ã§ãªã³ã©ã€ã³èšºå¯ãå§ãã WebRTC ã§ P2P ã®ãããªãã£ãããå©çšããããã«ã¯ãåæã®æ¥ç¶ã®ããã®åŠçåã³æ¥ç¶ã®ç¶æãªã©ã®åŠçãè¡ãå¿
èŠããããŸããåŒç€Ÿã§ã¯ãã®ãããã®åŠçã WebRTC SaaS ã® SkyWay åã³ãã® SDK ãå©çšããããšã§ç°¡ç¥åããŠããŸãã ãªã³ã©ã€ã³èšºå¯éå§æã«ã¯ãå
çšååŸããå»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã SkyWay ã® SDK ã«æž¡ãããšã§ãäžå¯Ÿäžã§ã®ãªã¢ã«ã¿ã€ã ãããªãã£ãããå®çŸã§ããŸãã import Peer , { MediaConnection } from "skyway-js" ; const peer = new Peer ({ key: "your-api-key" }); // äºåã«æ£è
ãšå
±æããŠããã peer id ã«å¯Ÿã㊠call ã¡ãœãããš MediaStream ãæž¡ãããšã§èšºå¯ãéå§ã§ããã const mediaConnection : MediaConnection = peer . call ( "shared-peer-id" , userMediaStream ); // 泚: æ£è
åŽã¯éä»ãããåŠçããã³ããªã³ã°ããæ©èœãå®è£
ããå¿
èŠããã ãããŸã§ããªã³ã©ã€ã³èšºå¯ãéå§ãããŸã§ã®åŠçã§ãã ⻠詳现㯠SkyWay å
¬åŒã® ãã¥ãŒããªã¢ã« ãªã©ãåç
§ãã ããã ç»é¢å
±æã®åŠç ãããŸã§ã§æ£è
ã«å¯ŸããŠå»åž«åŽã®ã«ã¡ã©ã»ãã€ã¯ã§ååŸãããæ åã»é³å£°ã衚瀺ãããŠããç¶æ
ã®ããããããåãæ¿ããåŠçãå¿
èŠã«ãªããŸããä»åã¯çŸåšæ¥ç¶ã«å©çšããŠãã MediaStream ããç»é¢å
±æçšã® MediaStream ã«å
¥ãæ¿ããããšã§å®çŸããŸããã ç»é¢ã® MediaStream ã®ååŸ ãŸãã¯å
±æããç»é¢ã® MediaStream ãååŸããå¿
èŠããããŸãããã㯠MediaDevices.getDisplayMedia() ã䜿ãããšã§å®çŸã§ããŸãã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); ç»é¢å
±æçšã® MediaStream ãäœã getDisplayMedia() ããå
±æããç»é¢ã® MediaStream ãååŸã§ãããã®ã®ããã®ãŸãŸå©çšãããšãã€ã¯ã®é³å£°ãå
¥ããŸããã ãã㯠getDisplayMedia() ããåãã MediaStream ã«ãã€ã¯ã®é³å£°ãå«ãŸããŠããªãããšãåå ãªã®ã§ãå¿
èŠãªç»åã»é³å£°ã®çµã¿åãããæã£ãç»é¢å
±æçšã® MediaStream ãäœæããããšã§å¯ŸåŠãã§ããŸãã MediaStreamTrack ãçµã¿ããããŠç»é¢å
±æçšã® MediaStream ãäœã ç»é¢å
±æçšã® MediaStream ãäœæããåã«ãŸããMediaStreamTrack ãš MediaStream ã®é¢ä¿ãçè§£ããå¿
èŠããããŸãã MediaStreamTrack ã¯ã¹ããªãŒã ã«å«ãŸããäžã€ã®ã¡ãã£ã¢ãã©ãã¯ã衚çŸãããã®ã§ãã kind ãšããèªã¿åãå°çšããããã£ãããããªãŒãã£ãªãã©ãã¯ã§ããã° "audio" ãããããªãã©ãã¯ã§ããã° "video" ãèšå®ãããŠããŸãã ãŸãã MediaStream ã¯è€æ°ã® MediaStreamTrack ããæãããªãŒãã£ãªãã©ãã¯ã»ãããªãã©ãã¯ãåãåºãã¡ãœããããããã MediaStream.getAudioTracks() ã» MediaStream.getVideoTracks() ãšããŠå®è£
ãããŠããŸãã ããããçµã¿åãããããšã§ããã€ã¯ãšç»é¢ã® MediaStreamTrack ãæã€ MediaStream ãäœãããšãã§ããããã SkyWay ã® SDK ã«æž¡ãããšã§ãç»é¢å
±æãå®çŸã§ããŸãã const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingMediaStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); MediaStream ã®å
¥ãæ¿ã æåŸã«ç»é¢å
±æç¶æ
ãžã®åãæ¿ãã§ãããã€ã¯ã»ã«ã¡ã©ãå
±æãããŠããç¶æ
ããã®åãæ¿ãã«ã¯ããã€ãã®æ¹æ³ãèããããŸãã äŸãã°ãå€éåã§ããã° MediaConnectionïŒ Skyway ã® SDK ã®åäœã§ããæ¥ç¶å
Peer ãžã®ã¡ãã£ã¢ãã£ãã«æ¥ç¶ãã管çããïŒã®å€éåãMediaStream ã®å€éåãMediaStreamTrack ã®å€éåãããããèããããŸãããããã®æ¹æ³ã¯ãã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ãæå¶ãªã©å®è£
äžã®éžæè¢ãå¢ããã¡ãªãããããäžæ¹ã§ãéä¿¡éãå€ããªã£ãŠããŸãç¹ããã¡ãªãããšèšããŸãã ä»åã¯å€éåãããã«æ¢åã® MediaStream ãåãæ¿ããå®è£
ã玹ä»ããŸãããã®æ¹æ³ã®ã¡ãªããã¯ãå€éåã«æ¯ã¹ããšéä¿¡éãå°ãªãããŸããã§ã« MediaStream ãäžã€ã§ããåæã§äœãããŠããå Žåã¯ãç»é¢å
±æãåããåŽã®å®è£
ã®å€æŽãäžèŠãšããç¹ã§ãã ãã®æ¹æ³ã¯ã SkyWay ã® SDK ã§ããã° MediaConnection ã® replaceStream ãšããã¡ãœãã ã«å¯ŸããŠæ°ãã MediaStream ãæž¡ãããšã§å®çŸãã§ããŸãã // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã // MediaConnection ã¯å
çš `peer.call` ããéã®è¿ãå€ãšããŠåããŠããããããããå©çšãã mediaConnection . replaceStream ( sharingMediaStream ); å®è£
åã«æžå¿µããŠãããã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ããªã©ãæ°ã«ãªãã»ã©ã¯ãªããå®çšã«è¶³ããããªå質ãä¿ã€ããšãã§ããããšã確èªããŠããŸãã å®è£
ã®å
šäœæŠèР以äžã®æµããå®è£
ãããšã次ã®ãããªã³ãŒãã«ãªããŸãã import Peer , { MediaConnection } from "skyway-js" ; /** å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ãå
±æããŠãªã³ã©ã€ã³èšºå¯éå§ãããšãããŸã§ **/ // getUserMedia()ã§ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ãååŸ const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); // Skyway sdk ã®åæååŠç const peer = new Peer ({ key: "your-api-key" }); // ãªã³ã©ã€ã³èšºå¯ã®éå§ const mediaConnection : MediaConnection = peer . call ( "peerId" , userMediaStream ); /** ç»é¢å
±æãéå§ããåŠç **/ // ç»é¢å
±æããç»é¢ã® stream ãåã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã mediaConnection . replaceStream ( sharingStream ); éçºäžã«ééããåé¡ãžã®å¯Ÿå¿ ã¹ãªãŒãã¢ãŒãã»å
±æã忢ãã¿ã³ãæŒãããšãã®å¯Ÿå¿ Google Chrome ã§ç»é¢å
±æã®éã«è¡šç€ºããããå
±æã忢ããã¿ã³ãæŒäžããããPC ãã¹ãªãŒãã¢ãŒãã«ãããšãç»é¢ã® MediaStreamTrack ãéåããŠããŸããŸãã ããã¯è©²åœã® MediaStreamTrack ã« "ended" ã®ã€ãã³ããªã¹ããç»é²ããŠããããšã§ãã³ããªã³ã°ã§ããŸãã displayVideoTrack . addEventListener ( "ended" , handleEndedEvent , { once: true }); TypeScript ã®åã®å¯Ÿå¿ çŸç¶ TypeScript ã®åã getDisplayMedia() ã«å¯Ÿå¿ããŠããªãã£ããããä»åã¯å®è£
ã®åèã«ããŠãã skyway-conf ã§å©çšãããŠããå ãæµçšãã圢ã§å¯Ÿå¿ãããŸããã declare global { interface MediaDevices { getDisplayMedia ( constraints : MediaStreamConstraints ): Promise < MediaStream >; } } ããã¯æ ¹æ¬çã«ã¯ TypeScript ã® dom.d.ts ã«åå®çŸ©ãå
¥ã£ãŠããªãããšãèµ·å ããŠããŸããã TypeScript4.4 ã§å¯Ÿå¿ããããããã§ã ã ãŸãšã æšä»ã®ç¶æ³ã«ããããªã³ã©ã€ã³èšºå¯ã®ããŒãºãé«ãŸããç»é¢å
±ææ©èœã®éèŠæ§ãé«ãŸããŸããã 蚺å¯äžã®ç»é¢å
±ææ©èœã¯ä»¥äžã® api ãçµã¿åãããããšã§å®çŸããããšãã§ããŸãã PC ç»é¢ã® MediaStream 㯠getDisplayMedia() ã䜿ãããšã§ååŸ MediaStream ã«å«ããé³å£°ã»ç»åã¹ããªãŒã ã倿Žãããå Žå㯠MediaStreamTrack ã®çµã¿åãããå€ããããšã§äœæ æ¥ç¶äžã® MediaStream ã®å€æŽã¯ SkyWay ã® SDK ã® MediaConnection.replaceStream() ãäœ¿ã æåŸã« CLINICS ã§ã¯æ¬çš¿ã§ç޹ä»ããç»é¢å
±æãªã©ã®æ°èŠæ©èœã®å°å
¥ãæ¥ã
ã®æ¹åãéããŠãå»çæ©é¢ã»æ£è
åæ¹ã«æ¯æããããããã¯ããç®æãéçºãè¡ã£ãŠããŸããèå³ãæããããšã³ãžãã¢ã®æ¹ãããã£ããããŸããããã² ãã¡ã ã«ãé£çµ¡ããã ããã°ãšæããŸãã https://www.medley.jp/jobs/
äºæ¥æ¬éš ãããã¯ãéçºå®€ãšã³ãžãã¢ã®æ¥äžã§ãã ãªã³ã©ã€ã³èšºçã»æè¬æå°ã»ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãCLINICSã ã®ãæ£è
ã»å»çæ©é¢ã«åããã¢ããªã±ãŒã·ã§ã³ã®æ©èœéçºãéçºåºç€ãã€ã³ãã©åšããæ
åœããŠãããŸãã ä»å CLINICS ãæäŸãããªã³ã©ã€ã³èšºçæ©èœã«ãç»é¢å
±ææ©èœãã远å ããŸããã®ã§ããã®èæ¯ã»æè¡çãªè©±ããŸãšããŸãã ç»é¢å
±ææ©èœå®è£
ã®èæ¯ CLINICS ãšãªã³ã©ã€ã³èšºç æ®æ®µçãããç
é¢ã«ããããšããå€ãã®å Žåã¯ç
é¢ã«è¡ããå»åž«ã®èšºå¯ã察é¢ã§åããäŒèšãããŠåž°ããšãã£ãæµãã«ãªãããšæããŸãã CLINICS ã®ãªã³ã©ã€ã³èšºçã¯ãã®æµããã€ã³ã¿ãŒããããéããŠæäŸãããµãŒãã¹ã§ãã â» ãªã³ã©ã€ã³èšºçã¯ãäžåºŠãå蚺çã§å¯Ÿé¢èšºçãåããéã«å»åž«ãå¯èœãšå€æããå Žåãæ¬¡å以éã®èšºå¯ã«ãããŠå¯èœã«ãªããŸãããŸããçŸåšã¯æ°åã³ãããŠã€ã«ã¹ææç察çæéæªçœ®ãšããŠãå蚺ãããªã³ã©ã€ã³èšºçãåããããšãå¯èœãšãªã£ãŠããŸãã CLINICS ãå©çšããå Žåãäºåã«äºçŽããæéã«ã¹ãããŸã㯠PC ã§åŸ
æ©ããããå»åž«ã®èšºå¯ããããªãã£ããã§åããäŒèšã¯ã¯ã¬ãžããã«ãŒãã§è¡ããããšããæµããšãªã£ãŠããŸãã ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãšããŠã® CLINICS 㯠2016 幎ã«ããªã³ã©ã€ã³èšºçã®ããã®ã·ã¹ãã ããšããŠããŒã³ã ããã 2018 幎ã«ã¯ã¯ã©ãŠãåé»åã«ã«ãæ©èœã ã 2019 幎ã«ã¯äºçŽç®¡çã·ã¹ãã æ©èœã ã 2020 幎ã«ã¯ãããã€ãè¬å±æ¯æŽã·ã¹ãã Pharms ãšã®é£æºæ©èœã远å ã ãæ£è
åãã¢ããªãããªã³ã©ã€ã³æè¬æå°ãã·ãŒã ã¬ã¹ã«åããããšãã§ããããã«ãªããŸããã ãããã¯ãéçºå®€ã§ã¯ããããªã³ã©ã€ã³èšºçæ©èœã»é»åã«ã«ãæ©èœã»äºçŽç®¡çæ©èœã»é£æºæ©èœã®æ¹åãæ¥ã
è¡ã£ãŠããŸãã ç»é¢å
±ææ©èœã®éèŠã®é«ãŸããå®è£
ã®æ±ºå® ãã®ããã« CLINICS ã®æ¹åãæ¥ã
è¡ãªã£ãŠããäžãæšå¹Žããå§ãŸã£ã æ°åã³ãããŠã€ã«ã¹ææçïŒCOVID-19ïŒ ã®æµè¡ã«äŒŽã£ãéèŠã®å¢å ã«ããããªã³ã©ã€ã³èšºçã®ä»¶æ°ãæ¥å¢ããŸããã CLINICS ãæ°å€ãã®å»çæ©é¢ã«ãå©çšããã ãäžã§ããªã³ã©ã€ã³èšºçã«é¢ããããŸããŸãªãèŠæãããã ãããã«ãªããŸããããã®äžã§ãç¹ã«å€ãã£ããã®ããä»å玹ä»ããç»é¢å
±ææ©èœã§ãã 察é¢ã§ã®èšºå¯ã®éã«å»åž«ãæ€æ»çµæãªã©ãæ£è
ã«èŠããªãã説æããããã«ããªã³ã©ã€ã³ã§èšºå¯ããå Žåã§ãè³æããªã¢ã«ã¿ã€ã ã§å
±æããªãã説æãã§ããããã«ãªãã°ãä»ãŸã§ä»¥äžã«ãªã³ã©ã€ã³ã§ã質ã®é«ã蚺å¯ãè¡ããããã«ãªããŸãã ãããã£ããŠãŒã¹ã±ãŒã¹ãèŠæãªã©ãæ€èšããçµæãCLINICS ãå©çšãããã¹ãŠã®å»çæ©é¢åã³æ£è
ã«ãšã£ãŠå€§ããªæ©æµãèŠèŸŒãŸããããããªã³ã©ã€ã³èšºå¯ïŒãããªãã£ããïŒäžã«å»åž«ã® PC ç»é¢ããªã¢ã«ã¿ã€ã ã§æ£è
ã«å
±æããæ©èœãšããŠå®è£
ãããããšã«ããŸããã ç»é¢å
±ææ©èœã®å®è£
ç»é¢å
±æãããå»åž«åŽåãã®ã³ãŒãã§ã©ããã£ãå®è£
æ¹æ³ãããã®ãã倧ãŸããªæµãããŸãšããŸãã ⻠以äžã«èšèŒããŠããã³ãŒãã¯èª¬æã®ããã®ç䌌ã³ãŒãã§ãã®ã§ããã®ãŸãŸã§ã¯åäœããªãããšã«ã泚æãã ããããŸããå»åž«åŽã®å®è£
äŸãæ²èŒããŠãããããæ£è
åŽïŒç»é¢å
±æãåããåŽïŒã®å®è£
ã¯å¥éå¿
èŠã«ãªããŸãã ãªã³ã©ã€ã³èšºå¯éå§ãŸã§ã®åŠç ãªã³ã©ã€ã³èšºå¯ãéå§ããã«ã¯å»åž«åŽã®ãã€ã¯ãšã«ã¡ã©ã§ååŸããæ
å ±ãæ£è
åŽã«éä»ããå¿
èŠããããŸããããã§ã¯ãããŸã§ã®å®è£
ã®æµããèŠãŠãããŸãã ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ã®ååŸ ãªã³ã©ã€ã³èšºå¯éå§æç¹ã§å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã®æ
å ±ãå
±æããããããŸãã¯ãããã®ã¹ããªãŒã ãååŸããå¿
èŠããããŸãããããã£ãã¡ãã£ã¢ã³ã³ãã³ãã®ã¹ããªãŒã ãåžãã€ã³ã¿ãŒãã§ã€ã¹ãšã㊠MediaStream ãå®çŸ©ãããŠããŸãã ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã¯ãäŸãã° MediaDevices.getUserMedia() ãå©çšããŠååŸã§ããŸãã const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); SkyWay çµç±ã§ãªã³ã©ã€ã³èšºå¯ãå§ãã WebRTC ã§ P2P ã®ãããªãã£ãããå©çšããããã«ã¯ãåæã®æ¥ç¶ã®ããã®åŠçåã³æ¥ç¶ã®ç¶æãªã©ã®åŠçãè¡ãå¿
èŠããããŸããåŒç€Ÿã§ã¯ãã®ãããã®åŠçã WebRTC SaaS ã® SkyWay åã³ãã® SDK ãå©çšããããšã§ç°¡ç¥åããŠããŸãã ãªã³ã©ã€ã³èšºå¯éå§æã«ã¯ãå
çšååŸããå»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã SkyWay ã® SDK ã«æž¡ãããšã§ãäžå¯Ÿäžã§ã®ãªã¢ã«ã¿ã€ã ãããªãã£ãããå®çŸã§ããŸãã import Peer , { MediaConnection } from "skyway-js" ; const peer = new Peer ({ key: "your-api-key" }); // äºåã«æ£è
ãšå
±æããŠããã peer id ã«å¯Ÿã㊠call ã¡ãœãããš MediaStream ãæž¡ãããšã§èšºå¯ãéå§ã§ããã const mediaConnection : MediaConnection = peer . call ( "shared-peer-id" , userMediaStream ); // 泚: æ£è
åŽã¯éä»ãããåŠçããã³ããªã³ã°ããæ©èœãå®è£
ããå¿
èŠããã ãããŸã§ããªã³ã©ã€ã³èšºå¯ãéå§ãããŸã§ã®åŠçã§ãã ⻠詳现㯠SkyWay å
¬åŒã® ãã¥ãŒããªã¢ã« ãªã©ãåç
§ãã ããã ç»é¢å
±æã®åŠç ãããŸã§ã§æ£è
ã«å¯ŸããŠå»åž«åŽã®ã«ã¡ã©ã»ãã€ã¯ã§ååŸãããæ åã»é³å£°ã衚瀺ãããŠããç¶æ
ã®ããããããåãæ¿ããåŠçãå¿
èŠã«ãªããŸããä»åã¯çŸåšæ¥ç¶ã«å©çšããŠãã MediaStream ããç»é¢å
±æçšã® MediaStream ã«å
¥ãæ¿ããããšã§å®çŸããŸããã ç»é¢ã® MediaStream ã®ååŸ ãŸãã¯å
±æããç»é¢ã® MediaStream ãååŸããå¿
èŠããããŸãããã㯠MediaDevices.getDisplayMedia() ã䜿ãããšã§å®çŸã§ããŸãã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); ç»é¢å
±æçšã® MediaStream ãäœã getDisplayMedia() ããå
±æããç»é¢ã® MediaStream ãååŸã§ãããã®ã®ããã®ãŸãŸå©çšãããšãã€ã¯ã®é³å£°ãå
¥ããŸããã ãã㯠getDisplayMedia() ããåãã MediaStream ã«ãã€ã¯ã®é³å£°ãå«ãŸããŠããªãããšãåå ãªã®ã§ãå¿
èŠãªç»åã»é³å£°ã®çµã¿åãããæã£ãç»é¢å
±æçšã® MediaStream ãäœæããããšã§å¯ŸåŠãã§ããŸãã MediaStreamTrack ãçµã¿ããããŠç»é¢å
±æçšã® MediaStream ãäœã ç»é¢å
±æçšã® MediaStream ãäœæããåã«ãŸããMediaStreamTrack ãš MediaStream ã®é¢ä¿ãçè§£ããå¿
èŠããããŸãã MediaStreamTrack ã¯ã¹ããªãŒã ã«å«ãŸããäžã€ã®ã¡ãã£ã¢ãã©ãã¯ã衚çŸãããã®ã§ãã kind ãšããèªã¿åãå°çšããããã£ãããããªãŒãã£ãªãã©ãã¯ã§ããã° "audio" ãããããªãã©ãã¯ã§ããã° "video" ãèšå®ãããŠããŸãã ãŸãã MediaStream ã¯è€æ°ã® MediaStreamTrack ããæãããªãŒãã£ãªãã©ãã¯ã»ãããªãã©ãã¯ãåãåºãã¡ãœããããããã MediaStream.getAudioTracks() ã» MediaStream.getVideoTracks() ãšããŠå®è£
ãããŠããŸãã ããããçµã¿åãããããšã§ããã€ã¯ãšç»é¢ã® MediaStreamTrack ãæã€ MediaStream ãäœãããšãã§ããããã SkyWay ã® SDK ã«æž¡ãããšã§ãç»é¢å
±æãå®çŸã§ããŸãã const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingMediaStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); MediaStream ã®å
¥ãæ¿ã æåŸã«ç»é¢å
±æç¶æ
ãžã®åãæ¿ãã§ãããã€ã¯ã»ã«ã¡ã©ãå
±æãããŠããç¶æ
ããã®åãæ¿ãã«ã¯ããã€ãã®æ¹æ³ãèããããŸãã äŸãã°ãå€éåã§ããã° MediaConnectionïŒ Skyway ã® SDK ã®åäœã§ããæ¥ç¶å
Peer ãžã®ã¡ãã£ã¢ãã£ãã«æ¥ç¶ãã管çããïŒã®å€éåãMediaStream ã®å€éåãMediaStreamTrack ã®å€éåãããããèããããŸãããããã®æ¹æ³ã¯ãã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ãæå¶ãªã©å®è£
äžã®éžæè¢ãå¢ããã¡ãªãããããäžæ¹ã§ãéä¿¡éãå€ããªã£ãŠããŸãç¹ããã¡ãªãããšèšããŸãã ä»åã¯å€éåãããã«æ¢åã® MediaStream ãåãæ¿ããå®è£
ã玹ä»ããŸãããã®æ¹æ³ã®ã¡ãªããã¯ãå€éåã«æ¯ã¹ããšéä¿¡éãå°ãªãããŸããã§ã« MediaStream ãäžã€ã§ããåæã§äœãããŠããå Žåã¯ãç»é¢å
±æãåããåŽã®å®è£
ã®å€æŽãäžèŠãšããç¹ã§ãã ãã®æ¹æ³ã¯ã SkyWay ã® SDK ã§ããã° MediaConnection ã® replaceStream ãšããã¡ãœãã ã«å¯ŸããŠæ°ãã MediaStream ãæž¡ãããšã§å®çŸãã§ããŸãã // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã // MediaConnection ã¯å
çš `peer.call` ããéã®è¿ãå€ãšããŠåããŠããããããããå©çšãã mediaConnection . replaceStream ( sharingMediaStream ); å®è£
åã«æžå¿µããŠãããã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ããªã©ãæ°ã«ãªãã»ã©ã¯ãªããå®çšã«è¶³ããããªå質ãä¿ã€ããšãã§ããããšã確èªããŠããŸãã å®è£
ã®å
šäœæŠèР以äžã®æµããå®è£
ãããšã次ã®ãããªã³ãŒãã«ãªããŸãã import Peer , { MediaConnection } from "skyway-js" ; /** å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ãå
±æããŠãªã³ã©ã€ã³èšºå¯éå§ãããšãããŸã§ **/ // getUserMedia()ã§ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ãååŸ const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); // Skyway sdk ã®åæååŠç const peer = new Peer ({ key: "your-api-key" }); // ãªã³ã©ã€ã³èšºå¯ã®éå§ const mediaConnection : MediaConnection = peer . call ( "peerId" , userMediaStream ); /** ç»é¢å
±æãéå§ããåŠç **/ // ç»é¢å
±æããç»é¢ã® stream ãåã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã mediaConnection . replaceStream ( sharingStream ); éçºäžã«ééããåé¡ãžã®å¯Ÿå¿ ã¹ãªãŒãã¢ãŒãã»å
±æã忢ãã¿ã³ãæŒãããšãã®å¯Ÿå¿ Google Chrome ã§ç»é¢å
±æã®éã«è¡šç€ºããããå
±æã忢ããã¿ã³ãæŒäžããããPC ãã¹ãªãŒãã¢ãŒãã«ãããšãç»é¢ã® MediaStreamTrack ãéåããŠããŸããŸãã ããã¯è©²åœã® MediaStreamTrack ã« "ended" ã®ã€ãã³ããªã¹ããç»é²ããŠããããšã§ãã³ããªã³ã°ã§ããŸãã displayVideoTrack . addEventListener ( "ended" , handleEndedEvent , { once: true }); TypeScript ã®åã®å¯Ÿå¿ çŸç¶ TypeScript ã®åã getDisplayMedia() ã«å¯Ÿå¿ããŠããªãã£ããããä»åã¯å®è£
ã®åèã«ããŠãã skyway-conf ã§å©çšãããŠããå ãæµçšãã圢ã§å¯Ÿå¿ãããŸããã declare global { interface MediaDevices { getDisplayMedia ( constraints : MediaStreamConstraints ): Promise < MediaStream >; } } ããã¯æ ¹æ¬çã«ã¯ TypeScript ã® dom.d.ts ã«åå®çŸ©ãå
¥ã£ãŠããªãããšãèµ·å ããŠããŸããã TypeScript4.4 ã§å¯Ÿå¿ããããããã§ã ã ãŸãšã æšä»ã®ç¶æ³ã«ããããªã³ã©ã€ã³èšºå¯ã®ããŒãºãé«ãŸããç»é¢å
±ææ©èœã®éèŠæ§ãé«ãŸããŸããã 蚺å¯äžã®ç»é¢å
±ææ©èœã¯ä»¥äžã® api ãçµã¿åãããããšã§å®çŸããããšãã§ããŸãã PC ç»é¢ã® MediaStream 㯠getDisplayMedia() ã䜿ãããšã§ååŸ MediaStream ã«å«ããé³å£°ã»ç»åã¹ããªãŒã ã倿Žãããå Žå㯠MediaStreamTrack ã®çµã¿åãããå€ããããšã§äœæ æ¥ç¶äžã® MediaStream ã®å€æŽã¯ SkyWay ã® SDK ã® MediaConnection.replaceStream() ãäœ¿ã æåŸã« CLINICS ã§ã¯æ¬çš¿ã§ç޹ä»ããç»é¢å
±æãªã©ã®æ°èŠæ©èœã®å°å
¥ãæ¥ã
ã®æ¹åãéããŠãå»çæ©é¢ã»æ£è
åæ¹ã«æ¯æããããããã¯ããç®æãéçºãè¡ã£ãŠããŸããèå³ãæããããšã³ãžãã¢ã®æ¹ãããã£ããããŸããããã² ãã¡ã ã«ãé£çµ¡ããã ããã°ãšæããŸãã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
äºæ¥æ¬éš ãããã¯ãéçºå®€ãšã³ãžãã¢ã®æ¥äžã§ãã ãªã³ã©ã€ã³èšºçã»æè¬æå°ã»ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãCLINICSã ã®ãæ£è
ã»å»çæ©é¢ã«åããã¢ããªã±ãŒã·ã§ã³ã®æ©èœéçºãéçºåºç€ãã€ã³ãã©åšããæ
åœããŠãããŸãã ä»å CLINICS ãæäŸãããªã³ã©ã€ã³èšºçæ©èœã«ãç»é¢å
±ææ©èœãã远å ããŸããã®ã§ããã®èæ¯ã»æè¡çãªè©±ããŸãšããŸãã ç»é¢å
±ææ©èœå®è£
ã®èæ¯ CLINICS ãšãªã³ã©ã€ã³èšºç æ®æ®µçãããç
é¢ã«ããããšããå€ãã®å Žåã¯ç
é¢ã«è¡ããå»åž«ã®èšºå¯ã察é¢ã§åããäŒèšãããŠåž°ããšãã£ãæµãã«ãªãããšæããŸãã CLINICS ã®ãªã³ã©ã€ã³èšºçã¯ãã®æµããã€ã³ã¿ãŒããããéããŠæäŸãããµãŒãã¹ã§ãã â» ãªã³ã©ã€ã³èšºçã¯ãäžåºŠãå蚺çã§å¯Ÿé¢èšºçãåããéã«å»åž«ãå¯èœãšå€æããå Žåãæ¬¡å以éã®èšºå¯ã«ãããŠå¯èœã«ãªããŸãããŸããçŸåšã¯æ°åã³ãããŠã€ã«ã¹ææç察çæéæªçœ®ãšããŠãå蚺ãããªã³ã©ã€ã³èšºçãåããããšãå¯èœãšãªã£ãŠããŸãã CLINICS ãå©çšããå Žåãäºåã«äºçŽããæéã«ã¹ãããŸã㯠PC ã§åŸ
æ©ããããå»åž«ã®èšºå¯ããããªãã£ããã§åããäŒèšã¯ã¯ã¬ãžããã«ãŒãã§è¡ããããšããæµããšãªã£ãŠããŸãã ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãšããŠã® CLINICS 㯠2016 幎ã«ããªã³ã©ã€ã³èšºçã®ããã®ã·ã¹ãã ããšããŠããŒã³ã ããã 2018 幎ã«ã¯ã¯ã©ãŠãåé»åã«ã«ãæ©èœã ã 2019 幎ã«ã¯äºçŽç®¡çã·ã¹ãã æ©èœã ã 2020 幎ã«ã¯ãããã€ãè¬å±æ¯æŽã·ã¹ãã Pharms ãšã®é£æºæ©èœã远å ã ãæ£è
åãã¢ããªãããªã³ã©ã€ã³æè¬æå°ãã·ãŒã ã¬ã¹ã«åããããšãã§ããããã«ãªããŸããã ãããã¯ãéçºå®€ã§ã¯ããããªã³ã©ã€ã³èšºçæ©èœã»é»åã«ã«ãæ©èœã»äºçŽç®¡çæ©èœã»é£æºæ©èœã®æ¹åãæ¥ã
è¡ã£ãŠããŸãã ç»é¢å
±ææ©èœã®éèŠã®é«ãŸããå®è£
ã®æ±ºå® ãã®ããã« CLINICS ã®æ¹åãæ¥ã
è¡ãªã£ãŠããäžãæšå¹Žããå§ãŸã£ã æ°åã³ãããŠã€ã«ã¹ææçïŒCOVID-19ïŒ ã®æµè¡ã«äŒŽã£ãéèŠã®å¢å ã«ããããªã³ã©ã€ã³èšºçã®ä»¶æ°ãæ¥å¢ããŸããã CLINICS ãæ°å€ãã®å»çæ©é¢ã«ãå©çšããã ãäžã§ããªã³ã©ã€ã³èšºçã«é¢ããããŸããŸãªãèŠæãããã ãããã«ãªããŸããããã®äžã§ãç¹ã«å€ãã£ããã®ããä»å玹ä»ããç»é¢å
±ææ©èœã§ãã 察é¢ã§ã®èšºå¯ã®éã«å»åž«ãæ€æ»çµæãªã©ãæ£è
ã«èŠããªãã説æããããã«ããªã³ã©ã€ã³ã§èšºå¯ããå Žåã§ãè³æããªã¢ã«ã¿ã€ã ã§å
±æããªãã説æãã§ããããã«ãªãã°ãä»ãŸã§ä»¥äžã«ãªã³ã©ã€ã³ã§ã質ã®é«ã蚺å¯ãè¡ããããã«ãªããŸãã ãããã£ããŠãŒã¹ã±ãŒã¹ãèŠæãªã©ãæ€èšããçµæãCLINICS ãå©çšãããã¹ãŠã®å»çæ©é¢åã³æ£è
ã«ãšã£ãŠå€§ããªæ©æµãèŠèŸŒãŸããããããªã³ã©ã€ã³èšºå¯ïŒãããªãã£ããïŒäžã«å»åž«ã® PC ç»é¢ããªã¢ã«ã¿ã€ã ã§æ£è
ã«å
±æããæ©èœãšããŠå®è£
ãããããšã«ããŸããã ç»é¢å
±ææ©èœã®å®è£
ç»é¢å
±æãããå»åž«åŽåãã®ã³ãŒãã§ã©ããã£ãå®è£
æ¹æ³ãããã®ãã倧ãŸããªæµãããŸãšããŸãã ⻠以äžã«èšèŒããŠããã³ãŒãã¯èª¬æã®ããã®ç䌌ã³ãŒãã§ãã®ã§ããã®ãŸãŸã§ã¯åäœããªãããšã«ã泚æãã ããããŸããå»åž«åŽã®å®è£
äŸãæ²èŒããŠãããããæ£è
åŽïŒç»é¢å
±æãåããåŽïŒã®å®è£
ã¯å¥éå¿
èŠã«ãªããŸãã ãªã³ã©ã€ã³èšºå¯éå§ãŸã§ã®åŠç ãªã³ã©ã€ã³èšºå¯ãéå§ããã«ã¯å»åž«åŽã®ãã€ã¯ãšã«ã¡ã©ã§ååŸããæ
å ±ãæ£è
åŽã«éä»ããå¿
èŠããããŸããããã§ã¯ãããŸã§ã®å®è£
ã®æµããèŠãŠãããŸãã ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ã®ååŸ ãªã³ã©ã€ã³èšºå¯éå§æç¹ã§å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã®æ
å ±ãå
±æããããããŸãã¯ãããã®ã¹ããªãŒã ãååŸããå¿
èŠããããŸãããããã£ãã¡ãã£ã¢ã³ã³ãã³ãã®ã¹ããªãŒã ãåžãã€ã³ã¿ãŒãã§ã€ã¹ãšã㊠MediaStream ãå®çŸ©ãããŠããŸãã ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã¯ãäŸãã° MediaDevices.getUserMedia() ãå©çšããŠååŸã§ããŸãã const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); SkyWay çµç±ã§ãªã³ã©ã€ã³èšºå¯ãå§ãã WebRTC ã§ P2P ã®ãããªãã£ãããå©çšããããã«ã¯ãåæã®æ¥ç¶ã®ããã®åŠçåã³æ¥ç¶ã®ç¶æãªã©ã®åŠçãè¡ãå¿
èŠããããŸããåŒç€Ÿã§ã¯ãã®ãããã®åŠçã WebRTC SaaS ã® SkyWay åã³ãã® SDK ãå©çšããããšã§ç°¡ç¥åããŠããŸãã ãªã³ã©ã€ã³èšºå¯éå§æã«ã¯ãå
çšååŸããå»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã SkyWay ã® SDK ã«æž¡ãããšã§ãäžå¯Ÿäžã§ã®ãªã¢ã«ã¿ã€ã ãããªãã£ãããå®çŸã§ããŸãã import Peer , { MediaConnection } from "skyway-js" ; const peer = new Peer ({ key: "your-api-key" }); // äºåã«æ£è
ãšå
±æããŠããã peer id ã«å¯Ÿã㊠call ã¡ãœãããš MediaStream ãæž¡ãããšã§èšºå¯ãéå§ã§ããã const mediaConnection : MediaConnection = peer . call ( "shared-peer-id" , userMediaStream ); // 泚: æ£è
åŽã¯éä»ãããåŠçããã³ããªã³ã°ããæ©èœãå®è£
ããå¿
èŠããã ãããŸã§ããªã³ã©ã€ã³èšºå¯ãéå§ãããŸã§ã®åŠçã§ãã ⻠詳现㯠SkyWay å
¬åŒã® ãã¥ãŒããªã¢ã« ãªã©ãåç
§ãã ããã ç»é¢å
±æã®åŠç ãããŸã§ã§æ£è
ã«å¯ŸããŠå»åž«åŽã®ã«ã¡ã©ã»ãã€ã¯ã§ååŸãããæ åã»é³å£°ã衚瀺ãããŠããç¶æ
ã®ããããããåãæ¿ããåŠçãå¿
èŠã«ãªããŸããä»åã¯çŸåšæ¥ç¶ã«å©çšããŠãã MediaStream ããç»é¢å
±æçšã® MediaStream ã«å
¥ãæ¿ããããšã§å®çŸããŸããã ç»é¢ã® MediaStream ã®ååŸ ãŸãã¯å
±æããç»é¢ã® MediaStream ãååŸããå¿
èŠããããŸãããã㯠MediaDevices.getDisplayMedia() ã䜿ãããšã§å®çŸã§ããŸãã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); ç»é¢å
±æçšã® MediaStream ãäœã getDisplayMedia() ããå
±æããç»é¢ã® MediaStream ãååŸã§ãããã®ã®ããã®ãŸãŸå©çšãããšãã€ã¯ã®é³å£°ãå
¥ããŸããã ãã㯠getDisplayMedia() ããåãã MediaStream ã«ãã€ã¯ã®é³å£°ãå«ãŸããŠããªãããšãåå ãªã®ã§ãå¿
èŠãªç»åã»é³å£°ã®çµã¿åãããæã£ãç»é¢å
±æçšã® MediaStream ãäœæããããšã§å¯ŸåŠãã§ããŸãã MediaStreamTrack ãçµã¿ããããŠç»é¢å
±æçšã® MediaStream ãäœã ç»é¢å
±æçšã® MediaStream ãäœæããåã«ãŸããMediaStreamTrack ãš MediaStream ã®é¢ä¿ãçè§£ããå¿
èŠããããŸãã MediaStreamTrack ã¯ã¹ããªãŒã ã«å«ãŸããäžã€ã®ã¡ãã£ã¢ãã©ãã¯ã衚çŸãããã®ã§ãã kind ãšããèªã¿åãå°çšããããã£ãããããªãŒãã£ãªãã©ãã¯ã§ããã° "audio" ãããããªãã©ãã¯ã§ããã° "video" ãèšå®ãããŠããŸãã ãŸãã MediaStream ã¯è€æ°ã® MediaStreamTrack ããæãããªãŒãã£ãªãã©ãã¯ã»ãããªãã©ãã¯ãåãåºãã¡ãœããããããã MediaStream.getAudioTracks() ã» MediaStream.getVideoTracks() ãšããŠå®è£
ãããŠããŸãã ããããçµã¿åãããããšã§ããã€ã¯ãšç»é¢ã® MediaStreamTrack ãæã€ MediaStream ãäœãããšãã§ããããã SkyWay ã® SDK ã«æž¡ãããšã§ãç»é¢å
±æãå®çŸã§ããŸãã const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingMediaStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); MediaStream ã®å
¥ãæ¿ã æåŸã«ç»é¢å
±æç¶æ
ãžã®åãæ¿ãã§ãããã€ã¯ã»ã«ã¡ã©ãå
±æãããŠããç¶æ
ããã®åãæ¿ãã«ã¯ããã€ãã®æ¹æ³ãèããããŸãã äŸãã°ãå€éåã§ããã° MediaConnectionïŒ Skyway ã® SDK ã®åäœã§ããæ¥ç¶å
Peer ãžã®ã¡ãã£ã¢ãã£ãã«æ¥ç¶ãã管çããïŒã®å€éåãMediaStream ã®å€éåãMediaStreamTrack ã®å€éåãããããèããããŸãããããã®æ¹æ³ã¯ãã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ãæå¶ãªã©å®è£
äžã®éžæè¢ãå¢ããã¡ãªãããããäžæ¹ã§ãéä¿¡éãå€ããªã£ãŠããŸãç¹ããã¡ãªãããšèšããŸãã ä»åã¯å€éåãããã«æ¢åã® MediaStream ãåãæ¿ããå®è£
ã玹ä»ããŸãããã®æ¹æ³ã®ã¡ãªããã¯ãå€éåã«æ¯ã¹ããšéä¿¡éãå°ãªãããŸããã§ã« MediaStream ãäžã€ã§ããåæã§äœãããŠããå Žåã¯ãç»é¢å
±æãåããåŽã®å®è£
ã®å€æŽãäžèŠãšããç¹ã§ãã ãã®æ¹æ³ã¯ã SkyWay ã® SDK ã§ããã° MediaConnection ã® replaceStream ãšããã¡ãœãã ã«å¯ŸããŠæ°ãã MediaStream ãæž¡ãããšã§å®çŸãã§ããŸãã // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã // MediaConnection ã¯å
çš `peer.call` ããéã®è¿ãå€ãšããŠåããŠããããããããå©çšãã mediaConnection . replaceStream ( sharingMediaStream ); å®è£
åã«æžå¿µããŠãããã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ããªã©ãæ°ã«ãªãã»ã©ã¯ãªããå®çšã«è¶³ããããªå質ãä¿ã€ããšãã§ããããšã確èªããŠããŸãã å®è£
ã®å
šäœæŠèР以äžã®æµããå®è£
ãããšã次ã®ãããªã³ãŒãã«ãªããŸãã import Peer , { MediaConnection } from "skyway-js" ; /** å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ãå
±æããŠãªã³ã©ã€ã³èšºå¯éå§ãããšãããŸã§ **/ // getUserMedia()ã§ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ãååŸ const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); // Skyway sdk ã®åæååŠç const peer = new Peer ({ key: "your-api-key" }); // ãªã³ã©ã€ã³èšºå¯ã®éå§ const mediaConnection : MediaConnection = peer . call ( "peerId" , userMediaStream ); /** ç»é¢å
±æãéå§ããåŠç **/ // ç»é¢å
±æããç»é¢ã® stream ãåã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã mediaConnection . replaceStream ( sharingStream ); éçºäžã«ééããåé¡ãžã®å¯Ÿå¿ ã¹ãªãŒãã¢ãŒãã»å
±æã忢ãã¿ã³ãæŒãããšãã®å¯Ÿå¿ Google Chrome ã§ç»é¢å
±æã®éã«è¡šç€ºããããå
±æã忢ããã¿ã³ãæŒäžããããPC ãã¹ãªãŒãã¢ãŒãã«ãããšãç»é¢ã® MediaStreamTrack ãéåããŠããŸããŸãã ããã¯è©²åœã® MediaStreamTrack ã« "ended" ã®ã€ãã³ããªã¹ããç»é²ããŠããããšã§ãã³ããªã³ã°ã§ããŸãã displayVideoTrack . addEventListener ( "ended" , handleEndedEvent , { once: true }); TypeScript ã®åã®å¯Ÿå¿ çŸç¶ TypeScript ã®åã getDisplayMedia() ã«å¯Ÿå¿ããŠããªãã£ããããä»åã¯å®è£
ã®åèã«ããŠãã skyway-conf ã§å©çšãããŠããå ãæµçšãã圢ã§å¯Ÿå¿ãããŸããã declare global { interface MediaDevices { getDisplayMedia ( constraints : MediaStreamConstraints ): Promise < MediaStream >; } } ããã¯æ ¹æ¬çã«ã¯ TypeScript ã® dom.d.ts ã«åå®çŸ©ãå
¥ã£ãŠããªãããšãèµ·å ããŠããŸããã TypeScript4.4 ã§å¯Ÿå¿ããããããã§ã ã ãŸãšã æšä»ã®ç¶æ³ã«ããããªã³ã©ã€ã³èšºå¯ã®ããŒãºãé«ãŸããç»é¢å
±ææ©èœã®éèŠæ§ãé«ãŸããŸããã 蚺å¯äžã®ç»é¢å
±ææ©èœã¯ä»¥äžã® api ãçµã¿åãããããšã§å®çŸããããšãã§ããŸãã PC ç»é¢ã® MediaStream 㯠getDisplayMedia() ã䜿ãããšã§ååŸ MediaStream ã«å«ããé³å£°ã»ç»åã¹ããªãŒã ã倿Žãããå Žå㯠MediaStreamTrack ã®çµã¿åãããå€ããããšã§äœæ æ¥ç¶äžã® MediaStream ã®å€æŽã¯ SkyWay ã® SDK ã® MediaConnection.replaceStream() ãäœ¿ã æåŸã« CLINICS ã§ã¯æ¬çš¿ã§ç޹ä»ããç»é¢å
±æãªã©ã®æ°èŠæ©èœã®å°å
¥ãæ¥ã
ã®æ¹åãéããŠãå»çæ©é¢ã»æ£è
åæ¹ã«æ¯æããããããã¯ããç®æãéçºãè¡ã£ãŠããŸããèå³ãæããããšã³ãžãã¢ã®æ¹ãããã£ããããŸããããã² ãã¡ã ã«ãé£çµ¡ããã ããã°ãšæããŸãã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
äºæ¥æ¬éš ãããã¯ãéçºå®€ãšã³ãžãã¢ã®æ¥äžã§ãã ãªã³ã©ã€ã³èšºçã»æè¬æå°ã»ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãCLINICSã ã®ãæ£è
ã»å»çæ©é¢ã«åããã¢ããªã±ãŒã·ã§ã³ã®æ©èœéçºãéçºåºç€ãã€ã³ãã©åšããæ
åœããŠãããŸãã ä»å CLINICS ãæäŸãããªã³ã©ã€ã³èšºçæ©èœã«ãç»é¢å
±ææ©èœãã远å ããŸããã®ã§ããã®èæ¯ã»æè¡çãªè©±ããŸãšããŸãã ç»é¢å
±ææ©èœå®è£
ã®èæ¯ CLINICS ãšãªã³ã©ã€ã³èšºç æ®æ®µçãããç
é¢ã«ããããšããå€ãã®å Žåã¯ç
é¢ã«è¡ããå»åž«ã®èšºå¯ã察é¢ã§åããäŒèšãããŠåž°ããšãã£ãæµãã«ãªãããšæããŸãã CLINICS ã®ãªã³ã©ã€ã³èšºçã¯ãã®æµããã€ã³ã¿ãŒããããéããŠæäŸãããµãŒãã¹ã§ãã â» ãªã³ã©ã€ã³èšºçã¯ãäžåºŠãå蚺çã§å¯Ÿé¢èšºçãåããéã«å»åž«ãå¯èœãšå€æããå Žåãæ¬¡å以éã®èšºå¯ã«ãããŠå¯èœã«ãªããŸãããŸããçŸåšã¯æ°åã³ãããŠã€ã«ã¹ææç察çæéæªçœ®ãšããŠãå蚺ãããªã³ã©ã€ã³èšºçãåããããšãå¯èœãšãªã£ãŠããŸãã CLINICS ãå©çšããå Žåãäºåã«äºçŽããæéã«ã¹ãããŸã㯠PC ã§åŸ
æ©ããããå»åž«ã®èšºå¯ããããªãã£ããã§åããäŒèšã¯ã¯ã¬ãžããã«ãŒãã§è¡ããããšããæµããšãªã£ãŠããŸãã ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãšããŠã® CLINICS 㯠2016 幎ã«ããªã³ã©ã€ã³èšºçã®ããã®ã·ã¹ãã ããšããŠããŒã³ã ããã 2018 幎ã«ã¯ã¯ã©ãŠãåé»åã«ã«ãæ©èœã ã 2019 幎ã«ã¯äºçŽç®¡çã·ã¹ãã æ©èœã ã 2020 幎ã«ã¯ãããã€ãè¬å±æ¯æŽã·ã¹ãã Pharms ãšã®é£æºæ©èœã远å ã ãæ£è
åãã¢ããªãããªã³ã©ã€ã³æè¬æå°ãã·ãŒã ã¬ã¹ã«åããããšãã§ããããã«ãªããŸããã ãããã¯ãéçºå®€ã§ã¯ããããªã³ã©ã€ã³èšºçæ©èœã»é»åã«ã«ãæ©èœã»äºçŽç®¡çæ©èœã»é£æºæ©èœã®æ¹åãæ¥ã
è¡ã£ãŠããŸãã ç»é¢å
±ææ©èœã®éèŠã®é«ãŸããå®è£
ã®æ±ºå® ãã®ããã« CLINICS ã®æ¹åãæ¥ã
è¡ãªã£ãŠããäžãæšå¹Žããå§ãŸã£ã æ°åã³ãããŠã€ã«ã¹ææçïŒCOVID-19ïŒ ã®æµè¡ã«äŒŽã£ãéèŠã®å¢å ã«ããããªã³ã©ã€ã³èšºçã®ä»¶æ°ãæ¥å¢ããŸããã CLINICS ãæ°å€ãã®å»çæ©é¢ã«ãå©çšããã ãäžã§ããªã³ã©ã€ã³èšºçã«é¢ããããŸããŸãªãèŠæãããã ãããã«ãªããŸããããã®äžã§ãç¹ã«å€ãã£ããã®ããä»å玹ä»ããç»é¢å
±ææ©èœã§ãã 察é¢ã§ã®èšºå¯ã®éã«å»åž«ãæ€æ»çµæãªã©ãæ£è
ã«èŠããªãã説æããããã«ããªã³ã©ã€ã³ã§èšºå¯ããå Žåã§ãè³æããªã¢ã«ã¿ã€ã ã§å
±æããªãã説æãã§ããããã«ãªãã°ãä»ãŸã§ä»¥äžã«ãªã³ã©ã€ã³ã§ã質ã®é«ã蚺å¯ãè¡ããããã«ãªããŸãã ãããã£ããŠãŒã¹ã±ãŒã¹ãèŠæãªã©ãæ€èšããçµæãCLINICS ãå©çšãããã¹ãŠã®å»çæ©é¢åã³æ£è
ã«ãšã£ãŠå€§ããªæ©æµãèŠèŸŒãŸããããããªã³ã©ã€ã³èšºå¯ïŒãããªãã£ããïŒäžã«å»åž«ã® PC ç»é¢ããªã¢ã«ã¿ã€ã ã§æ£è
ã«å
±æããæ©èœãšããŠå®è£
ãããããšã«ããŸããã ç»é¢å
±ææ©èœã®å®è£
ç»é¢å
±æãããå»åž«åŽåãã®ã³ãŒãã§ã©ããã£ãå®è£
æ¹æ³ãããã®ãã倧ãŸããªæµãããŸãšããŸãã ⻠以äžã«èšèŒããŠããã³ãŒãã¯èª¬æã®ããã®ç䌌ã³ãŒãã§ãã®ã§ããã®ãŸãŸã§ã¯åäœããªãããšã«ã泚æãã ããããŸããå»åž«åŽã®å®è£
äŸãæ²èŒããŠãããããæ£è
åŽïŒç»é¢å
±æãåããåŽïŒã®å®è£
ã¯å¥éå¿
èŠã«ãªããŸãã ãªã³ã©ã€ã³èšºå¯éå§ãŸã§ã®åŠç ãªã³ã©ã€ã³èšºå¯ãéå§ããã«ã¯å»åž«åŽã®ãã€ã¯ãšã«ã¡ã©ã§ååŸããæ
å ±ãæ£è
åŽã«éä»ããå¿
èŠããããŸããããã§ã¯ãããŸã§ã®å®è£
ã®æµããèŠãŠãããŸãã ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ã®ååŸ ãªã³ã©ã€ã³èšºå¯éå§æç¹ã§å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã®æ
å ±ãå
±æããããããŸãã¯ãããã®ã¹ããªãŒã ãååŸããå¿
èŠããããŸãããããã£ãã¡ãã£ã¢ã³ã³ãã³ãã®ã¹ããªãŒã ãåžãã€ã³ã¿ãŒãã§ã€ã¹ãšã㊠MediaStream ãå®çŸ©ãããŠããŸãã ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã¯ãäŸãã° MediaDevices.getUserMedia() ãå©çšããŠååŸã§ããŸãã const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); SkyWay çµç±ã§ãªã³ã©ã€ã³èšºå¯ãå§ãã WebRTC ã§ P2P ã®ãããªãã£ãããå©çšããããã«ã¯ãåæã®æ¥ç¶ã®ããã®åŠçåã³æ¥ç¶ã®ç¶æãªã©ã®åŠçãè¡ãå¿
èŠããããŸããåŒç€Ÿã§ã¯ãã®ãããã®åŠçã WebRTC SaaS ã® SkyWay åã³ãã® SDK ãå©çšããããšã§ç°¡ç¥åããŠããŸãã ãªã³ã©ã€ã³èšºå¯éå§æã«ã¯ãå
çšååŸããå»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã SkyWay ã® SDK ã«æž¡ãããšã§ãäžå¯Ÿäžã§ã®ãªã¢ã«ã¿ã€ã ãããªãã£ãããå®çŸã§ããŸãã import Peer , { MediaConnection } from "skyway-js" ; const peer = new Peer ({ key: "your-api-key" }); // äºåã«æ£è
ãšå
±æããŠããã peer id ã«å¯Ÿã㊠call ã¡ãœãããš MediaStream ãæž¡ãããšã§èšºå¯ãéå§ã§ããã const mediaConnection : MediaConnection = peer . call ( "shared-peer-id" , userMediaStream ); // 泚: æ£è
åŽã¯éä»ãããåŠçããã³ããªã³ã°ããæ©èœãå®è£
ããå¿
èŠããã ãããŸã§ããªã³ã©ã€ã³èšºå¯ãéå§ãããŸã§ã®åŠçã§ãã ⻠詳现㯠SkyWay å
¬åŒã® ãã¥ãŒããªã¢ã« ãªã©ãåç
§ãã ããã ç»é¢å
±æã®åŠç ãããŸã§ã§æ£è
ã«å¯ŸããŠå»åž«åŽã®ã«ã¡ã©ã»ãã€ã¯ã§ååŸãããæ åã»é³å£°ã衚瀺ãããŠããç¶æ
ã®ããããããåãæ¿ããåŠçãå¿
èŠã«ãªããŸããä»åã¯çŸåšæ¥ç¶ã«å©çšããŠãã MediaStream ããç»é¢å
±æçšã® MediaStream ã«å
¥ãæ¿ããããšã§å®çŸããŸããã ç»é¢ã® MediaStream ã®ååŸ ãŸãã¯å
±æããç»é¢ã® MediaStream ãååŸããå¿
èŠããããŸãããã㯠MediaDevices.getDisplayMedia() ã䜿ãããšã§å®çŸã§ããŸãã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); ç»é¢å
±æçšã® MediaStream ãäœã getDisplayMedia() ããå
±æããç»é¢ã® MediaStream ãååŸã§ãããã®ã®ããã®ãŸãŸå©çšãããšãã€ã¯ã®é³å£°ãå
¥ããŸããã ãã㯠getDisplayMedia() ããåãã MediaStream ã«ãã€ã¯ã®é³å£°ãå«ãŸããŠããªãããšãåå ãªã®ã§ãå¿
èŠãªç»åã»é³å£°ã®çµã¿åãããæã£ãç»é¢å
±æçšã® MediaStream ãäœæããããšã§å¯ŸåŠãã§ããŸãã MediaStreamTrack ãçµã¿ããããŠç»é¢å
±æçšã® MediaStream ãäœã ç»é¢å
±æçšã® MediaStream ãäœæããåã«ãŸããMediaStreamTrack ãš MediaStream ã®é¢ä¿ãçè§£ããå¿
èŠããããŸãã MediaStreamTrack ã¯ã¹ããªãŒã ã«å«ãŸããäžã€ã®ã¡ãã£ã¢ãã©ãã¯ã衚çŸãããã®ã§ãã kind ãšããèªã¿åãå°çšããããã£ãããããªãŒãã£ãªãã©ãã¯ã§ããã° "audio" ãããããªãã©ãã¯ã§ããã° "video" ãèšå®ãããŠããŸãã ãŸãã MediaStream ã¯è€æ°ã® MediaStreamTrack ããæãããªãŒãã£ãªãã©ãã¯ã»ãããªãã©ãã¯ãåãåºãã¡ãœããããããã MediaStream.getAudioTracks() ã» MediaStream.getVideoTracks() ãšããŠå®è£
ãããŠããŸãã ããããçµã¿åãããããšã§ããã€ã¯ãšç»é¢ã® MediaStreamTrack ãæã€ MediaStream ãäœãããšãã§ããããã SkyWay ã® SDK ã«æž¡ãããšã§ãç»é¢å
±æãå®çŸã§ããŸãã const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingMediaStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); MediaStream ã®å
¥ãæ¿ã æåŸã«ç»é¢å
±æç¶æ
ãžã®åãæ¿ãã§ãããã€ã¯ã»ã«ã¡ã©ãå
±æãããŠããç¶æ
ããã®åãæ¿ãã«ã¯ããã€ãã®æ¹æ³ãèããããŸãã äŸãã°ãå€éåã§ããã° MediaConnectionïŒ Skyway ã® SDK ã®åäœã§ããæ¥ç¶å
Peer ãžã®ã¡ãã£ã¢ãã£ãã«æ¥ç¶ãã管çããïŒã®å€éåãMediaStream ã®å€éåãMediaStreamTrack ã®å€éåãããããèããããŸãããããã®æ¹æ³ã¯ãã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ãæå¶ãªã©å®è£
äžã®éžæè¢ãå¢ããã¡ãªãããããäžæ¹ã§ãéä¿¡éãå€ããªã£ãŠããŸãç¹ããã¡ãªãããšèšããŸãã ä»åã¯å€éåãããã«æ¢åã® MediaStream ãåãæ¿ããå®è£
ã玹ä»ããŸãããã®æ¹æ³ã®ã¡ãªããã¯ãå€éåã«æ¯ã¹ããšéä¿¡éãå°ãªãããŸããã§ã« MediaStream ãäžã€ã§ããåæã§äœãããŠããå Žåã¯ãç»é¢å
±æãåããåŽã®å®è£
ã®å€æŽãäžèŠãšããç¹ã§ãã ãã®æ¹æ³ã¯ã SkyWay ã® SDK ã§ããã° MediaConnection ã® replaceStream ãšããã¡ãœãã ã«å¯ŸããŠæ°ãã MediaStream ãæž¡ãããšã§å®çŸãã§ããŸãã // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã // MediaConnection ã¯å
çš `peer.call` ããéã®è¿ãå€ãšããŠåããŠããããããããå©çšãã mediaConnection . replaceStream ( sharingMediaStream ); å®è£
åã«æžå¿µããŠãããã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ããªã©ãæ°ã«ãªãã»ã©ã¯ãªããå®çšã«è¶³ããããªå質ãä¿ã€ããšãã§ããããšã確èªããŠããŸãã å®è£
ã®å
šäœæŠèР以äžã®æµããå®è£
ãããšã次ã®ãããªã³ãŒãã«ãªããŸãã import Peer , { MediaConnection } from "skyway-js" ; /** å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ãå
±æããŠãªã³ã©ã€ã³èšºå¯éå§ãããšãããŸã§ **/ // getUserMedia()ã§ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ãååŸ const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); // Skyway sdk ã®åæååŠç const peer = new Peer ({ key: "your-api-key" }); // ãªã³ã©ã€ã³èšºå¯ã®éå§ const mediaConnection : MediaConnection = peer . call ( "peerId" , userMediaStream ); /** ç»é¢å
±æãéå§ããåŠç **/ // ç»é¢å
±æããç»é¢ã® stream ãåã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã mediaConnection . replaceStream ( sharingStream ); éçºäžã«ééããåé¡ãžã®å¯Ÿå¿ ã¹ãªãŒãã¢ãŒãã»å
±æã忢ãã¿ã³ãæŒãããšãã®å¯Ÿå¿ Google Chrome ã§ç»é¢å
±æã®éã«è¡šç€ºããããå
±æã忢ããã¿ã³ãæŒäžããããPC ãã¹ãªãŒãã¢ãŒãã«ãããšãç»é¢ã® MediaStreamTrack ãéåããŠããŸããŸãã ããã¯è©²åœã® MediaStreamTrack ã« "ended" ã®ã€ãã³ããªã¹ããç»é²ããŠããããšã§ãã³ããªã³ã°ã§ããŸãã displayVideoTrack . addEventListener ( "ended" , handleEndedEvent , { once: true }); TypeScript ã®åã®å¯Ÿå¿ çŸç¶ TypeScript ã®åã getDisplayMedia() ã«å¯Ÿå¿ããŠããªãã£ããããä»åã¯å®è£
ã®åèã«ããŠãã skyway-conf ã§å©çšãããŠããå ãæµçšãã圢ã§å¯Ÿå¿ãããŸããã declare global { interface MediaDevices { getDisplayMedia ( constraints : MediaStreamConstraints ): Promise < MediaStream >; } } ããã¯æ ¹æ¬çã«ã¯ TypeScript ã® dom.d.ts ã«åå®çŸ©ãå
¥ã£ãŠããªãããšãèµ·å ããŠããŸããã TypeScript4.4 ã§å¯Ÿå¿ããããããã§ã ã ãŸãšã æšä»ã®ç¶æ³ã«ããããªã³ã©ã€ã³èšºå¯ã®ããŒãºãé«ãŸããç»é¢å
±ææ©èœã®éèŠæ§ãé«ãŸããŸããã 蚺å¯äžã®ç»é¢å
±ææ©èœã¯ä»¥äžã® api ãçµã¿åãããããšã§å®çŸããããšãã§ããŸãã PC ç»é¢ã® MediaStream 㯠getDisplayMedia() ã䜿ãããšã§ååŸ MediaStream ã«å«ããé³å£°ã»ç»åã¹ããªãŒã ã倿Žãããå Žå㯠MediaStreamTrack ã®çµã¿åãããå€ããããšã§äœæ æ¥ç¶äžã® MediaStream ã®å€æŽã¯ SkyWay ã® SDK ã® MediaConnection.replaceStream() ãäœ¿ã æåŸã« CLINICS ã§ã¯æ¬çš¿ã§ç޹ä»ããç»é¢å
±æãªã©ã®æ°èŠæ©èœã®å°å
¥ãæ¥ã
ã®æ¹åãéããŠãå»çæ©é¢ã»æ£è
åæ¹ã«æ¯æããããããã¯ããç®æãéçºãè¡ã£ãŠããŸããèå³ãæããããšã³ãžãã¢ã®æ¹ãããã£ããããŸããããã² ãã¡ã ã«ãé£çµ¡ããã ããã°ãšæããŸãã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
äºæ¥æ¬éš ãããã¯ãéçºå®€ãšã³ãžãã¢ã®æ¥äžã§ãã ãªã³ã©ã€ã³èšºçã»æè¬æå°ã»ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãCLINICSã ã®ãæ£è
ã»å»çæ©é¢ã«åããã¢ããªã±ãŒã·ã§ã³ã®æ©èœéçºãéçºåºç€ãã€ã³ãã©åšããæ
åœããŠãããŸãã ä»å CLINICS ãæäŸãããªã³ã©ã€ã³èšºçæ©èœã«ãç»é¢å
±ææ©èœãã远å ããŸããã®ã§ããã®èæ¯ã»æè¡çãªè©±ããŸãšããŸãã ç»é¢å
±ææ©èœå®è£
ã®èæ¯ CLINICS ãšãªã³ã©ã€ã³èšºç æ®æ®µçãããç
é¢ã«ããããšããå€ãã®å Žåã¯ç
é¢ã«è¡ããå»åž«ã®èšºå¯ã察é¢ã§åããäŒèšãããŠåž°ããšãã£ãæµãã«ãªãããšæããŸãã CLINICS ã®ãªã³ã©ã€ã³èšºçã¯ãã®æµããã€ã³ã¿ãŒããããéããŠæäŸãããµãŒãã¹ã§ãã â» ãªã³ã©ã€ã³èšºçã¯ãäžåºŠãå蚺çã§å¯Ÿé¢èšºçãåããéã«å»åž«ãå¯èœãšå€æããå Žåãæ¬¡å以éã®èšºå¯ã«ãããŠå¯èœã«ãªããŸãããŸããçŸåšã¯æ°åã³ãããŠã€ã«ã¹ææç察çæéæªçœ®ãšããŠãå蚺ãããªã³ã©ã€ã³èšºçãåããããšãå¯èœãšãªã£ãŠããŸãã CLINICS ãå©çšããå Žåãäºåã«äºçŽããæéã«ã¹ãããŸã㯠PC ã§åŸ
æ©ããããå»åž«ã®èšºå¯ããããªãã£ããã§åããäŒèšã¯ã¯ã¬ãžããã«ãŒãã§è¡ããããšããæµããšãªã£ãŠããŸãã ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãšããŠã® CLINICS 㯠2016 幎ã«ããªã³ã©ã€ã³èšºçã®ããã®ã·ã¹ãã ããšããŠããŒã³ã ããã 2018 幎ã«ã¯ã¯ã©ãŠãåé»åã«ã«ãæ©èœã ã 2019 幎ã«ã¯äºçŽç®¡çã·ã¹ãã æ©èœã ã 2020 幎ã«ã¯ãããã€ãè¬å±æ¯æŽã·ã¹ãã Pharms ãšã®é£æºæ©èœã远å ã ãæ£è
åãã¢ããªãããªã³ã©ã€ã³æè¬æå°ãã·ãŒã ã¬ã¹ã«åããããšãã§ããããã«ãªããŸããã ãããã¯ãéçºå®€ã§ã¯ããããªã³ã©ã€ã³èšºçæ©èœã»é»åã«ã«ãæ©èœã»äºçŽç®¡çæ©èœã»é£æºæ©èœã®æ¹åãæ¥ã
è¡ã£ãŠããŸãã ç»é¢å
±ææ©èœã®éèŠã®é«ãŸããå®è£
ã®æ±ºå® ãã®ããã« CLINICS ã®æ¹åãæ¥ã
è¡ãªã£ãŠããäžãæšå¹Žããå§ãŸã£ã æ°åã³ãããŠã€ã«ã¹ææçïŒCOVID-19ïŒ ã®æµè¡ã«äŒŽã£ãéèŠã®å¢å ã«ããããªã³ã©ã€ã³èšºçã®ä»¶æ°ãæ¥å¢ããŸããã CLINICS ãæ°å€ãã®å»çæ©é¢ã«ãå©çšããã ãäžã§ããªã³ã©ã€ã³èšºçã«é¢ããããŸããŸãªãèŠæãããã ãããã«ãªããŸããããã®äžã§ãç¹ã«å€ãã£ããã®ããä»å玹ä»ããç»é¢å
±ææ©èœã§ãã 察é¢ã§ã®èšºå¯ã®éã«å»åž«ãæ€æ»çµæãªã©ãæ£è
ã«èŠããªãã説æããããã«ããªã³ã©ã€ã³ã§èšºå¯ããå Žåã§ãè³æããªã¢ã«ã¿ã€ã ã§å
±æããªãã説æãã§ããããã«ãªãã°ãä»ãŸã§ä»¥äžã«ãªã³ã©ã€ã³ã§ã質ã®é«ã蚺å¯ãè¡ããããã«ãªããŸãã ãããã£ããŠãŒã¹ã±ãŒã¹ãèŠæãªã©ãæ€èšããçµæãCLINICS ãå©çšãããã¹ãŠã®å»çæ©é¢åã³æ£è
ã«ãšã£ãŠå€§ããªæ©æµãèŠèŸŒãŸããããããªã³ã©ã€ã³èšºå¯ïŒãããªãã£ããïŒäžã«å»åž«ã® PC ç»é¢ããªã¢ã«ã¿ã€ã ã§æ£è
ã«å
±æããæ©èœãšããŠå®è£
ãããããšã«ããŸããã ç»é¢å
±ææ©èœã®å®è£
ç»é¢å
±æãããå»åž«åŽåãã®ã³ãŒãã§ã©ããã£ãå®è£
æ¹æ³ãããã®ãã倧ãŸããªæµãããŸãšããŸãã ⻠以äžã«èšèŒããŠããã³ãŒãã¯èª¬æã®ããã®ç䌌ã³ãŒãã§ãã®ã§ããã®ãŸãŸã§ã¯åäœããªãããšã«ã泚æãã ããããŸããå»åž«åŽã®å®è£
äŸãæ²èŒããŠãããããæ£è
åŽïŒç»é¢å
±æãåããåŽïŒã®å®è£
ã¯å¥éå¿
èŠã«ãªããŸãã ãªã³ã©ã€ã³èšºå¯éå§ãŸã§ã®åŠç ãªã³ã©ã€ã³èšºå¯ãéå§ããã«ã¯å»åž«åŽã®ãã€ã¯ãšã«ã¡ã©ã§ååŸããæ
å ±ãæ£è
åŽã«éä»ããå¿
èŠããããŸããããã§ã¯ãããŸã§ã®å®è£
ã®æµããèŠãŠãããŸãã ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ã®ååŸ ãªã³ã©ã€ã³èšºå¯éå§æç¹ã§å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã®æ
å ±ãå
±æããããããŸãã¯ãããã®ã¹ããªãŒã ãååŸããå¿
èŠããããŸãããããã£ãã¡ãã£ã¢ã³ã³ãã³ãã®ã¹ããªãŒã ãåžãã€ã³ã¿ãŒãã§ã€ã¹ãšã㊠MediaStream ãå®çŸ©ãããŠããŸãã ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã¯ãäŸãã° MediaDevices.getUserMedia() ãå©çšããŠååŸã§ããŸãã const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); SkyWay çµç±ã§ãªã³ã©ã€ã³èšºå¯ãå§ãã WebRTC ã§ P2P ã®ãããªãã£ãããå©çšããããã«ã¯ãåæã®æ¥ç¶ã®ããã®åŠçåã³æ¥ç¶ã®ç¶æãªã©ã®åŠçãè¡ãå¿
èŠããããŸããåŒç€Ÿã§ã¯ãã®ãããã®åŠçã WebRTC SaaS ã® SkyWay åã³ãã® SDK ãå©çšããããšã§ç°¡ç¥åããŠããŸãã ãªã³ã©ã€ã³èšºå¯éå§æã«ã¯ãå
çšååŸããå»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ã® MediaStream ã SkyWay ã® SDK ã«æž¡ãããšã§ãäžå¯Ÿäžã§ã®ãªã¢ã«ã¿ã€ã ãããªãã£ãããå®çŸã§ããŸãã import Peer , { MediaConnection } from "skyway-js" ; const peer = new Peer ({ key: "your-api-key" }); // äºåã«æ£è
ãšå
±æããŠããã peer id ã«å¯Ÿã㊠call ã¡ãœãããš MediaStream ãæž¡ãããšã§èšºå¯ãéå§ã§ããã const mediaConnection : MediaConnection = peer . call ( "shared-peer-id" , userMediaStream ); // 泚: æ£è
åŽã¯éä»ãããåŠçããã³ããªã³ã°ããæ©èœãå®è£
ããå¿
èŠããã ãããŸã§ããªã³ã©ã€ã³èšºå¯ãéå§ãããŸã§ã®åŠçã§ãã ⻠詳现㯠SkyWay å
¬åŒã® ãã¥ãŒããªã¢ã« ãªã©ãåç
§ãã ããã ç»é¢å
±æã®åŠç ãããŸã§ã§æ£è
ã«å¯ŸããŠå»åž«åŽã®ã«ã¡ã©ã»ãã€ã¯ã§ååŸãããæ åã»é³å£°ã衚瀺ãããŠããç¶æ
ã®ããããããåãæ¿ããåŠçãå¿
èŠã«ãªããŸããä»åã¯çŸåšæ¥ç¶ã«å©çšããŠãã MediaStream ããç»é¢å
±æçšã® MediaStream ã«å
¥ãæ¿ããããšã§å®çŸããŸããã ç»é¢ã® MediaStream ã®ååŸ ãŸãã¯å
±æããç»é¢ã® MediaStream ãååŸããå¿
èŠããããŸãããã㯠MediaDevices.getDisplayMedia() ã䜿ãããšã§å®çŸã§ããŸãã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); ç»é¢å
±æçšã® MediaStream ãäœã getDisplayMedia() ããå
±æããç»é¢ã® MediaStream ãååŸã§ãããã®ã®ããã®ãŸãŸå©çšãããšãã€ã¯ã®é³å£°ãå
¥ããŸããã ãã㯠getDisplayMedia() ããåãã MediaStream ã«ãã€ã¯ã®é³å£°ãå«ãŸããŠããªãããšãåå ãªã®ã§ãå¿
èŠãªç»åã»é³å£°ã®çµã¿åãããæã£ãç»é¢å
±æçšã® MediaStream ãäœæããããšã§å¯ŸåŠãã§ããŸãã MediaStreamTrack ãçµã¿ããããŠç»é¢å
±æçšã® MediaStream ãäœã ç»é¢å
±æçšã® MediaStream ãäœæããåã«ãŸããMediaStreamTrack ãš MediaStream ã®é¢ä¿ãçè§£ããå¿
èŠããããŸãã MediaStreamTrack ã¯ã¹ããªãŒã ã«å«ãŸããäžã€ã®ã¡ãã£ã¢ãã©ãã¯ã衚çŸãããã®ã§ãã kind ãšããèªã¿åãå°çšããããã£ãããããªãŒãã£ãªãã©ãã¯ã§ããã° "audio" ãããããªãã©ãã¯ã§ããã° "video" ãèšå®ãããŠããŸãã ãŸãã MediaStream ã¯è€æ°ã® MediaStreamTrack ããæãããªãŒãã£ãªãã©ãã¯ã»ãããªãã©ãã¯ãåãåºãã¡ãœããããããã MediaStream.getAudioTracks() ã» MediaStream.getVideoTracks() ãšããŠå®è£
ãããŠããŸãã ããããçµã¿åãããããšã§ããã€ã¯ãšç»é¢ã® MediaStreamTrack ãæã€ MediaStream ãäœãããšãã§ããããã SkyWay ã® SDK ã«æž¡ãããšã§ãç»é¢å
±æãå®çŸã§ããŸãã const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingMediaStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); MediaStream ã®å
¥ãæ¿ã æåŸã«ç»é¢å
±æç¶æ
ãžã®åãæ¿ãã§ãããã€ã¯ã»ã«ã¡ã©ãå
±æãããŠããç¶æ
ããã®åãæ¿ãã«ã¯ããã€ãã®æ¹æ³ãèããããŸãã äŸãã°ãå€éåã§ããã° MediaConnectionïŒ Skyway ã® SDK ã®åäœã§ããæ¥ç¶å
Peer ãžã®ã¡ãã£ã¢ãã£ãã«æ¥ç¶ãã管çããïŒã®å€éåãMediaStream ã®å€éåãMediaStreamTrack ã®å€éåãããããèããããŸãããããã®æ¹æ³ã¯ãã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ãæå¶ãªã©å®è£
äžã®éžæè¢ãå¢ããã¡ãªãããããäžæ¹ã§ãéä¿¡éãå€ããªã£ãŠããŸãç¹ããã¡ãªãããšèšããŸãã ä»åã¯å€éåãããã«æ¢åã® MediaStream ãåãæ¿ããå®è£
ã玹ä»ããŸãããã®æ¹æ³ã®ã¡ãªããã¯ãå€éåã«æ¯ã¹ããšéä¿¡éãå°ãªãããŸããã§ã« MediaStream ãäžã€ã§ããåæã§äœãããŠããå Žåã¯ãç»é¢å
±æãåããåŽã®å®è£
ã®å€æŽãäžèŠãšããç¹ã§ãã ãã®æ¹æ³ã¯ã SkyWay ã® SDK ã§ããã° MediaConnection ã® replaceStream ãšããã¡ãœãã ã«å¯ŸããŠæ°ãã MediaStream ãæž¡ãããšã§å®çŸãã§ããŸãã // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã // MediaConnection ã¯å
çš `peer.call` ããéã®è¿ãå€ãšããŠåããŠããããããããå©çšãã mediaConnection . replaceStream ( sharingMediaStream ); å®è£
åã«æžå¿µããŠãããã€ã¯ã»ã«ã¡ã©ã®åãæ¿ãæã®ãã©ã€ããªã©ãæ°ã«ãªãã»ã©ã¯ãªããå®çšã«è¶³ããããªå質ãä¿ã€ããšãã§ããããšã確èªããŠããŸãã å®è£
ã®å
šäœæŠèР以äžã®æµããå®è£
ãããšã次ã®ãããªã³ãŒãã«ãªããŸãã import Peer , { MediaConnection } from "skyway-js" ; /** å»åž«åŽã®ãã€ã¯ã»ã«ã¡ã©ãå
±æããŠãªã³ã©ã€ã³èšºå¯éå§ãããšãããŸã§ **/ // getUserMedia()ã§ã«ã¡ã©ã»ãã€ã¯ã®ã¹ããªãŒã ãååŸ const userMediaStream : MediaStream = await navigator . mediaDevices . getUserMedia ({ video: true , audio: true , }); // Skyway sdk ã®åæååŠç const peer = new Peer ({ key: "your-api-key" }); // ãªã³ã©ã€ã³èšºå¯ã®éå§ const mediaConnection : MediaConnection = peer . call ( "peerId" , userMediaStream ); /** ç»é¢å
±æãéå§ããåŠç **/ // ç»é¢å
±æããç»é¢ã® stream ãåã const displayStream : MediaStream = await navigator . mediaDevices . getDisplayMedia ( { video: true } ); const [ displayVideoTrack ]: MediaStreamTrack [] = displayStream . getVideoTracks (); // ç»é¢å
±æã®é³å£°ã¯ãã€ã¯ã®é³å£°ãå©çšãããã®ã§ãuserMediaStream ãã audioTrack ãåãåºããŠãã const [ userAudioTrack ]: MediaStreamTrack [] = userMediaStream . getAudioTracks (); // ç»é¢å
±æããããã® MediaStream ãäœæãã(ç»é¢ã® videoTrackããã€ã¯ã® audioTrack ãæã€ MediaStream ãäœã) const sharingStream : MediaStream = new MediaStream ([ displayVideoTrack , userAudioTrack , ]); // ç»é¢å
±æçšã® MediaStream ãæž¡ãããšã§ãç»é¢å
±æãéå§ãã mediaConnection . replaceStream ( sharingStream ); éçºäžã«ééããåé¡ãžã®å¯Ÿå¿ ã¹ãªãŒãã¢ãŒãã»å
±æã忢ãã¿ã³ãæŒãããšãã®å¯Ÿå¿ Google Chrome ã§ç»é¢å
±æã®éã«è¡šç€ºããããå
±æã忢ããã¿ã³ãæŒäžããããPC ãã¹ãªãŒãã¢ãŒãã«ãããšãç»é¢ã® MediaStreamTrack ãéåããŠããŸããŸãã ããã¯è©²åœã® MediaStreamTrack ã« "ended" ã®ã€ãã³ããªã¹ããç»é²ããŠããããšã§ãã³ããªã³ã°ã§ããŸãã displayVideoTrack . addEventListener ( "ended" , handleEndedEvent , { once: true }); TypeScript ã®åã®å¯Ÿå¿ çŸç¶ TypeScript ã®åã getDisplayMedia() ã«å¯Ÿå¿ããŠããªãã£ããããä»åã¯å®è£
ã®åèã«ããŠãã skyway-conf ã§å©çšãããŠããå ãæµçšãã圢ã§å¯Ÿå¿ãããŸããã declare global { interface MediaDevices { getDisplayMedia ( constraints : MediaStreamConstraints ): Promise < MediaStream >; } } ããã¯æ ¹æ¬çã«ã¯ TypeScript ã® dom.d.ts ã«åå®çŸ©ãå
¥ã£ãŠããªãããšãèµ·å ããŠããŸããã TypeScript4.4 ã§å¯Ÿå¿ããããããã§ã ã ãŸãšã æšä»ã®ç¶æ³ã«ããããªã³ã©ã€ã³èšºå¯ã®ããŒãºãé«ãŸããç»é¢å
±ææ©èœã®éèŠæ§ãé«ãŸããŸããã 蚺å¯äžã®ç»é¢å
±ææ©èœã¯ä»¥äžã® api ãçµã¿åãããããšã§å®çŸããããšãã§ããŸãã PC ç»é¢ã® MediaStream 㯠getDisplayMedia() ã䜿ãããšã§ååŸ MediaStream ã«å«ããé³å£°ã»ç»åã¹ããªãŒã ã倿Žãããå Žå㯠MediaStreamTrack ã®çµã¿åãããå€ããããšã§äœæ æ¥ç¶äžã® MediaStream ã®å€æŽã¯ SkyWay ã® SDK ã® MediaConnection.replaceStream() ãäœ¿ã æåŸã« CLINICS ã§ã¯æ¬çš¿ã§ç޹ä»ããç»é¢å
±æãªã©ã®æ°èŠæ©èœã®å°å
¥ãæ¥ã
ã®æ¹åãéããŠãå»çæ©é¢ã»æ£è
åæ¹ã«æ¯æããããããã¯ããç®æãéçºãè¡ã£ãŠããŸããèå³ãæããããšã³ãžãã¢ã®æ¹ãããã£ããããŸããããã² ãã¡ã ã«ãé£çµ¡ããã ããã°ãšæããŸãã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã¯ããã« ã¯ãããŸããŠãã³ãŒãã¬ãŒããšã³ãžãã¢ã®å±±äžã§ãã 2020 幎㫠Slack ãæŽ»çšãã ChatOps çšè°ã¯ãŒã¯ãããŒãå
補ã§éçºããã®ã§ãããããã«ã2021 幎 4 æã«ãã® Slack çšè°ãšé»åå¥çŽã·ã¹ãã ã§ãã ã¯ã©ãŠããµã€ã³ ã飿ºãããŠãé»åå¥çŽããã£ãšäŸ¿å©ã«äœ¿ããçç£æ§ã®åäžãå®çŸããŸããã®ã§ã話ãããããŸãã ãŸããåœç€Ÿã®çšè°ã·ã¹ãã 㯠2020 幎 12 æã®åœç€Ÿã®èšäº ã®ããããã«ãªããŸãããçšè°ã®äœæ¥ã Slack äžã§å®çµããã ChatOps ã«ããçšè°ã¯ãŒã¯ãã㌠ãšãªã£ãŠãããŸããæ¬çš¿ã«ã€ããŠã¯ 2021 幎 7 æã«å·çããŠãããŸãã®ã§äžåºŠå°å
¥ãã 1 幎çšçµéãããã®é倧ããªãã©ãã«ãç¡ããä»ãåœç€Ÿã®æ¥µããŠè¿
éãªæææ±ºå®ã®äžå©ã«ãªã£ãŠããŸããChatOps ã«ããçšè°ã¯ãŒã¯ãããŒã«ã€ããŠã¯ãçŽè¿ã2021 幎 6 æã« LayerX 瀟ã LayerX ã¯ãŒã¯ãããŒã®æ°æ©èœãšããŠçºè¡š ãããµãŒãã¹ãšããŠãæäŸããã æ¥çµæ°è ã§ãåãäžããããŠããããšãããä»çŸåšã®ãã©ãã€ã ãšããŠãå
é²çã§æå¹ãªäžææ³ã§ãã£ããšåèªèããŠãããŸãã ä»åãæ°åã³ãããŠã€ã«ã¹æææ¡å€§é²æ¢ã«äŒŽããªã¢ãŒãã¯ãŒã¯ã®å éãšããç¶æ³ããããåœç€Ÿã§ 2021 幎 4 æã«é»åå¥çŽã·ã¹ãã ãšããŠã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããé»åå¥çŽã«éãããå¥çŽæŒå°äœæ¥ã¯çšè°ã®åŸç¶äœæ¥ã«åœããããããã å°å
¥ããŠäœ¿çšããã®ã¿ãªãããã¯ã©ãŠããµã€ã³ã® API ãå©çšããŠçšè°äžã«ããããŒã¿ãé»åå¥çŽã«éä¿¡ãããããšã§ã·ãŒã ã¬ã¹ãªé£æºãå®çŸããŠããŸããæ¬çš¿ã§ã¯åœç€Ÿãè¡ã£ãã·ãŒã ã¬ã¹ãªé£æºææ³ã«ã€ããŠè©³çްãã説æããããŸãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ã® API 飿ºã«ã€ã㊠å®è£
æŠèŠ åŒç€Ÿã®çšè°ã·ã¹ãã ã§ãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ãšã®é£æºã«ã€ããŠã話ãããŸãããŸããæ¬çš¿ã®éçºéšåãšã·ã¹ãã æ§æã¯äžèšã«ãªã£ãŠãããŸãã åŠçå
容ã®è©³çްã¯åŸã»ã©è¿°ã¹ãŸãããæŠèŠãšããŠã¯ TeamSprit(Apex)ããã¯ã©ãŠããµã€ã³ã® API ãã³ãŒã«ããã¯ã©ãŠããµã€ã³äžã§äœæããå¥çŽææžãžçšè°ã«èšèŒãããŠããå¥çŽæžãã¡ã€ã«ãå
æ¹æ
åœè
çã®æ
å ±ã飿ºããä»çµã¿ãšãªã£ãŠãããŸããããã«ããå¥çŽæ
åœè
ã¯ã¯ã©ãŠããµã€ã³ã«ãã°ã€ã³åŸãäžèšã® 3 ã¹ãããã§å
æ¹ã«éä¿¡ã§ããããã«ãªã£ãŠããŸãã èšèŒå
容ã®ç¢ºèª æŒå°ã»çœ²åç®æã®èšå® å
æ¹ãžã®éä¿¡ ã¯ã©ãŠããµã€ã³ã䜿çšããŠå¥çŽææžãäžããäœæããå Žåã®ãŠãŒã¶äœæ¥ãšãåœç€Ÿã§æ¡çšãã API 飿ºè¡ã£ãå Žåã®ãŠãŒã¶äœæ¥ãæ¯èŒãããã®ãäžèšã®è¡šã§ããäœæ¥ãååçšåºŠåæžãããããšãåãããŸãã äœæ¥é
çª äžããäœæããå Žå API 飿ºãå©çšããåœç€Ÿã®å Žå 1 ãã°ã€ã³ ãã°ã€ã³ 2 å¥çŽææžã®äœæ(ä»¶åãå¥çŽææžãšããŠã®å®åèšå®ç) ãªã 3 å¥çŽæžãã¡ã€ã«ã®ã¢ããããŒã ãªã 4 å
æ¹ã®éä¿¡å
èšå® ãªã 5 æŒå°æ¬ã®èšå® æŒå°æ¬ã®èšå® 6 å
æ¹ãžã®éä¿¡ å
æ¹ãžã®éä¿¡ å®è£
ä»åã®éçºã§äœ¿çšãã ã¯ã©ãŠããµã€ã³ API ã¯äžèšã® 5 ã€ã® API ã䜿çšããŸãã (â»ä»¥éãã¯ã©ãŠããµã€ã³ API ã«å£ãã倿°ã衚çŸããå Žå㯠{} ã§æ¬ããŸã)ã API çš®é¡ äœ¿çšçšé post /token ã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸ post /document å¥çŽææžã®äœæ put /documents/{documentID}/attribute å¥çŽææžã®äœæã§èšå®ã§ããªãã现ããé
ç®ã®èšå® post /documents/{documentID}/files ãã¡ã€ã«ã®ã¢ããããŒã post /documents/{documentID}/participants å
æ¹ã®éä¿¡å
èšå® å
šäœåã§èšèŒããã¯ã©ãŠããµã€ã³ã®é£æºéšã«ã€ããŠãäžèšã® API ãç¹ã亀ããŠè©³çްåãããšäžå³ã®ããã«ãªããŸãã å®è£
æ¹æ³ãšããŠã¯ã¯ã©ãŠããµã€ã³ API ã®ãªãã¡ã¬ã³ã¹ãåç
§ãããã¹ãå®è¡æã«åºåããã curl ã³ãã³ããåèã«åæ§ã®ã¬ã¹ãã³ã¹ãåŸãããã« Apex ã§ HTTP ãªã¯ãšã¹ããå®è£
ããŸãããã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸãäŸã«ãšããšäžèšã®ããã«ãªããŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/token' \ -H 'accept: application/json' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id=xxxxxxyyyyyyzzzzzz' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/token' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Content-Type' , 'application/x-www-form-urlencoded' ); req . setBody ( 'client_id=' + 'xxxxxxyyyyyyzzzzzz' ); ç§èªèº«ãApex ãã¯ã©ãŠããµã€ã³ API ããã®æ¡ä»¶ãæ
åœãããŸã§è§Šã£ãããšããããŸããã§ãããããªã¯ãšã¹ãã®è©Šè¡ããå®è£
ãŸã§ 2 é±éããããªãçšåºŠã§å®è£
ããããšãã§ããŸããã ãã ããå®è£
ãéçšã«ããã£ãŠã¯äžèš 2 ç¹ã«ã€ããŠæ³šæãå¿
èŠã«ãªããŸãã Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã 1. Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ãã¡ã€ã«ã®ã¢ããããŒãã«ã€ããŠã¯ä»å䜿çšãã API ã®äžã§ãå¯äžããã¹ãå®è¡ã® curl ãš Apex ã®ãªã¯ãšã¹ãå®è£
ã§å·®åãçãŸããŸãããŸãããã®å·®åã確èªããããã« curl ã³ãã³ãäŸãš Apex ã®ãªã¯ãšã¹ãå®è£
äŸã§ headerãbody ã«ã»ããããŠããå€ãæ¯èŒããŠã¿ãŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/documents/{document_id}/files' \ -H 'accept: application/json' \ -H 'Authorization: AAAAAABBBBBBCCCCCC' \ -H 'Content-Type: multipart/form-data' \ -F 'name=ãã¹ã' \ -F 'uploadfile=@ãã¹ã.pdf;type=application/pdf' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/documents/{document_id}/files' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Authorization' , âAAAAAABBBBBBCCCCCCâ); req . setHeader ( 'Content-Type' , 'multipart/form-data; boundary={boundary}' ); // â»1 req . setBodyAsBlob ({multipartBody}); // â»2 äž»ãªéã㯠â»1 , â»2 ãšã³ã¡ã³ãããéšåã«ãªããŸãã Apex ã§ã¯ HTTP ãªã¯ãšã¹ãã®å€ãæã§æžããŠããããšã«ãªãã®ã§ããã¹ãå®è¡äŸã®ããã« curl ããããªã«åŠçããŠããéšå(-F ãªãã·ã§ã³ã®éšåã Apex ã§èšèŒããŠãã boundary)ãå®è£
ããªããã°ãªããŸããããããåçŽã«å®è£
ã§ããªãçç±ã«ãªããŸãã boundary ã«ã€ããŠã¯ multipart/form-data ãéä¿¡ããéã«å¿
èŠãªå¢çã§ããããŒã§ã©ã®æååãå¢çã§ããããèšå®ããŸãã curl ã®-F ãªãã·ã§ã³ã§å®çŸ©ããŠããæååãšãã¡ã€ã«æå®éšåã¯ãApex ã§ãã¡ã€ã«(ãã€ããª)ãæ±ãããããã® body ã«å«ãŸããæååãå«ã㊠Blob åã§æ±ãå¿
èŠããããŸã( Content-Transfer-Encoding: base64 ã« API æäŸåŽã察å¿ããŠããå Žåã¯äŸå€ã«ãªããŸã)ããã®ãããæååãšãã€ããªããŒã¿ãçµåãäžã€ã® Blob ã«ããæ¹æ³ã¯äžèšã«ãªããŸãã ããã€ããªããŒã¿ãããbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã® 3 ã°ã«ãŒãã«åããã 3 ã°ã«ãŒãããããã Base64 ã§ç¬Šå·åããã 笊å·åããããã€ããªããŒã¿ããšãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååãã«ã€ããŠãBase64 ã®ããŒã¿ããã£ã³ã°ã瀺ãâ=âãå«ãŸããªãããã«æ¹è¡ã³ãŒãã§èª¿æŽããã ãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã®é ã§çµåããã çµåãã Base64 ã®ããŒã¿ã埩å·ããŠãäžã€ã® Blob ãšããã 2. ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã ã¢ã¯ã»ã¹ããŒã¯ã³ããã®æå¹æé㯠token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹ãšããŠã¯ã©ãŠããµã€ã³ããçºè¡ãããŸãã çºè¡ãããã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 3600 } ãã®ã¬ã¹ãã³ã¹ã®å
ãexpires_in ã®å€ãããŒã¯ã³ã®æå¹æéã«ãªããŸããæ²é¡ã®éããæå¹æéã®ç®¡çã¯ã¯ã©ãŠããµã€ã³åŽã§è¡ãããæå¹æéå
ã«å床ããŒã¯ã³ã®ãªã¯ãšã¹ããè¡ã£ãå Žåãçµéããæéã ã expires_in ã®å€ãå°ãããªã£ãçµæãè¿ã£ãŠããŠãaccess_token ãªã©ã¯åãå€ãååŸãããŸããæå¹æéå
ã« token API ãå床å®è¡ããçµæãäžèšã«ãªããŸãã æå¹æéåãåã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 762 } äžæ¹ãæå¹æéåŸã«ããŒã¯ã³ã®ãªã¯ãšã¹ããå®è¡ãããšããããŸã§ãšç°ãªãã¢ã¯ã»ã¹ããŒã¯ã³ãååŸããæ°ããæå¹æéãèšå®ãããŸãã æå¹æéåãåŸã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "XXXXXXYYYYYYZZZZZZ" , "token_type" : "xxxx" , "expires_in" : 3600 } ãã®ãããAPI 飿ºãäžåºŠåããåŸãæå¹æéããããã§ããäžåºŠ API 飿ºãåããŠããŸã£ãå Žåãã¿ã€ãã³ã°ãæªããšå¥çŽææžã®äœæããæçµåŠçã§ããå
æ¹ã®éä¿¡å
èšå®ãŸã§ã®ããã»ã¹å
ã®ã©ãããããããŒã¯ã³ã®æå¹æéåããçºçããå¯èœæ§ãæ³å®ãããŸããå®éã«æéåããçºçããå Žåãçºçæä»¥éã«çºè¡ãããã®åã® API 飿ºåŠçã倱æããŸãã ããŒã¯ã³ã®æå¹æéåããçºçããéãAPI ãªãã¡ã¬ã³ã¹ãã HTTP ã¹ããŒã¿ã¹ã³ãŒãã 401 ãã€ãšã©ãŒå
容ãâunauthorizedâã§å¿çãããããšãããåœç€Ÿã§ã¯ãã®ãšã©ãŒãåããå Žåã«ããŒã¯ã³ãåååŸããŠåŠçããªãã©ã€ããããã«å®è£
ããŸããã æŒå°ææžäœæãäŸã«ãšããšäžèšã®ãããªå®è£
ã€ã¡ãŒãžã«ãªããŸãã //ã¯ã©ãŠããµã€ã³äžã«æŒå°ææžãäœæããäœæããææž ID ãååŸãã public String getDocumentId ( String authToken, String title, String message){ ã»ã»ã»äžç¥ã»ã»ã» HTTPResponse res = http . send (req); if ( res . getStatusCode () == 200 ){ ã»ã»ã»æ£åžžã«çµäºããéã®åŠçã»ã»ã» } //ã¿ã€ãã³ã°ãæªã token ãã¿ã€ã ã¢ãŠãããå ŽåãããŒã¯ã³ãååŸãçŽããŠããªãã©ã€ãã else if ( res . getStatusCode () == 401 ){ //ã¬ã¹ãã³ã¹ã®å
容ã確èªããããããšã©ãŒã¬ã¹ãã³ã¹ã®äžèº«ãååŸãã Map < String , Object > responseBody = new Map < String , Object >(); responseBody = ( Map <String, Object>) JSON . deserializeUntyped ( res . getBody ()); String errorVal = (String) responseBody . get ( 'error' ); //ãªãã¡ã¬ã³ã¹äžãã¢ã¯ã»ã¹ããŒã¯ã³ãç¡å¹(æå¹æéåã)ã®å Žåã'unauthorizedâãšãªã if ( errorVal . equals ( 'unauthorized' )){ //ã¯ã©ãŠããµã€ã³ã®ã¢ã¯ã»ã¹ããŒã¯ã³ã®åååŸ authToken = getAuthToken (); //åçŽååž°ã§åå®è¡ããã documentId = getDocumentId (authToken, title, message); } ã»ã»ã»äžç¥ã»ã»ã» } ã»ã»ã»ä»¥äžçç¥ã»ã»ã» } å®è£
ãçµã㊠äžèšãå®è£
ããçµæãçšè°ãšå
¥åå
容ãåãããŸãã¯ãçšè°ããçæã§ããå
容ã¯å
šãŠã·ã¹ãã 飿ºã§èªåçæãããããæŒå°æ
åœã¯çšè°ãšã¯ã©ãŠããµã€ã³ã®ç»é¢ã䞊ã¹ãŠè»¢èšãããããªç
©éãªäœæ¥ãå¿
èŠãšããªãç°å¢ã«ãªããŸããããŸããå¥çŽæžã®è£œæ¬ãéµéçã®çŽåªäœã§ãããæ
ã®äºåã®åæžãã§ããããã«ãªãçã®ãé»åå¥çŽãå°å
¥ããããšã®ããããã®ã¡ãªããã䜵ããŠäº«åããŠããŸãã åœç€Ÿã§ã¯ 2021 幎 4 æåŸåããã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããã2021 幎 6 ææç¹ã§ã¯ãã§ã« æéã§ç· çµããå¥çŽæžã®ã3 å²ä»¥äžããé»åå¥çŽã掻çšããŠãã ãæŒå°æ
åœã®å±æãšããŠä»åŸãå©çšãæ¡å€§ããŠããäºå®ã§ãã ã³ãŒãã¬ãŒããšã³ãžãã¢åéäž ã¡ãã¬ãŒã®ã³ãŒãã¬ãŒãéšéã§ã¯ãæ¬çš¿ã®ããã«ãSaaS ã®å°å
¥ã²ãšã€ãšã£ãŠãæ€èšãå°œãããæ¢åã®ã·ã¹ãã ãšææ©çã«çµåãããããšã§ã培åºçã«åçæ§ã远æ±ããçµç¹åºç€ãã仿ãã¥ããããè¡ã£ãŠããŸãã é¢çœããïŒèå³ãããïŒãšæããæ¹ã¯ããã²åœç€Ÿæ¡çšããŒãžãããå¿åãé¡ãããŸãïŒ æåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã https://www.medley.jp/jobs/
ã¯ããã« ã¯ãããŸããŠãã³ãŒãã¬ãŒããšã³ãžãã¢ã®å±±äžã§ãã 2020 幎㫠Slack ãæŽ»çšãã ChatOps çšè°ã¯ãŒã¯ãããŒãå
補ã§éçºããã®ã§ãããããã«ã2021 幎 4 æã«ãã® Slack çšè°ãšé»åå¥çŽã·ã¹ãã ã§ãã ã¯ã©ãŠããµã€ã³ ã飿ºãããŠãé»åå¥çŽããã£ãšäŸ¿å©ã«äœ¿ããçç£æ§ã®åäžãå®çŸããŸããã®ã§ã話ãããããŸãã ãŸããåœç€Ÿã®çšè°ã·ã¹ãã 㯠2020 幎 12 æã®åœç€Ÿã®èšäº ã®ããããã«ãªããŸãããçšè°ã®äœæ¥ã Slack äžã§å®çµããã ChatOps ã«ããçšè°ã¯ãŒã¯ãã㌠ãšãªã£ãŠãããŸããæ¬çš¿ã«ã€ããŠã¯ 2021 幎 7 æã«å·çããŠãããŸãã®ã§äžåºŠå°å
¥ãã 1 幎çšçµéãããã®é倧ããªãã©ãã«ãç¡ããä»ãåœç€Ÿã®æ¥µããŠè¿
éãªæææ±ºå®ã®äžå©ã«ãªã£ãŠããŸããChatOps ã«ããçšè°ã¯ãŒã¯ãããŒã«ã€ããŠã¯ãçŽè¿ã2021 幎 6 æã« LayerX 瀟ã LayerX ã¯ãŒã¯ãããŒã®æ°æ©èœãšããŠçºè¡š ãããµãŒãã¹ãšããŠãæäŸããã æ¥çµæ°è ã§ãåãäžããããŠããããšãããä»çŸåšã®ãã©ãã€ã ãšããŠãå
é²çã§æå¹ãªäžææ³ã§ãã£ããšåèªèããŠãããŸãã ä»åãæ°åã³ãããŠã€ã«ã¹æææ¡å€§é²æ¢ã«äŒŽããªã¢ãŒãã¯ãŒã¯ã®å éãšããç¶æ³ããããåœç€Ÿã§ 2021 幎 4 æã«é»åå¥çŽã·ã¹ãã ãšããŠã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããé»åå¥çŽã«éãããå¥çŽæŒå°äœæ¥ã¯çšè°ã®åŸç¶äœæ¥ã«åœããããããã å°å
¥ããŠäœ¿çšããã®ã¿ãªãããã¯ã©ãŠããµã€ã³ã® API ãå©çšããŠçšè°äžã«ããããŒã¿ãé»åå¥çŽã«éä¿¡ãããããšã§ã·ãŒã ã¬ã¹ãªé£æºãå®çŸããŠããŸããæ¬çš¿ã§ã¯åœç€Ÿãè¡ã£ãã·ãŒã ã¬ã¹ãªé£æºææ³ã«ã€ããŠè©³çްãã説æããããŸãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ã® API 飿ºã«ã€ã㊠å®è£
æŠèŠ åŒç€Ÿã®çšè°ã·ã¹ãã ã§ãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ãšã®é£æºã«ã€ããŠã話ãããŸãããŸããæ¬çš¿ã®éçºéšåãšã·ã¹ãã æ§æã¯äžèšã«ãªã£ãŠãããŸãã åŠçå
容ã®è©³çްã¯åŸã»ã©è¿°ã¹ãŸãããæŠèŠãšããŠã¯ TeamSprit(Apex)ããã¯ã©ãŠããµã€ã³ã® API ãã³ãŒã«ããã¯ã©ãŠããµã€ã³äžã§äœæããå¥çŽææžãžçšè°ã«èšèŒãããŠããå¥çŽæžãã¡ã€ã«ãå
æ¹æ
åœè
çã®æ
å ±ã飿ºããä»çµã¿ãšãªã£ãŠãããŸããããã«ããå¥çŽæ
åœè
ã¯ã¯ã©ãŠããµã€ã³ã«ãã°ã€ã³åŸãäžèšã® 3 ã¹ãããã§å
æ¹ã«éä¿¡ã§ããããã«ãªã£ãŠããŸãã èšèŒå
容ã®ç¢ºèª æŒå°ã»çœ²åç®æã®èšå® å
æ¹ãžã®éä¿¡ ã¯ã©ãŠããµã€ã³ã䜿çšããŠå¥çŽææžãäžããäœæããå Žåã®ãŠãŒã¶äœæ¥ãšãåœç€Ÿã§æ¡çšãã API 飿ºè¡ã£ãå Žåã®ãŠãŒã¶äœæ¥ãæ¯èŒãããã®ãäžèšã®è¡šã§ããäœæ¥ãååçšåºŠåæžãããããšãåãããŸãã äœæ¥é
çª äžããäœæããå Žå API 飿ºãå©çšããåœç€Ÿã®å Žå 1 ãã°ã€ã³ ãã°ã€ã³ 2 å¥çŽææžã®äœæ(ä»¶åãå¥çŽææžãšããŠã®å®åèšå®ç) ãªã 3 å¥çŽæžãã¡ã€ã«ã®ã¢ããããŒã ãªã 4 å
æ¹ã®éä¿¡å
èšå® ãªã 5 æŒå°æ¬ã®èšå® æŒå°æ¬ã®èšå® 6 å
æ¹ãžã®éä¿¡ å
æ¹ãžã®éä¿¡ å®è£
ä»åã®éçºã§äœ¿çšãã ã¯ã©ãŠããµã€ã³ API ã¯äžèšã® 5 ã€ã® API ã䜿çšããŸãã (â»ä»¥éãã¯ã©ãŠããµã€ã³ API ã«å£ãã倿°ã衚çŸããå Žå㯠{} ã§æ¬ããŸã)ã API çš®é¡ äœ¿çšçšé post /token ã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸ post /document å¥çŽææžã®äœæ put /documents/{documentID}/attribute å¥çŽææžã®äœæã§èšå®ã§ããªãã现ããé
ç®ã®èšå® post /documents/{documentID}/files ãã¡ã€ã«ã®ã¢ããããŒã post /documents/{documentID}/participants å
æ¹ã®éä¿¡å
èšå® å
šäœåã§èšèŒããã¯ã©ãŠããµã€ã³ã®é£æºéšã«ã€ããŠãäžèšã® API ãç¹ã亀ããŠè©³çްåãããšäžå³ã®ããã«ãªããŸãã å®è£
æ¹æ³ãšããŠã¯ã¯ã©ãŠããµã€ã³ API ã®ãªãã¡ã¬ã³ã¹ãåç
§ãããã¹ãå®è¡æã«åºåããã curl ã³ãã³ããåèã«åæ§ã®ã¬ã¹ãã³ã¹ãåŸãããã« Apex ã§ HTTP ãªã¯ãšã¹ããå®è£
ããŸãããã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸãäŸã«ãšããšäžèšã®ããã«ãªããŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/token' \ -H 'accept: application/json' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id=xxxxxxyyyyyyzzzzzz' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/token' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Content-Type' , 'application/x-www-form-urlencoded' ); req . setBody ( 'client_id=' + 'xxxxxxyyyyyyzzzzzz' ); ç§èªèº«ãApex ãã¯ã©ãŠããµã€ã³ API ããã®æ¡ä»¶ãæ
åœãããŸã§è§Šã£ãããšããããŸããã§ãããããªã¯ãšã¹ãã®è©Šè¡ããå®è£
ãŸã§ 2 é±éããããªãçšåºŠã§å®è£
ããããšãã§ããŸããã ãã ããå®è£
ãéçšã«ããã£ãŠã¯äžèš 2 ç¹ã«ã€ããŠæ³šæãå¿
èŠã«ãªããŸãã Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã 1. Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ãã¡ã€ã«ã®ã¢ããããŒãã«ã€ããŠã¯ä»å䜿çšãã API ã®äžã§ãå¯äžããã¹ãå®è¡ã® curl ãš Apex ã®ãªã¯ãšã¹ãå®è£
ã§å·®åãçãŸããŸãããŸãããã®å·®åã確èªããããã« curl ã³ãã³ãäŸãš Apex ã®ãªã¯ãšã¹ãå®è£
äŸã§ headerãbody ã«ã»ããããŠããå€ãæ¯èŒããŠã¿ãŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/documents/{document_id}/files' \ -H 'accept: application/json' \ -H 'Authorization: AAAAAABBBBBBCCCCCC' \ -H 'Content-Type: multipart/form-data' \ -F 'name=ãã¹ã' \ -F 'uploadfile=@ãã¹ã.pdf;type=application/pdf' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/documents/{document_id}/files' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Authorization' , âAAAAAABBBBBBCCCCCCâ); req . setHeader ( 'Content-Type' , 'multipart/form-data; boundary={boundary}' ); // â»1 req . setBodyAsBlob ({multipartBody}); // â»2 äž»ãªéã㯠â»1 , â»2 ãšã³ã¡ã³ãããéšåã«ãªããŸãã Apex ã§ã¯ HTTP ãªã¯ãšã¹ãã®å€ãæã§æžããŠããããšã«ãªãã®ã§ããã¹ãå®è¡äŸã®ããã« curl ããããªã«åŠçããŠããéšå(-F ãªãã·ã§ã³ã®éšåã Apex ã§èšèŒããŠãã boundary)ãå®è£
ããªããã°ãªããŸããããããåçŽã«å®è£
ã§ããªãçç±ã«ãªããŸãã boundary ã«ã€ããŠã¯ multipart/form-data ãéä¿¡ããéã«å¿
èŠãªå¢çã§ããããŒã§ã©ã®æååãå¢çã§ããããèšå®ããŸãã curl ã®-F ãªãã·ã§ã³ã§å®çŸ©ããŠããæååãšãã¡ã€ã«æå®éšåã¯ãApex ã§ãã¡ã€ã«(ãã€ããª)ãæ±ãããããã® body ã«å«ãŸããæååãå«ã㊠Blob åã§æ±ãå¿
èŠããããŸã( Content-Transfer-Encoding: base64 ã« API æäŸåŽã察å¿ããŠããå Žåã¯äŸå€ã«ãªããŸã)ããã®ãããæååãšãã€ããªããŒã¿ãçµåãäžã€ã® Blob ã«ããæ¹æ³ã¯äžèšã«ãªããŸãã ããã€ããªããŒã¿ãããbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã® 3 ã°ã«ãŒãã«åããã 3 ã°ã«ãŒãããããã Base64 ã§ç¬Šå·åããã 笊å·åããããã€ããªããŒã¿ããšãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååãã«ã€ããŠãBase64 ã®ããŒã¿ããã£ã³ã°ã瀺ãâ=âãå«ãŸããªãããã«æ¹è¡ã³ãŒãã§èª¿æŽããã ãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã®é ã§çµåããã çµåãã Base64 ã®ããŒã¿ã埩å·ããŠãäžã€ã® Blob ãšããã 2. ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã ã¢ã¯ã»ã¹ããŒã¯ã³ããã®æå¹æé㯠token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹ãšããŠã¯ã©ãŠããµã€ã³ããçºè¡ãããŸãã çºè¡ãããã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 3600 } ãã®ã¬ã¹ãã³ã¹ã®å
ãexpires_in ã®å€ãããŒã¯ã³ã®æå¹æéã«ãªããŸããæ²é¡ã®éããæå¹æéã®ç®¡çã¯ã¯ã©ãŠããµã€ã³åŽã§è¡ãããæå¹æéå
ã«å床ããŒã¯ã³ã®ãªã¯ãšã¹ããè¡ã£ãå Žåãçµéããæéã ã expires_in ã®å€ãå°ãããªã£ãçµæãè¿ã£ãŠããŠãaccess_token ãªã©ã¯åãå€ãååŸãããŸããæå¹æéå
ã« token API ãå床å®è¡ããçµæãäžèšã«ãªããŸãã æå¹æéåãåã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 762 } äžæ¹ãæå¹æéåŸã«ããŒã¯ã³ã®ãªã¯ãšã¹ããå®è¡ãããšããããŸã§ãšç°ãªãã¢ã¯ã»ã¹ããŒã¯ã³ãååŸããæ°ããæå¹æéãèšå®ãããŸãã æå¹æéåãåŸã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "XXXXXXYYYYYYZZZZZZ" , "token_type" : "xxxx" , "expires_in" : 3600 } ãã®ãããAPI 飿ºãäžåºŠåããåŸãæå¹æéããããã§ããäžåºŠ API 飿ºãåããŠããŸã£ãå Žåãã¿ã€ãã³ã°ãæªããšå¥çŽææžã®äœæããæçµåŠçã§ããå
æ¹ã®éä¿¡å
èšå®ãŸã§ã®ããã»ã¹å
ã®ã©ãããããããŒã¯ã³ã®æå¹æéåããçºçããå¯èœæ§ãæ³å®ãããŸããå®éã«æéåããçºçããå Žåãçºçæä»¥éã«çºè¡ãããã®åã® API 飿ºåŠçã倱æããŸãã ããŒã¯ã³ã®æå¹æéåããçºçããéãAPI ãªãã¡ã¬ã³ã¹ãã HTTP ã¹ããŒã¿ã¹ã³ãŒãã 401 ãã€ãšã©ãŒå
容ãâunauthorizedâã§å¿çãããããšãããåœç€Ÿã§ã¯ãã®ãšã©ãŒãåããå Žåã«ããŒã¯ã³ãåååŸããŠåŠçããªãã©ã€ããããã«å®è£
ããŸããã æŒå°ææžäœæãäŸã«ãšããšäžèšã®ãããªå®è£
ã€ã¡ãŒãžã«ãªããŸãã //ã¯ã©ãŠããµã€ã³äžã«æŒå°ææžãäœæããäœæããææž ID ãååŸãã public String getDocumentId ( String authToken, String title, String message){ ã»ã»ã»äžç¥ã»ã»ã» HTTPResponse res = http . send (req); if ( res . getStatusCode () == 200 ){ ã»ã»ã»æ£åžžã«çµäºããéã®åŠçã»ã»ã» } //ã¿ã€ãã³ã°ãæªã token ãã¿ã€ã ã¢ãŠãããå ŽåãããŒã¯ã³ãååŸãçŽããŠããªãã©ã€ãã else if ( res . getStatusCode () == 401 ){ //ã¬ã¹ãã³ã¹ã®å
容ã確èªããããããšã©ãŒã¬ã¹ãã³ã¹ã®äžèº«ãååŸãã Map < String , Object > responseBody = new Map < String , Object >(); responseBody = ( Map <String, Object>) JSON . deserializeUntyped ( res . getBody ()); String errorVal = (String) responseBody . get ( 'error' ); //ãªãã¡ã¬ã³ã¹äžãã¢ã¯ã»ã¹ããŒã¯ã³ãç¡å¹(æå¹æéåã)ã®å Žåã'unauthorizedâãšãªã if ( errorVal . equals ( 'unauthorized' )){ //ã¯ã©ãŠããµã€ã³ã®ã¢ã¯ã»ã¹ããŒã¯ã³ã®åååŸ authToken = getAuthToken (); //åçŽååž°ã§åå®è¡ããã documentId = getDocumentId (authToken, title, message); } ã»ã»ã»äžç¥ã»ã»ã» } ã»ã»ã»ä»¥äžçç¥ã»ã»ã» } å®è£
ãçµã㊠äžèšãå®è£
ããçµæãçšè°ãšå
¥åå
容ãåãããŸãã¯ãçšè°ããçæã§ããå
容ã¯å
šãŠã·ã¹ãã 飿ºã§èªåçæãããããæŒå°æ
åœã¯çšè°ãšã¯ã©ãŠããµã€ã³ã®ç»é¢ã䞊ã¹ãŠè»¢èšãããããªç
©éãªäœæ¥ãå¿
èŠãšããªãç°å¢ã«ãªããŸããããŸããå¥çŽæžã®è£œæ¬ãéµéçã®çŽåªäœã§ãããæ
ã®äºåã®åæžãã§ããããã«ãªãçã®ãé»åå¥çŽãå°å
¥ããããšã®ããããã®ã¡ãªããã䜵ããŠäº«åããŠããŸãã åœç€Ÿã§ã¯ 2021 幎 4 æåŸåããã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããã2021 幎 6 ææç¹ã§ã¯ãã§ã« æéã§ç· çµããå¥çŽæžã®ã3 å²ä»¥äžããé»åå¥çŽã掻çšããŠãã ãæŒå°æ
åœã®å±æãšããŠä»åŸãå©çšãæ¡å€§ããŠããäºå®ã§ãã ã³ãŒãã¬ãŒããšã³ãžãã¢åéäž ã¡ãã¬ãŒã®ã³ãŒãã¬ãŒãéšéã§ã¯ãæ¬çš¿ã®ããã«ãSaaS ã®å°å
¥ã²ãšã€ãšã£ãŠãæ€èšãå°œãããæ¢åã®ã·ã¹ãã ãšææ©çã«çµåãããããšã§ã培åºçã«åçæ§ã远æ±ããçµç¹åºç€ãã仿ãã¥ããããè¡ã£ãŠããŸãã é¢çœããïŒèå³ãããïŒãšæããæ¹ã¯ããã²åœç€Ÿæ¡çšããŒãžãããå¿åãé¡ãããŸãïŒ æåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã¯ããã« ã¯ãããŸããŠãã³ãŒãã¬ãŒããšã³ãžãã¢ã®å±±äžã§ãã 2020 幎㫠Slack ãæŽ»çšãã ChatOps çšè°ã¯ãŒã¯ãããŒãå
補ã§éçºããã®ã§ãããããã«ã2021 幎 4 æã«ãã® Slack çšè°ãšé»åå¥çŽã·ã¹ãã ã§ãã ã¯ã©ãŠããµã€ã³ ã飿ºãããŠãé»åå¥çŽããã£ãšäŸ¿å©ã«äœ¿ããçç£æ§ã®åäžãå®çŸããŸããã®ã§ã話ãããããŸãã ãŸããåœç€Ÿã®çšè°ã·ã¹ãã 㯠2020 幎 12 æã®åœç€Ÿã®èšäº ã®ããããã«ãªããŸãããçšè°ã®äœæ¥ã Slack äžã§å®çµããã ChatOps ã«ããçšè°ã¯ãŒã¯ãã㌠ãšãªã£ãŠãããŸããæ¬çš¿ã«ã€ããŠã¯ 2021 幎 7 æã«å·çããŠãããŸãã®ã§äžåºŠå°å
¥ãã 1 幎çšçµéãããã®é倧ããªãã©ãã«ãç¡ããä»ãåœç€Ÿã®æ¥µããŠè¿
éãªæææ±ºå®ã®äžå©ã«ãªã£ãŠããŸããChatOps ã«ããçšè°ã¯ãŒã¯ãããŒã«ã€ããŠã¯ãçŽè¿ã2021 幎 6 æã« LayerX 瀟ã LayerX ã¯ãŒã¯ãããŒã®æ°æ©èœãšããŠçºè¡š ãããµãŒãã¹ãšããŠãæäŸããã æ¥çµæ°è ã§ãåãäžããããŠããããšãããä»çŸåšã®ãã©ãã€ã ãšããŠãå
é²çã§æå¹ãªäžææ³ã§ãã£ããšåèªèããŠãããŸãã ä»åãæ°åã³ãããŠã€ã«ã¹æææ¡å€§é²æ¢ã«äŒŽããªã¢ãŒãã¯ãŒã¯ã®å éãšããç¶æ³ããããåœç€Ÿã§ 2021 幎 4 æã«é»åå¥çŽã·ã¹ãã ãšããŠã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããé»åå¥çŽã«éãããå¥çŽæŒå°äœæ¥ã¯çšè°ã®åŸç¶äœæ¥ã«åœããããããã å°å
¥ããŠäœ¿çšããã®ã¿ãªãããã¯ã©ãŠããµã€ã³ã® API ãå©çšããŠçšè°äžã«ããããŒã¿ãé»åå¥çŽã«éä¿¡ãããããšã§ã·ãŒã ã¬ã¹ãªé£æºãå®çŸããŠããŸããæ¬çš¿ã§ã¯åœç€Ÿãè¡ã£ãã·ãŒã ã¬ã¹ãªé£æºææ³ã«ã€ããŠè©³çްãã説æããããŸãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ã® API 飿ºã«ã€ã㊠å®è£
æŠèŠ åŒç€Ÿã®çšè°ã·ã¹ãã ã§ãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ãšã®é£æºã«ã€ããŠã話ãããŸãããŸããæ¬çš¿ã®éçºéšåãšã·ã¹ãã æ§æã¯äžèšã«ãªã£ãŠãããŸãã åŠçå
容ã®è©³çްã¯åŸã»ã©è¿°ã¹ãŸãããæŠèŠãšããŠã¯ TeamSprit(Apex)ããã¯ã©ãŠããµã€ã³ã® API ãã³ãŒã«ããã¯ã©ãŠããµã€ã³äžã§äœæããå¥çŽææžãžçšè°ã«èšèŒãããŠããå¥çŽæžãã¡ã€ã«ãå
æ¹æ
åœè
çã®æ
å ±ã飿ºããä»çµã¿ãšãªã£ãŠãããŸããããã«ããå¥çŽæ
åœè
ã¯ã¯ã©ãŠããµã€ã³ã«ãã°ã€ã³åŸãäžèšã® 3 ã¹ãããã§å
æ¹ã«éä¿¡ã§ããããã«ãªã£ãŠããŸãã èšèŒå
容ã®ç¢ºèª æŒå°ã»çœ²åç®æã®èšå® å
æ¹ãžã®éä¿¡ ã¯ã©ãŠããµã€ã³ã䜿çšããŠå¥çŽææžãäžããäœæããå Žåã®ãŠãŒã¶äœæ¥ãšãåœç€Ÿã§æ¡çšãã API 飿ºè¡ã£ãå Žåã®ãŠãŒã¶äœæ¥ãæ¯èŒãããã®ãäžèšã®è¡šã§ããäœæ¥ãååçšåºŠåæžãããããšãåãããŸãã äœæ¥é
çª äžããäœæããå Žå API 飿ºãå©çšããåœç€Ÿã®å Žå 1 ãã°ã€ã³ ãã°ã€ã³ 2 å¥çŽææžã®äœæ(ä»¶åãå¥çŽææžãšããŠã®å®åèšå®ç) ãªã 3 å¥çŽæžãã¡ã€ã«ã®ã¢ããããŒã ãªã 4 å
æ¹ã®éä¿¡å
èšå® ãªã 5 æŒå°æ¬ã®èšå® æŒå°æ¬ã®èšå® 6 å
æ¹ãžã®éä¿¡ å
æ¹ãžã®éä¿¡ å®è£
ä»åã®éçºã§äœ¿çšãã ã¯ã©ãŠããµã€ã³ API ã¯äžèšã® 5 ã€ã® API ã䜿çšããŸãã (â»ä»¥éãã¯ã©ãŠããµã€ã³ API ã«å£ãã倿°ã衚çŸããå Žå㯠{} ã§æ¬ããŸã)ã API çš®é¡ äœ¿çšçšé post /token ã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸ post /document å¥çŽææžã®äœæ put /documents/{documentID}/attribute å¥çŽææžã®äœæã§èšå®ã§ããªãã现ããé
ç®ã®èšå® post /documents/{documentID}/files ãã¡ã€ã«ã®ã¢ããããŒã post /documents/{documentID}/participants å
æ¹ã®éä¿¡å
èšå® å
šäœåã§èšèŒããã¯ã©ãŠããµã€ã³ã®é£æºéšã«ã€ããŠãäžèšã® API ãç¹ã亀ããŠè©³çްåãããšäžå³ã®ããã«ãªããŸãã å®è£
æ¹æ³ãšããŠã¯ã¯ã©ãŠããµã€ã³ API ã®ãªãã¡ã¬ã³ã¹ãåç
§ãããã¹ãå®è¡æã«åºåããã curl ã³ãã³ããåèã«åæ§ã®ã¬ã¹ãã³ã¹ãåŸãããã« Apex ã§ HTTP ãªã¯ãšã¹ããå®è£
ããŸãããã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸãäŸã«ãšããšäžèšã®ããã«ãªããŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/token' \ -H 'accept: application/json' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id=xxxxxxyyyyyyzzzzzz' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/token' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Content-Type' , 'application/x-www-form-urlencoded' ); req . setBody ( 'client_id=' + 'xxxxxxyyyyyyzzzzzz' ); ç§èªèº«ãApex ãã¯ã©ãŠããµã€ã³ API ããã®æ¡ä»¶ãæ
åœãããŸã§è§Šã£ãããšããããŸããã§ãããããªã¯ãšã¹ãã®è©Šè¡ããå®è£
ãŸã§ 2 é±éããããªãçšåºŠã§å®è£
ããããšãã§ããŸããã ãã ããå®è£
ãéçšã«ããã£ãŠã¯äžèš 2 ç¹ã«ã€ããŠæ³šæãå¿
èŠã«ãªããŸãã Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã 1. Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ãã¡ã€ã«ã®ã¢ããããŒãã«ã€ããŠã¯ä»å䜿çšãã API ã®äžã§ãå¯äžããã¹ãå®è¡ã® curl ãš Apex ã®ãªã¯ãšã¹ãå®è£
ã§å·®åãçãŸããŸãããŸãããã®å·®åã確èªããããã« curl ã³ãã³ãäŸãš Apex ã®ãªã¯ãšã¹ãå®è£
äŸã§ headerãbody ã«ã»ããããŠããå€ãæ¯èŒããŠã¿ãŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/documents/{document_id}/files' \ -H 'accept: application/json' \ -H 'Authorization: AAAAAABBBBBBCCCCCC' \ -H 'Content-Type: multipart/form-data' \ -F 'name=ãã¹ã' \ -F 'uploadfile=@ãã¹ã.pdf;type=application/pdf' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/documents/{document_id}/files' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Authorization' , âAAAAAABBBBBBCCCCCCâ); req . setHeader ( 'Content-Type' , 'multipart/form-data; boundary={boundary}' ); // â»1 req . setBodyAsBlob ({multipartBody}); // â»2 äž»ãªéã㯠â»1 , â»2 ãšã³ã¡ã³ãããéšåã«ãªããŸãã Apex ã§ã¯ HTTP ãªã¯ãšã¹ãã®å€ãæã§æžããŠããããšã«ãªãã®ã§ããã¹ãå®è¡äŸã®ããã« curl ããããªã«åŠçããŠããéšå(-F ãªãã·ã§ã³ã®éšåã Apex ã§èšèŒããŠãã boundary)ãå®è£
ããªããã°ãªããŸããããããåçŽã«å®è£
ã§ããªãçç±ã«ãªããŸãã boundary ã«ã€ããŠã¯ multipart/form-data ãéä¿¡ããéã«å¿
èŠãªå¢çã§ããããŒã§ã©ã®æååãå¢çã§ããããèšå®ããŸãã curl ã®-F ãªãã·ã§ã³ã§å®çŸ©ããŠããæååãšãã¡ã€ã«æå®éšåã¯ãApex ã§ãã¡ã€ã«(ãã€ããª)ãæ±ãããããã® body ã«å«ãŸããæååãå«ã㊠Blob åã§æ±ãå¿
èŠããããŸã( Content-Transfer-Encoding: base64 ã« API æäŸåŽã察å¿ããŠããå Žåã¯äŸå€ã«ãªããŸã)ããã®ãããæååãšãã€ããªããŒã¿ãçµåãäžã€ã® Blob ã«ããæ¹æ³ã¯äžèšã«ãªããŸãã ããã€ããªããŒã¿ãããbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã® 3 ã°ã«ãŒãã«åããã 3 ã°ã«ãŒãããããã Base64 ã§ç¬Šå·åããã 笊å·åããããã€ããªããŒã¿ããšãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååãã«ã€ããŠãBase64 ã®ããŒã¿ããã£ã³ã°ã瀺ãâ=âãå«ãŸããªãããã«æ¹è¡ã³ãŒãã§èª¿æŽããã ãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã®é ã§çµåããã çµåãã Base64 ã®ããŒã¿ã埩å·ããŠãäžã€ã® Blob ãšããã 2. ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã ã¢ã¯ã»ã¹ããŒã¯ã³ããã®æå¹æé㯠token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹ãšããŠã¯ã©ãŠããµã€ã³ããçºè¡ãããŸãã çºè¡ãããã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 3600 } ãã®ã¬ã¹ãã³ã¹ã®å
ãexpires_in ã®å€ãããŒã¯ã³ã®æå¹æéã«ãªããŸããæ²é¡ã®éããæå¹æéã®ç®¡çã¯ã¯ã©ãŠããµã€ã³åŽã§è¡ãããæå¹æéå
ã«å床ããŒã¯ã³ã®ãªã¯ãšã¹ããè¡ã£ãå Žåãçµéããæéã ã expires_in ã®å€ãå°ãããªã£ãçµæãè¿ã£ãŠããŠãaccess_token ãªã©ã¯åãå€ãååŸãããŸããæå¹æéå
ã« token API ãå床å®è¡ããçµæãäžèšã«ãªããŸãã æå¹æéåãåã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 762 } äžæ¹ãæå¹æéåŸã«ããŒã¯ã³ã®ãªã¯ãšã¹ããå®è¡ãããšããããŸã§ãšç°ãªãã¢ã¯ã»ã¹ããŒã¯ã³ãååŸããæ°ããæå¹æéãèšå®ãããŸãã æå¹æéåãåŸã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "XXXXXXYYYYYYZZZZZZ" , "token_type" : "xxxx" , "expires_in" : 3600 } ãã®ãããAPI 飿ºãäžåºŠåããåŸãæå¹æéããããã§ããäžåºŠ API 飿ºãåããŠããŸã£ãå Žåãã¿ã€ãã³ã°ãæªããšå¥çŽææžã®äœæããæçµåŠçã§ããå
æ¹ã®éä¿¡å
èšå®ãŸã§ã®ããã»ã¹å
ã®ã©ãããããããŒã¯ã³ã®æå¹æéåããçºçããå¯èœæ§ãæ³å®ãããŸããå®éã«æéåããçºçããå Žåãçºçæä»¥éã«çºè¡ãããã®åã® API 飿ºåŠçã倱æããŸãã ããŒã¯ã³ã®æå¹æéåããçºçããéãAPI ãªãã¡ã¬ã³ã¹ãã HTTP ã¹ããŒã¿ã¹ã³ãŒãã 401 ãã€ãšã©ãŒå
容ãâunauthorizedâã§å¿çãããããšãããåœç€Ÿã§ã¯ãã®ãšã©ãŒãåããå Žåã«ããŒã¯ã³ãåååŸããŠåŠçããªãã©ã€ããããã«å®è£
ããŸããã æŒå°ææžäœæãäŸã«ãšããšäžèšã®ãããªå®è£
ã€ã¡ãŒãžã«ãªããŸãã //ã¯ã©ãŠããµã€ã³äžã«æŒå°ææžãäœæããäœæããææž ID ãååŸãã public String getDocumentId ( String authToken, String title, String message){ ã»ã»ã»äžç¥ã»ã»ã» HTTPResponse res = http . send (req); if ( res . getStatusCode () == 200 ){ ã»ã»ã»æ£åžžã«çµäºããéã®åŠçã»ã»ã» } //ã¿ã€ãã³ã°ãæªã token ãã¿ã€ã ã¢ãŠãããå ŽåãããŒã¯ã³ãååŸãçŽããŠããªãã©ã€ãã else if ( res . getStatusCode () == 401 ){ //ã¬ã¹ãã³ã¹ã®å
容ã確èªããããããšã©ãŒã¬ã¹ãã³ã¹ã®äžèº«ãååŸãã Map < String , Object > responseBody = new Map < String , Object >(); responseBody = ( Map <String, Object>) JSON . deserializeUntyped ( res . getBody ()); String errorVal = (String) responseBody . get ( 'error' ); //ãªãã¡ã¬ã³ã¹äžãã¢ã¯ã»ã¹ããŒã¯ã³ãç¡å¹(æå¹æéåã)ã®å Žåã'unauthorizedâãšãªã if ( errorVal . equals ( 'unauthorized' )){ //ã¯ã©ãŠããµã€ã³ã®ã¢ã¯ã»ã¹ããŒã¯ã³ã®åååŸ authToken = getAuthToken (); //åçŽååž°ã§åå®è¡ããã documentId = getDocumentId (authToken, title, message); } ã»ã»ã»äžç¥ã»ã»ã» } ã»ã»ã»ä»¥äžçç¥ã»ã»ã» } å®è£
ãçµã㊠äžèšãå®è£
ããçµæãçšè°ãšå
¥åå
容ãåãããŸãã¯ãçšè°ããçæã§ããå
容ã¯å
šãŠã·ã¹ãã 飿ºã§èªåçæãããããæŒå°æ
åœã¯çšè°ãšã¯ã©ãŠããµã€ã³ã®ç»é¢ã䞊ã¹ãŠè»¢èšãããããªç
©éãªäœæ¥ãå¿
èŠãšããªãç°å¢ã«ãªããŸããããŸããå¥çŽæžã®è£œæ¬ãéµéçã®çŽåªäœã§ãããæ
ã®äºåã®åæžãã§ããããã«ãªãçã®ãé»åå¥çŽãå°å
¥ããããšã®ããããã®ã¡ãªããã䜵ããŠäº«åããŠããŸãã åœç€Ÿã§ã¯ 2021 幎 4 æåŸåããã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããã2021 幎 6 ææç¹ã§ã¯ãã§ã« æéã§ç· çµããå¥çŽæžã®ã3 å²ä»¥äžããé»åå¥çŽã掻çšããŠãã ãæŒå°æ
åœã®å±æãšããŠä»åŸãå©çšãæ¡å€§ããŠããäºå®ã§ãã ã³ãŒãã¬ãŒããšã³ãžãã¢åéäž ã¡ãã¬ãŒã®ã³ãŒãã¬ãŒãéšéã§ã¯ãæ¬çš¿ã®ããã«ãSaaS ã®å°å
¥ã²ãšã€ãšã£ãŠãæ€èšãå°œãããæ¢åã®ã·ã¹ãã ãšææ©çã«çµåãããããšã§ã培åºçã«åçæ§ã远æ±ããçµç¹åºç€ãã仿ãã¥ããããè¡ã£ãŠããŸãã é¢çœããïŒèå³ãããïŒãšæããæ¹ã¯ããã²åœç€Ÿæ¡çšããŒãžãããå¿åãé¡ãããŸãïŒ æåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã¯ããã« ã¯ãããŸããŠãã³ãŒãã¬ãŒããšã³ãžãã¢ã®å±±äžã§ãã 2020 幎㫠Slack ãæŽ»çšãã ChatOps çšè°ã¯ãŒã¯ãããŒãå
補ã§éçºããã®ã§ãããããã«ã2021 幎 4 æã«ãã® Slack çšè°ãšé»åå¥çŽã·ã¹ãã ã§ãã ã¯ã©ãŠããµã€ã³ ã飿ºãããŠãé»åå¥çŽããã£ãšäŸ¿å©ã«äœ¿ããçç£æ§ã®åäžãå®çŸããŸããã®ã§ã話ãããããŸãã ãŸããåœç€Ÿã®çšè°ã·ã¹ãã 㯠2020 幎 12 æã®åœç€Ÿã®èšäº ã®ããããã«ãªããŸãããçšè°ã®äœæ¥ã Slack äžã§å®çµããã ChatOps ã«ããçšè°ã¯ãŒã¯ãã㌠ãšãªã£ãŠãããŸããæ¬çš¿ã«ã€ããŠã¯ 2021 幎 7 æã«å·çããŠãããŸãã®ã§äžåºŠå°å
¥ãã 1 幎çšçµéãããã®é倧ããªãã©ãã«ãç¡ããä»ãåœç€Ÿã®æ¥µããŠè¿
éãªæææ±ºå®ã®äžå©ã«ãªã£ãŠããŸããChatOps ã«ããçšè°ã¯ãŒã¯ãããŒã«ã€ããŠã¯ãçŽè¿ã2021 幎 6 æã« LayerX 瀟ã LayerX ã¯ãŒã¯ãããŒã®æ°æ©èœãšããŠçºè¡š ãããµãŒãã¹ãšããŠãæäŸããã æ¥çµæ°è ã§ãåãäžããããŠããããšãããä»çŸåšã®ãã©ãã€ã ãšããŠãå
é²çã§æå¹ãªäžææ³ã§ãã£ããšåèªèããŠãããŸãã ä»åãæ°åã³ãããŠã€ã«ã¹æææ¡å€§é²æ¢ã«äŒŽããªã¢ãŒãã¯ãŒã¯ã®å éãšããç¶æ³ããããåœç€Ÿã§ 2021 幎 4 æã«é»åå¥çŽã·ã¹ãã ãšããŠã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããé»åå¥çŽã«éãããå¥çŽæŒå°äœæ¥ã¯çšè°ã®åŸç¶äœæ¥ã«åœããããããã å°å
¥ããŠäœ¿çšããã®ã¿ãªãããã¯ã©ãŠããµã€ã³ã® API ãå©çšããŠçšè°äžã«ããããŒã¿ãé»åå¥çŽã«éä¿¡ãããããšã§ã·ãŒã ã¬ã¹ãªé£æºãå®çŸããŠããŸããæ¬çš¿ã§ã¯åœç€Ÿãè¡ã£ãã·ãŒã ã¬ã¹ãªé£æºææ³ã«ã€ããŠè©³çްãã説æããããŸãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ã® API 飿ºã«ã€ã㊠å®è£
æŠèŠ åŒç€Ÿã®çšè°ã·ã¹ãã ã§ãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ãšã®é£æºã«ã€ããŠã話ãããŸãããŸããæ¬çš¿ã®éçºéšåãšã·ã¹ãã æ§æã¯äžèšã«ãªã£ãŠãããŸãã åŠçå
容ã®è©³çްã¯åŸã»ã©è¿°ã¹ãŸãããæŠèŠãšããŠã¯ TeamSprit(Apex)ããã¯ã©ãŠããµã€ã³ã® API ãã³ãŒã«ããã¯ã©ãŠããµã€ã³äžã§äœæããå¥çŽææžãžçšè°ã«èšèŒãããŠããå¥çŽæžãã¡ã€ã«ãå
æ¹æ
åœè
çã®æ
å ±ã飿ºããä»çµã¿ãšãªã£ãŠãããŸããããã«ããå¥çŽæ
åœè
ã¯ã¯ã©ãŠããµã€ã³ã«ãã°ã€ã³åŸãäžèšã® 3 ã¹ãããã§å
æ¹ã«éä¿¡ã§ããããã«ãªã£ãŠããŸãã èšèŒå
容ã®ç¢ºèª æŒå°ã»çœ²åç®æã®èšå® å
æ¹ãžã®éä¿¡ ã¯ã©ãŠããµã€ã³ã䜿çšããŠå¥çŽææžãäžããäœæããå Žåã®ãŠãŒã¶äœæ¥ãšãåœç€Ÿã§æ¡çšãã API 飿ºè¡ã£ãå Žåã®ãŠãŒã¶äœæ¥ãæ¯èŒãããã®ãäžèšã®è¡šã§ããäœæ¥ãååçšåºŠåæžãããããšãåãããŸãã äœæ¥é
çª äžããäœæããå Žå API 飿ºãå©çšããåœç€Ÿã®å Žå 1 ãã°ã€ã³ ãã°ã€ã³ 2 å¥çŽææžã®äœæ(ä»¶åãå¥çŽææžãšããŠã®å®åèšå®ç) ãªã 3 å¥çŽæžãã¡ã€ã«ã®ã¢ããããŒã ãªã 4 å
æ¹ã®éä¿¡å
èšå® ãªã 5 æŒå°æ¬ã®èšå® æŒå°æ¬ã®èšå® 6 å
æ¹ãžã®éä¿¡ å
æ¹ãžã®éä¿¡ å®è£
ä»åã®éçºã§äœ¿çšãã ã¯ã©ãŠããµã€ã³ API ã¯äžèšã® 5 ã€ã® API ã䜿çšããŸãã (â»ä»¥éãã¯ã©ãŠããµã€ã³ API ã«å£ãã倿°ã衚çŸããå Žå㯠{} ã§æ¬ããŸã)ã API çš®é¡ äœ¿çšçšé post /token ã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸ post /document å¥çŽææžã®äœæ put /documents/{documentID}/attribute å¥çŽææžã®äœæã§èšå®ã§ããªãã现ããé
ç®ã®èšå® post /documents/{documentID}/files ãã¡ã€ã«ã®ã¢ããããŒã post /documents/{documentID}/participants å
æ¹ã®éä¿¡å
èšå® å
šäœåã§èšèŒããã¯ã©ãŠããµã€ã³ã®é£æºéšã«ã€ããŠãäžèšã® API ãç¹ã亀ããŠè©³çްåãããšäžå³ã®ããã«ãªããŸãã å®è£
æ¹æ³ãšããŠã¯ã¯ã©ãŠããµã€ã³ API ã®ãªãã¡ã¬ã³ã¹ãåç
§ãããã¹ãå®è¡æã«åºåããã curl ã³ãã³ããåèã«åæ§ã®ã¬ã¹ãã³ã¹ãåŸãããã« Apex ã§ HTTP ãªã¯ãšã¹ããå®è£
ããŸãããã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸãäŸã«ãšããšäžèšã®ããã«ãªããŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/token' \ -H 'accept: application/json' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id=xxxxxxyyyyyyzzzzzz' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/token' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Content-Type' , 'application/x-www-form-urlencoded' ); req . setBody ( 'client_id=' + 'xxxxxxyyyyyyzzzzzz' ); ç§èªèº«ãApex ãã¯ã©ãŠããµã€ã³ API ããã®æ¡ä»¶ãæ
åœãããŸã§è§Šã£ãããšããããŸããã§ãããããªã¯ãšã¹ãã®è©Šè¡ããå®è£
ãŸã§ 2 é±éããããªãçšåºŠã§å®è£
ããããšãã§ããŸããã ãã ããå®è£
ãéçšã«ããã£ãŠã¯äžèš 2 ç¹ã«ã€ããŠæ³šæãå¿
èŠã«ãªããŸãã Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã 1. Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ãã¡ã€ã«ã®ã¢ããããŒãã«ã€ããŠã¯ä»å䜿çšãã API ã®äžã§ãå¯äžããã¹ãå®è¡ã® curl ãš Apex ã®ãªã¯ãšã¹ãå®è£
ã§å·®åãçãŸããŸãããŸãããã®å·®åã確èªããããã« curl ã³ãã³ãäŸãš Apex ã®ãªã¯ãšã¹ãå®è£
äŸã§ headerãbody ã«ã»ããããŠããå€ãæ¯èŒããŠã¿ãŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/documents/{document_id}/files' \ -H 'accept: application/json' \ -H 'Authorization: AAAAAABBBBBBCCCCCC' \ -H 'Content-Type: multipart/form-data' \ -F 'name=ãã¹ã' \ -F 'uploadfile=@ãã¹ã.pdf;type=application/pdf' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/documents/{document_id}/files' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Authorization' , âAAAAAABBBBBBCCCCCCâ); req . setHeader ( 'Content-Type' , 'multipart/form-data; boundary={boundary}' ); // â»1 req . setBodyAsBlob ({multipartBody}); // â»2 äž»ãªéã㯠â»1 , â»2 ãšã³ã¡ã³ãããéšåã«ãªããŸãã Apex ã§ã¯ HTTP ãªã¯ãšã¹ãã®å€ãæã§æžããŠããããšã«ãªãã®ã§ããã¹ãå®è¡äŸã®ããã« curl ããããªã«åŠçããŠããéšå(-F ãªãã·ã§ã³ã®éšåã Apex ã§èšèŒããŠãã boundary)ãå®è£
ããªããã°ãªããŸããããããåçŽã«å®è£
ã§ããªãçç±ã«ãªããŸãã boundary ã«ã€ããŠã¯ multipart/form-data ãéä¿¡ããéã«å¿
èŠãªå¢çã§ããããŒã§ã©ã®æååãå¢çã§ããããèšå®ããŸãã curl ã®-F ãªãã·ã§ã³ã§å®çŸ©ããŠããæååãšãã¡ã€ã«æå®éšåã¯ãApex ã§ãã¡ã€ã«(ãã€ããª)ãæ±ãããããã® body ã«å«ãŸããæååãå«ã㊠Blob åã§æ±ãå¿
èŠããããŸã( Content-Transfer-Encoding: base64 ã« API æäŸåŽã察å¿ããŠããå Žåã¯äŸå€ã«ãªããŸã)ããã®ãããæååãšãã€ããªããŒã¿ãçµåãäžã€ã® Blob ã«ããæ¹æ³ã¯äžèšã«ãªããŸãã ããã€ããªããŒã¿ãããbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã® 3 ã°ã«ãŒãã«åããã 3 ã°ã«ãŒãããããã Base64 ã§ç¬Šå·åããã 笊å·åããããã€ããªããŒã¿ããšãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååãã«ã€ããŠãBase64 ã®ããŒã¿ããã£ã³ã°ã瀺ãâ=âãå«ãŸããªãããã«æ¹è¡ã³ãŒãã§èª¿æŽããã ãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã®é ã§çµåããã çµåãã Base64 ã®ããŒã¿ã埩å·ããŠãäžã€ã® Blob ãšããã 2. ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã ã¢ã¯ã»ã¹ããŒã¯ã³ããã®æå¹æé㯠token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹ãšããŠã¯ã©ãŠããµã€ã³ããçºè¡ãããŸãã çºè¡ãããã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 3600 } ãã®ã¬ã¹ãã³ã¹ã®å
ãexpires_in ã®å€ãããŒã¯ã³ã®æå¹æéã«ãªããŸããæ²é¡ã®éããæå¹æéã®ç®¡çã¯ã¯ã©ãŠããµã€ã³åŽã§è¡ãããæå¹æéå
ã«å床ããŒã¯ã³ã®ãªã¯ãšã¹ããè¡ã£ãå Žåãçµéããæéã ã expires_in ã®å€ãå°ãããªã£ãçµæãè¿ã£ãŠããŠãaccess_token ãªã©ã¯åãå€ãååŸãããŸããæå¹æéå
ã« token API ãå床å®è¡ããçµæãäžèšã«ãªããŸãã æå¹æéåãåã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 762 } äžæ¹ãæå¹æéåŸã«ããŒã¯ã³ã®ãªã¯ãšã¹ããå®è¡ãããšããããŸã§ãšç°ãªãã¢ã¯ã»ã¹ããŒã¯ã³ãååŸããæ°ããæå¹æéãèšå®ãããŸãã æå¹æéåãåŸã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "XXXXXXYYYYYYZZZZZZ" , "token_type" : "xxxx" , "expires_in" : 3600 } ãã®ãããAPI 飿ºãäžåºŠåããåŸãæå¹æéããããã§ããäžåºŠ API 飿ºãåããŠããŸã£ãå Žåãã¿ã€ãã³ã°ãæªããšå¥çŽææžã®äœæããæçµåŠçã§ããå
æ¹ã®éä¿¡å
èšå®ãŸã§ã®ããã»ã¹å
ã®ã©ãããããããŒã¯ã³ã®æå¹æéåããçºçããå¯èœæ§ãæ³å®ãããŸããå®éã«æéåããçºçããå Žåãçºçæä»¥éã«çºè¡ãããã®åã® API 飿ºåŠçã倱æããŸãã ããŒã¯ã³ã®æå¹æéåããçºçããéãAPI ãªãã¡ã¬ã³ã¹ãã HTTP ã¹ããŒã¿ã¹ã³ãŒãã 401 ãã€ãšã©ãŒå
容ãâunauthorizedâã§å¿çãããããšãããåœç€Ÿã§ã¯ãã®ãšã©ãŒãåããå Žåã«ããŒã¯ã³ãåååŸããŠåŠçããªãã©ã€ããããã«å®è£
ããŸããã æŒå°ææžäœæãäŸã«ãšããšäžèšã®ãããªå®è£
ã€ã¡ãŒãžã«ãªããŸãã //ã¯ã©ãŠããµã€ã³äžã«æŒå°ææžãäœæããäœæããææž ID ãååŸãã public String getDocumentId ( String authToken, String title, String message){ ã»ã»ã»äžç¥ã»ã»ã» HTTPResponse res = http . send (req); if ( res . getStatusCode () == 200 ){ ã»ã»ã»æ£åžžã«çµäºããéã®åŠçã»ã»ã» } //ã¿ã€ãã³ã°ãæªã token ãã¿ã€ã ã¢ãŠãããå ŽåãããŒã¯ã³ãååŸãçŽããŠããªãã©ã€ãã else if ( res . getStatusCode () == 401 ){ //ã¬ã¹ãã³ã¹ã®å
容ã確èªããããããšã©ãŒã¬ã¹ãã³ã¹ã®äžèº«ãååŸãã Map < String , Object > responseBody = new Map < String , Object >(); responseBody = ( Map <String, Object>) JSON . deserializeUntyped ( res . getBody ()); String errorVal = (String) responseBody . get ( 'error' ); //ãªãã¡ã¬ã³ã¹äžãã¢ã¯ã»ã¹ããŒã¯ã³ãç¡å¹(æå¹æéåã)ã®å Žåã'unauthorizedâãšãªã if ( errorVal . equals ( 'unauthorized' )){ //ã¯ã©ãŠããµã€ã³ã®ã¢ã¯ã»ã¹ããŒã¯ã³ã®åååŸ authToken = getAuthToken (); //åçŽååž°ã§åå®è¡ããã documentId = getDocumentId (authToken, title, message); } ã»ã»ã»äžç¥ã»ã»ã» } ã»ã»ã»ä»¥äžçç¥ã»ã»ã» } å®è£
ãçµã㊠äžèšãå®è£
ããçµæãçšè°ãšå
¥åå
容ãåãããŸãã¯ãçšè°ããçæã§ããå
容ã¯å
šãŠã·ã¹ãã 飿ºã§èªåçæãããããæŒå°æ
åœã¯çšè°ãšã¯ã©ãŠããµã€ã³ã®ç»é¢ã䞊ã¹ãŠè»¢èšãããããªç
©éãªäœæ¥ãå¿
èŠãšããªãç°å¢ã«ãªããŸããããŸããå¥çŽæžã®è£œæ¬ãéµéçã®çŽåªäœã§ãããæ
ã®äºåã®åæžãã§ããããã«ãªãçã®ãé»åå¥çŽãå°å
¥ããããšã®ããããã®ã¡ãªããã䜵ããŠäº«åããŠããŸãã åœç€Ÿã§ã¯ 2021 幎 4 æåŸåããã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããã2021 幎 6 ææç¹ã§ã¯ãã§ã« æéã§ç· çµããå¥çŽæžã®ã3 å²ä»¥äžããé»åå¥çŽã掻çšããŠãã ãæŒå°æ
åœã®å±æãšããŠä»åŸãå©çšãæ¡å€§ããŠããäºå®ã§ãã ã³ãŒãã¬ãŒããšã³ãžãã¢åéäž ã¡ãã¬ãŒã®ã³ãŒãã¬ãŒãéšéã§ã¯ãæ¬çš¿ã®ããã«ãSaaS ã®å°å
¥ã²ãšã€ãšã£ãŠãæ€èšãå°œãããæ¢åã®ã·ã¹ãã ãšææ©çã«çµåãããããšã§ã培åºçã«åçæ§ã远æ±ããçµç¹åºç€ãã仿ãã¥ããããè¡ã£ãŠããŸãã é¢çœããïŒèå³ãããïŒãšæããæ¹ã¯ããã²åœç€Ÿæ¡çšããŒãžãããå¿åãé¡ãããŸãïŒ æåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã¯ããã« ã¯ãããŸããŠãã³ãŒãã¬ãŒããšã³ãžãã¢ã®å±±äžã§ãã 2020 幎㫠Slack ãæŽ»çšãã ChatOps çšè°ã¯ãŒã¯ãããŒãå
補ã§éçºããã®ã§ãããããã«ã2021 幎 4 æã«ãã® Slack çšè°ãšé»åå¥çŽã·ã¹ãã ã§ãã ã¯ã©ãŠããµã€ã³ ã飿ºãããŠãé»åå¥çŽããã£ãšäŸ¿å©ã«äœ¿ããçç£æ§ã®åäžãå®çŸããŸããã®ã§ã話ãããããŸãã ãŸããåœç€Ÿã®çšè°ã·ã¹ãã 㯠2020 幎 12 æã®åœç€Ÿã®èšäº ã®ããããã«ãªããŸãããçšè°ã®äœæ¥ã Slack äžã§å®çµããã ChatOps ã«ããçšè°ã¯ãŒã¯ãã㌠ãšãªã£ãŠãããŸããæ¬çš¿ã«ã€ããŠã¯ 2021 幎 7 æã«å·çããŠãããŸãã®ã§äžåºŠå°å
¥ãã 1 幎çšçµéãããã®é倧ããªãã©ãã«ãç¡ããä»ãåœç€Ÿã®æ¥µããŠè¿
éãªæææ±ºå®ã®äžå©ã«ãªã£ãŠããŸããChatOps ã«ããçšè°ã¯ãŒã¯ãããŒã«ã€ããŠã¯ãçŽè¿ã2021 幎 6 æã« LayerX 瀟ã LayerX ã¯ãŒã¯ãããŒã®æ°æ©èœãšããŠçºè¡š ãããµãŒãã¹ãšããŠãæäŸããã æ¥çµæ°è ã§ãåãäžããããŠããããšãããä»çŸåšã®ãã©ãã€ã ãšããŠãå
é²çã§æå¹ãªäžææ³ã§ãã£ããšåèªèããŠãããŸãã ä»åãæ°åã³ãããŠã€ã«ã¹æææ¡å€§é²æ¢ã«äŒŽããªã¢ãŒãã¯ãŒã¯ã®å éãšããç¶æ³ããããåœç€Ÿã§ 2021 幎 4 æã«é»åå¥çŽã·ã¹ãã ãšããŠã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããé»åå¥çŽã«éãããå¥çŽæŒå°äœæ¥ã¯çšè°ã®åŸç¶äœæ¥ã«åœããããããã å°å
¥ããŠäœ¿çšããã®ã¿ãªãããã¯ã©ãŠããµã€ã³ã® API ãå©çšããŠçšè°äžã«ããããŒã¿ãé»åå¥çŽã«éä¿¡ãããããšã§ã·ãŒã ã¬ã¹ãªé£æºãå®çŸããŠããŸããæ¬çš¿ã§ã¯åœç€Ÿãè¡ã£ãã·ãŒã ã¬ã¹ãªé£æºææ³ã«ã€ããŠè©³çްãã説æããããŸãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ã® API 飿ºã«ã€ã㊠å®è£
æŠèŠ åŒç€Ÿã®çšè°ã·ã¹ãã ã§ãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ãšã®é£æºã«ã€ããŠã話ãããŸãããŸããæ¬çš¿ã®éçºéšåãšã·ã¹ãã æ§æã¯äžèšã«ãªã£ãŠãããŸãã åŠçå
容ã®è©³çްã¯åŸã»ã©è¿°ã¹ãŸãããæŠèŠãšããŠã¯ TeamSprit(Apex)ããã¯ã©ãŠããµã€ã³ã® API ãã³ãŒã«ããã¯ã©ãŠããµã€ã³äžã§äœæããå¥çŽææžãžçšè°ã«èšèŒãããŠããå¥çŽæžãã¡ã€ã«ãå
æ¹æ
åœè
çã®æ
å ±ã飿ºããä»çµã¿ãšãªã£ãŠãããŸããããã«ããå¥çŽæ
åœè
ã¯ã¯ã©ãŠããµã€ã³ã«ãã°ã€ã³åŸãäžèšã® 3 ã¹ãããã§å
æ¹ã«éä¿¡ã§ããããã«ãªã£ãŠããŸãã èšèŒå
容ã®ç¢ºèª æŒå°ã»çœ²åç®æã®èšå® å
æ¹ãžã®éä¿¡ ã¯ã©ãŠããµã€ã³ã䜿çšããŠå¥çŽææžãäžããäœæããå Žåã®ãŠãŒã¶äœæ¥ãšãåœç€Ÿã§æ¡çšãã API 飿ºè¡ã£ãå Žåã®ãŠãŒã¶äœæ¥ãæ¯èŒãããã®ãäžèšã®è¡šã§ããäœæ¥ãååçšåºŠåæžãããããšãåãããŸãã äœæ¥é
çª äžããäœæããå Žå API 飿ºãå©çšããåœç€Ÿã®å Žå 1 ãã°ã€ã³ ãã°ã€ã³ 2 å¥çŽææžã®äœæ(ä»¶åãå¥çŽææžãšããŠã®å®åèšå®ç) ãªã 3 å¥çŽæžãã¡ã€ã«ã®ã¢ããããŒã ãªã 4 å
æ¹ã®éä¿¡å
èšå® ãªã 5 æŒå°æ¬ã®èšå® æŒå°æ¬ã®èšå® 6 å
æ¹ãžã®éä¿¡ å
æ¹ãžã®éä¿¡ å®è£
ä»åã®éçºã§äœ¿çšãã ã¯ã©ãŠããµã€ã³ API ã¯äžèšã® 5 ã€ã® API ã䜿çšããŸãã (â»ä»¥éãã¯ã©ãŠããµã€ã³ API ã«å£ãã倿°ã衚çŸããå Žå㯠{} ã§æ¬ããŸã)ã API çš®é¡ äœ¿çšçšé post /token ã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸ post /document å¥çŽææžã®äœæ put /documents/{documentID}/attribute å¥çŽææžã®äœæã§èšå®ã§ããªãã现ããé
ç®ã®èšå® post /documents/{documentID}/files ãã¡ã€ã«ã®ã¢ããããŒã post /documents/{documentID}/participants å
æ¹ã®éä¿¡å
èšå® å
šäœåã§èšèŒããã¯ã©ãŠããµã€ã³ã®é£æºéšã«ã€ããŠãäžèšã® API ãç¹ã亀ããŠè©³çްåãããšäžå³ã®ããã«ãªããŸãã å®è£
æ¹æ³ãšããŠã¯ã¯ã©ãŠããµã€ã³ API ã®ãªãã¡ã¬ã³ã¹ãåç
§ãããã¹ãå®è¡æã«åºåããã curl ã³ãã³ããåèã«åæ§ã®ã¬ã¹ãã³ã¹ãåŸãããã« Apex ã§ HTTP ãªã¯ãšã¹ããå®è£
ããŸãããã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸãäŸã«ãšããšäžèšã®ããã«ãªããŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/token' \ -H 'accept: application/json' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id=xxxxxxyyyyyyzzzzzz' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/token' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Content-Type' , 'application/x-www-form-urlencoded' ); req . setBody ( 'client_id=' + 'xxxxxxyyyyyyzzzzzz' ); ç§èªèº«ãApex ãã¯ã©ãŠããµã€ã³ API ããã®æ¡ä»¶ãæ
åœãããŸã§è§Šã£ãããšããããŸããã§ãããããªã¯ãšã¹ãã®è©Šè¡ããå®è£
ãŸã§ 2 é±éããããªãçšåºŠã§å®è£
ããããšãã§ããŸããã ãã ããå®è£
ãéçšã«ããã£ãŠã¯äžèš 2 ç¹ã«ã€ããŠæ³šæãå¿
èŠã«ãªããŸãã Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã 1. Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ãã¡ã€ã«ã®ã¢ããããŒãã«ã€ããŠã¯ä»å䜿çšãã API ã®äžã§ãå¯äžããã¹ãå®è¡ã® curl ãš Apex ã®ãªã¯ãšã¹ãå®è£
ã§å·®åãçãŸããŸãããŸãããã®å·®åã確èªããããã« curl ã³ãã³ãäŸãš Apex ã®ãªã¯ãšã¹ãå®è£
äŸã§ headerãbody ã«ã»ããããŠããå€ãæ¯èŒããŠã¿ãŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/documents/{document_id}/files' \ -H 'accept: application/json' \ -H 'Authorization: AAAAAABBBBBBCCCCCC' \ -H 'Content-Type: multipart/form-data' \ -F 'name=ãã¹ã' \ -F 'uploadfile=@ãã¹ã.pdf;type=application/pdf' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/documents/{document_id}/files' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Authorization' , âAAAAAABBBBBBCCCCCCâ); req . setHeader ( 'Content-Type' , 'multipart/form-data; boundary={boundary}' ); // â»1 req . setBodyAsBlob ({multipartBody}); // â»2 äž»ãªéã㯠â»1 , â»2 ãšã³ã¡ã³ãããéšåã«ãªããŸãã Apex ã§ã¯ HTTP ãªã¯ãšã¹ãã®å€ãæã§æžããŠããããšã«ãªãã®ã§ããã¹ãå®è¡äŸã®ããã« curl ããããªã«åŠçããŠããéšå(-F ãªãã·ã§ã³ã®éšåã Apex ã§èšèŒããŠãã boundary)ãå®è£
ããªããã°ãªããŸããããããåçŽã«å®è£
ã§ããªãçç±ã«ãªããŸãã boundary ã«ã€ããŠã¯ multipart/form-data ãéä¿¡ããéã«å¿
èŠãªå¢çã§ããããŒã§ã©ã®æååãå¢çã§ããããèšå®ããŸãã curl ã®-F ãªãã·ã§ã³ã§å®çŸ©ããŠããæååãšãã¡ã€ã«æå®éšåã¯ãApex ã§ãã¡ã€ã«(ãã€ããª)ãæ±ãããããã® body ã«å«ãŸããæååãå«ã㊠Blob åã§æ±ãå¿
èŠããããŸã( Content-Transfer-Encoding: base64 ã« API æäŸåŽã察å¿ããŠããå Žåã¯äŸå€ã«ãªããŸã)ããã®ãããæååãšãã€ããªããŒã¿ãçµåãäžã€ã® Blob ã«ããæ¹æ³ã¯äžèšã«ãªããŸãã ããã€ããªããŒã¿ãããbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã® 3 ã°ã«ãŒãã«åããã 3 ã°ã«ãŒãããããã Base64 ã§ç¬Šå·åããã 笊å·åããããã€ããªããŒã¿ããšãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååãã«ã€ããŠãBase64 ã®ããŒã¿ããã£ã³ã°ã瀺ãâ=âãå«ãŸããªãããã«æ¹è¡ã³ãŒãã§èª¿æŽããã ãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã®é ã§çµåããã çµåãã Base64 ã®ããŒã¿ã埩å·ããŠãäžã€ã® Blob ãšããã 2. ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã ã¢ã¯ã»ã¹ããŒã¯ã³ããã®æå¹æé㯠token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹ãšããŠã¯ã©ãŠããµã€ã³ããçºè¡ãããŸãã çºè¡ãããã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 3600 } ãã®ã¬ã¹ãã³ã¹ã®å
ãexpires_in ã®å€ãããŒã¯ã³ã®æå¹æéã«ãªããŸããæ²é¡ã®éããæå¹æéã®ç®¡çã¯ã¯ã©ãŠããµã€ã³åŽã§è¡ãããæå¹æéå
ã«å床ããŒã¯ã³ã®ãªã¯ãšã¹ããè¡ã£ãå Žåãçµéããæéã ã expires_in ã®å€ãå°ãããªã£ãçµæãè¿ã£ãŠããŠãaccess_token ãªã©ã¯åãå€ãååŸãããŸããæå¹æéå
ã« token API ãå床å®è¡ããçµæãäžèšã«ãªããŸãã æå¹æéåãåã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 762 } äžæ¹ãæå¹æéåŸã«ããŒã¯ã³ã®ãªã¯ãšã¹ããå®è¡ãããšããããŸã§ãšç°ãªãã¢ã¯ã»ã¹ããŒã¯ã³ãååŸããæ°ããæå¹æéãèšå®ãããŸãã æå¹æéåãåŸã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "XXXXXXYYYYYYZZZZZZ" , "token_type" : "xxxx" , "expires_in" : 3600 } ãã®ãããAPI 飿ºãäžåºŠåããåŸãæå¹æéããããã§ããäžåºŠ API 飿ºãåããŠããŸã£ãå Žåãã¿ã€ãã³ã°ãæªããšå¥çŽææžã®äœæããæçµåŠçã§ããå
æ¹ã®éä¿¡å
èšå®ãŸã§ã®ããã»ã¹å
ã®ã©ãããããããŒã¯ã³ã®æå¹æéåããçºçããå¯èœæ§ãæ³å®ãããŸããå®éã«æéåããçºçããå Žåãçºçæä»¥éã«çºè¡ãããã®åã® API 飿ºåŠçã倱æããŸãã ããŒã¯ã³ã®æå¹æéåããçºçããéãAPI ãªãã¡ã¬ã³ã¹ãã HTTP ã¹ããŒã¿ã¹ã³ãŒãã 401 ãã€ãšã©ãŒå
容ãâunauthorizedâã§å¿çãããããšãããåœç€Ÿã§ã¯ãã®ãšã©ãŒãåããå Žåã«ããŒã¯ã³ãåååŸããŠåŠçããªãã©ã€ããããã«å®è£
ããŸããã æŒå°ææžäœæãäŸã«ãšããšäžèšã®ãããªå®è£
ã€ã¡ãŒãžã«ãªããŸãã //ã¯ã©ãŠããµã€ã³äžã«æŒå°ææžãäœæããäœæããææž ID ãååŸãã public String getDocumentId ( String authToken, String title, String message){ ã»ã»ã»äžç¥ã»ã»ã» HTTPResponse res = http . send (req); if ( res . getStatusCode () == 200 ){ ã»ã»ã»æ£åžžã«çµäºããéã®åŠçã»ã»ã» } //ã¿ã€ãã³ã°ãæªã token ãã¿ã€ã ã¢ãŠãããå ŽåãããŒã¯ã³ãååŸãçŽããŠããªãã©ã€ãã else if ( res . getStatusCode () == 401 ){ //ã¬ã¹ãã³ã¹ã®å
容ã確èªããããããšã©ãŒã¬ã¹ãã³ã¹ã®äžèº«ãååŸãã Map < String , Object > responseBody = new Map < String , Object >(); responseBody = ( Map <String, Object>) JSON . deserializeUntyped ( res . getBody ()); String errorVal = (String) responseBody . get ( 'error' ); //ãªãã¡ã¬ã³ã¹äžãã¢ã¯ã»ã¹ããŒã¯ã³ãç¡å¹(æå¹æéåã)ã®å Žåã'unauthorizedâãšãªã if ( errorVal . equals ( 'unauthorized' )){ //ã¯ã©ãŠããµã€ã³ã®ã¢ã¯ã»ã¹ããŒã¯ã³ã®åååŸ authToken = getAuthToken (); //åçŽååž°ã§åå®è¡ããã documentId = getDocumentId (authToken, title, message); } ã»ã»ã»äžç¥ã»ã»ã» } ã»ã»ã»ä»¥äžçç¥ã»ã»ã» } å®è£
ãçµã㊠äžèšãå®è£
ããçµæãçšè°ãšå
¥åå
容ãåãããŸãã¯ãçšè°ããçæã§ããå
容ã¯å
šãŠã·ã¹ãã 飿ºã§èªåçæãããããæŒå°æ
åœã¯çšè°ãšã¯ã©ãŠããµã€ã³ã®ç»é¢ã䞊ã¹ãŠè»¢èšãããããªç
©éãªäœæ¥ãå¿
èŠãšããªãç°å¢ã«ãªããŸããããŸããå¥çŽæžã®è£œæ¬ãéµéçã®çŽåªäœã§ãããæ
ã®äºåã®åæžãã§ããããã«ãªãçã®ãé»åå¥çŽãå°å
¥ããããšã®ããããã®ã¡ãªããã䜵ããŠäº«åããŠããŸãã åœç€Ÿã§ã¯ 2021 幎 4 æåŸåããã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããã2021 幎 6 ææç¹ã§ã¯ãã§ã« æéã§ç· çµããå¥çŽæžã®ã3 å²ä»¥äžããé»åå¥çŽã掻çšããŠãã ãæŒå°æ
åœã®å±æãšããŠä»åŸãå©çšãæ¡å€§ããŠããäºå®ã§ãã ã³ãŒãã¬ãŒããšã³ãžãã¢åéäž ã¡ãã¬ãŒã®ã³ãŒãã¬ãŒãéšéã§ã¯ãæ¬çš¿ã®ããã«ãSaaS ã®å°å
¥ã²ãšã€ãšã£ãŠãæ€èšãå°œãããæ¢åã®ã·ã¹ãã ãšææ©çã«çµåãããããšã§ã培åºçã«åçæ§ã远æ±ããçµç¹åºç€ãã仿ãã¥ããããè¡ã£ãŠããŸãã é¢çœããïŒèå³ãããïŒãšæããæ¹ã¯ããã²åœç€Ÿæ¡çšããŒãžãããå¿åãé¡ãããŸãïŒ æåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã¯ããã« ã¯ãããŸããŠãã³ãŒãã¬ãŒããšã³ãžãã¢ã®å±±äžã§ãã 2020 幎㫠Slack ãæŽ»çšãã ChatOps çšè°ã¯ãŒã¯ãããŒãå
補ã§éçºããã®ã§ãããããã«ã2021 幎 4 æã«ãã® Slack çšè°ãšé»åå¥çŽã·ã¹ãã ã§ãã ã¯ã©ãŠããµã€ã³ ã飿ºãããŠãé»åå¥çŽããã£ãšäŸ¿å©ã«äœ¿ããçç£æ§ã®åäžãå®çŸããŸããã®ã§ã話ãããããŸãã ãŸããåœç€Ÿã®çšè°ã·ã¹ãã 㯠2020 幎 12 æã®åœç€Ÿã®èšäº ã®ããããã«ãªããŸãããçšè°ã®äœæ¥ã Slack äžã§å®çµããã ChatOps ã«ããçšè°ã¯ãŒã¯ãã㌠ãšãªã£ãŠãããŸããæ¬çš¿ã«ã€ããŠã¯ 2021 幎 7 æã«å·çããŠãããŸãã®ã§äžåºŠå°å
¥ãã 1 幎çšçµéãããã®é倧ããªãã©ãã«ãç¡ããä»ãåœç€Ÿã®æ¥µããŠè¿
éãªæææ±ºå®ã®äžå©ã«ãªã£ãŠããŸããChatOps ã«ããçšè°ã¯ãŒã¯ãããŒã«ã€ããŠã¯ãçŽè¿ã2021 幎 6 æã« LayerX 瀟ã LayerX ã¯ãŒã¯ãããŒã®æ°æ©èœãšããŠçºè¡š ãããµãŒãã¹ãšããŠãæäŸããã æ¥çµæ°è ã§ãåãäžããããŠããããšãããä»çŸåšã®ãã©ãã€ã ãšããŠãå
é²çã§æå¹ãªäžææ³ã§ãã£ããšåèªèããŠãããŸãã ä»åãæ°åã³ãããŠã€ã«ã¹æææ¡å€§é²æ¢ã«äŒŽããªã¢ãŒãã¯ãŒã¯ã®å éãšããç¶æ³ããããåœç€Ÿã§ 2021 幎 4 æã«é»åå¥çŽã·ã¹ãã ãšããŠã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããé»åå¥çŽã«éãããå¥çŽæŒå°äœæ¥ã¯çšè°ã®åŸç¶äœæ¥ã«åœããããããã å°å
¥ããŠäœ¿çšããã®ã¿ãªãããã¯ã©ãŠããµã€ã³ã® API ãå©çšããŠçšè°äžã«ããããŒã¿ãé»åå¥çŽã«éä¿¡ãããããšã§ã·ãŒã ã¬ã¹ãªé£æºãå®çŸããŠããŸããæ¬çš¿ã§ã¯åœç€Ÿãè¡ã£ãã·ãŒã ã¬ã¹ãªé£æºææ³ã«ã€ããŠè©³çްãã説æããããŸãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ã® API 飿ºã«ã€ã㊠å®è£
æŠèŠ åŒç€Ÿã®çšè°ã·ã¹ãã ã§ãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ãšã®é£æºã«ã€ããŠã話ãããŸãããŸããæ¬çš¿ã®éçºéšåãšã·ã¹ãã æ§æã¯äžèšã«ãªã£ãŠãããŸãã åŠçå
容ã®è©³çްã¯åŸã»ã©è¿°ã¹ãŸãããæŠèŠãšããŠã¯ TeamSprit(Apex)ããã¯ã©ãŠããµã€ã³ã® API ãã³ãŒã«ããã¯ã©ãŠããµã€ã³äžã§äœæããå¥çŽææžãžçšè°ã«èšèŒãããŠããå¥çŽæžãã¡ã€ã«ãå
æ¹æ
åœè
çã®æ
å ±ã飿ºããä»çµã¿ãšãªã£ãŠãããŸããããã«ããå¥çŽæ
åœè
ã¯ã¯ã©ãŠããµã€ã³ã«ãã°ã€ã³åŸãäžèšã® 3 ã¹ãããã§å
æ¹ã«éä¿¡ã§ããããã«ãªã£ãŠããŸãã èšèŒå
容ã®ç¢ºèª æŒå°ã»çœ²åç®æã®èšå® å
æ¹ãžã®éä¿¡ ã¯ã©ãŠããµã€ã³ã䜿çšããŠå¥çŽææžãäžããäœæããå Žåã®ãŠãŒã¶äœæ¥ãšãåœç€Ÿã§æ¡çšãã API 飿ºè¡ã£ãå Žåã®ãŠãŒã¶äœæ¥ãæ¯èŒãããã®ãäžèšã®è¡šã§ããäœæ¥ãååçšåºŠåæžãããããšãåãããŸãã äœæ¥é
çª äžããäœæããå Žå API 飿ºãå©çšããåœç€Ÿã®å Žå 1 ãã°ã€ã³ ãã°ã€ã³ 2 å¥çŽææžã®äœæ(ä»¶åãå¥çŽææžãšããŠã®å®åèšå®ç) ãªã 3 å¥çŽæžãã¡ã€ã«ã®ã¢ããããŒã ãªã 4 å
æ¹ã®éä¿¡å
èšå® ãªã 5 æŒå°æ¬ã®èšå® æŒå°æ¬ã®èšå® 6 å
æ¹ãžã®éä¿¡ å
æ¹ãžã®éä¿¡ å®è£
ä»åã®éçºã§äœ¿çšãã ã¯ã©ãŠããµã€ã³ API ã¯äžèšã® 5 ã€ã® API ã䜿çšããŸãã (â»ä»¥éãã¯ã©ãŠããµã€ã³ API ã«å£ãã倿°ã衚çŸããå Žå㯠{} ã§æ¬ããŸã)ã API çš®é¡ äœ¿çšçšé post /token ã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸ post /document å¥çŽææžã®äœæ put /documents/{documentID}/attribute å¥çŽææžã®äœæã§èšå®ã§ããªãã现ããé
ç®ã®èšå® post /documents/{documentID}/files ãã¡ã€ã«ã®ã¢ããããŒã post /documents/{documentID}/participants å
æ¹ã®éä¿¡å
èšå® å
šäœåã§èšèŒããã¯ã©ãŠããµã€ã³ã®é£æºéšã«ã€ããŠãäžèšã® API ãç¹ã亀ããŠè©³çްåãããšäžå³ã®ããã«ãªããŸãã å®è£
æ¹æ³ãšããŠã¯ã¯ã©ãŠããµã€ã³ API ã®ãªãã¡ã¬ã³ã¹ãåç
§ãããã¹ãå®è¡æã«åºåããã curl ã³ãã³ããåèã«åæ§ã®ã¬ã¹ãã³ã¹ãåŸãããã« Apex ã§ HTTP ãªã¯ãšã¹ããå®è£
ããŸãããã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸãäŸã«ãšããšäžèšã®ããã«ãªããŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/token' \ -H 'accept: application/json' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id=xxxxxxyyyyyyzzzzzz' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/token' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Content-Type' , 'application/x-www-form-urlencoded' ); req . setBody ( 'client_id=' + 'xxxxxxyyyyyyzzzzzz' ); ç§èªèº«ãApex ãã¯ã©ãŠããµã€ã³ API ããã®æ¡ä»¶ãæ
åœãããŸã§è§Šã£ãããšããããŸããã§ãããããªã¯ãšã¹ãã®è©Šè¡ããå®è£
ãŸã§ 2 é±éããããªãçšåºŠã§å®è£
ããããšãã§ããŸããã ãã ããå®è£
ãéçšã«ããã£ãŠã¯äžèš 2 ç¹ã«ã€ããŠæ³šæãå¿
èŠã«ãªããŸãã Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã 1. Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ãã¡ã€ã«ã®ã¢ããããŒãã«ã€ããŠã¯ä»å䜿çšãã API ã®äžã§ãå¯äžããã¹ãå®è¡ã® curl ãš Apex ã®ãªã¯ãšã¹ãå®è£
ã§å·®åãçãŸããŸãããŸãããã®å·®åã確èªããããã« curl ã³ãã³ãäŸãš Apex ã®ãªã¯ãšã¹ãå®è£
äŸã§ headerãbody ã«ã»ããããŠããå€ãæ¯èŒããŠã¿ãŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/documents/{document_id}/files' \ -H 'accept: application/json' \ -H 'Authorization: AAAAAABBBBBBCCCCCC' \ -H 'Content-Type: multipart/form-data' \ -F 'name=ãã¹ã' \ -F 'uploadfile=@ãã¹ã.pdf;type=application/pdf' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/documents/{document_id}/files' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Authorization' , âAAAAAABBBBBBCCCCCCâ); req . setHeader ( 'Content-Type' , 'multipart/form-data; boundary={boundary}' ); // â»1 req . setBodyAsBlob ({multipartBody}); // â»2 äž»ãªéã㯠â»1 , â»2 ãšã³ã¡ã³ãããéšåã«ãªããŸãã Apex ã§ã¯ HTTP ãªã¯ãšã¹ãã®å€ãæã§æžããŠããããšã«ãªãã®ã§ããã¹ãå®è¡äŸã®ããã« curl ããããªã«åŠçããŠããéšå(-F ãªãã·ã§ã³ã®éšåã Apex ã§èšèŒããŠãã boundary)ãå®è£
ããªããã°ãªããŸããããããåçŽã«å®è£
ã§ããªãçç±ã«ãªããŸãã boundary ã«ã€ããŠã¯ multipart/form-data ãéä¿¡ããéã«å¿
èŠãªå¢çã§ããããŒã§ã©ã®æååãå¢çã§ããããèšå®ããŸãã curl ã®-F ãªãã·ã§ã³ã§å®çŸ©ããŠããæååãšãã¡ã€ã«æå®éšåã¯ãApex ã§ãã¡ã€ã«(ãã€ããª)ãæ±ãããããã® body ã«å«ãŸããæååãå«ã㊠Blob åã§æ±ãå¿
èŠããããŸã( Content-Transfer-Encoding: base64 ã« API æäŸåŽã察å¿ããŠããå Žåã¯äŸå€ã«ãªããŸã)ããã®ãããæååãšãã€ããªããŒã¿ãçµåãäžã€ã® Blob ã«ããæ¹æ³ã¯äžèšã«ãªããŸãã ããã€ããªããŒã¿ãããbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã® 3 ã°ã«ãŒãã«åããã 3 ã°ã«ãŒãããããã Base64 ã§ç¬Šå·åããã 笊å·åããããã€ããªããŒã¿ããšãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååãã«ã€ããŠãBase64 ã®ããŒã¿ããã£ã³ã°ã瀺ãâ=âãå«ãŸããªãããã«æ¹è¡ã³ãŒãã§èª¿æŽããã ãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã®é ã§çµåããã çµåãã Base64 ã®ããŒã¿ã埩å·ããŠãäžã€ã® Blob ãšããã 2. ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã ã¢ã¯ã»ã¹ããŒã¯ã³ããã®æå¹æé㯠token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹ãšããŠã¯ã©ãŠããµã€ã³ããçºè¡ãããŸãã çºè¡ãããã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 3600 } ãã®ã¬ã¹ãã³ã¹ã®å
ãexpires_in ã®å€ãããŒã¯ã³ã®æå¹æéã«ãªããŸããæ²é¡ã®éããæå¹æéã®ç®¡çã¯ã¯ã©ãŠããµã€ã³åŽã§è¡ãããæå¹æéå
ã«å床ããŒã¯ã³ã®ãªã¯ãšã¹ããè¡ã£ãå Žåãçµéããæéã ã expires_in ã®å€ãå°ãããªã£ãçµæãè¿ã£ãŠããŠãaccess_token ãªã©ã¯åãå€ãååŸãããŸããæå¹æéå
ã« token API ãå床å®è¡ããçµæãäžèšã«ãªããŸãã æå¹æéåãåã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 762 } äžæ¹ãæå¹æéåŸã«ããŒã¯ã³ã®ãªã¯ãšã¹ããå®è¡ãããšããããŸã§ãšç°ãªãã¢ã¯ã»ã¹ããŒã¯ã³ãååŸããæ°ããæå¹æéãèšå®ãããŸãã æå¹æéåãåŸã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "XXXXXXYYYYYYZZZZZZ" , "token_type" : "xxxx" , "expires_in" : 3600 } ãã®ãããAPI 飿ºãäžåºŠåããåŸãæå¹æéããããã§ããäžåºŠ API 飿ºãåããŠããŸã£ãå Žåãã¿ã€ãã³ã°ãæªããšå¥çŽææžã®äœæããæçµåŠçã§ããå
æ¹ã®éä¿¡å
èšå®ãŸã§ã®ããã»ã¹å
ã®ã©ãããããããŒã¯ã³ã®æå¹æéåããçºçããå¯èœæ§ãæ³å®ãããŸããå®éã«æéåããçºçããå Žåãçºçæä»¥éã«çºè¡ãããã®åã® API 飿ºåŠçã倱æããŸãã ããŒã¯ã³ã®æå¹æéåããçºçããéãAPI ãªãã¡ã¬ã³ã¹ãã HTTP ã¹ããŒã¿ã¹ã³ãŒãã 401 ãã€ãšã©ãŒå
容ãâunauthorizedâã§å¿çãããããšãããåœç€Ÿã§ã¯ãã®ãšã©ãŒãåããå Žåã«ããŒã¯ã³ãåååŸããŠåŠçããªãã©ã€ããããã«å®è£
ããŸããã æŒå°ææžäœæãäŸã«ãšããšäžèšã®ãããªå®è£
ã€ã¡ãŒãžã«ãªããŸãã //ã¯ã©ãŠããµã€ã³äžã«æŒå°ææžãäœæããäœæããææž ID ãååŸãã public String getDocumentId ( String authToken, String title, String message){ ã»ã»ã»äžç¥ã»ã»ã» HTTPResponse res = http . send (req); if ( res . getStatusCode () == 200 ){ ã»ã»ã»æ£åžžã«çµäºããéã®åŠçã»ã»ã» } //ã¿ã€ãã³ã°ãæªã token ãã¿ã€ã ã¢ãŠãããå ŽåãããŒã¯ã³ãååŸãçŽããŠããªãã©ã€ãã else if ( res . getStatusCode () == 401 ){ //ã¬ã¹ãã³ã¹ã®å
容ã確èªããããããšã©ãŒã¬ã¹ãã³ã¹ã®äžèº«ãååŸãã Map < String , Object > responseBody = new Map < String , Object >(); responseBody = ( Map <String, Object>) JSON . deserializeUntyped ( res . getBody ()); String errorVal = (String) responseBody . get ( 'error' ); //ãªãã¡ã¬ã³ã¹äžãã¢ã¯ã»ã¹ããŒã¯ã³ãç¡å¹(æå¹æéåã)ã®å Žåã'unauthorizedâãšãªã if ( errorVal . equals ( 'unauthorized' )){ //ã¯ã©ãŠããµã€ã³ã®ã¢ã¯ã»ã¹ããŒã¯ã³ã®åååŸ authToken = getAuthToken (); //åçŽååž°ã§åå®è¡ããã documentId = getDocumentId (authToken, title, message); } ã»ã»ã»äžç¥ã»ã»ã» } ã»ã»ã»ä»¥äžçç¥ã»ã»ã» } å®è£
ãçµã㊠äžèšãå®è£
ããçµæãçšè°ãšå
¥åå
容ãåãããŸãã¯ãçšè°ããçæã§ããå
容ã¯å
šãŠã·ã¹ãã 飿ºã§èªåçæãããããæŒå°æ
åœã¯çšè°ãšã¯ã©ãŠããµã€ã³ã®ç»é¢ã䞊ã¹ãŠè»¢èšãããããªç
©éãªäœæ¥ãå¿
èŠãšããªãç°å¢ã«ãªããŸããããŸããå¥çŽæžã®è£œæ¬ãéµéçã®çŽåªäœã§ãããæ
ã®äºåã®åæžãã§ããããã«ãªãçã®ãé»åå¥çŽãå°å
¥ããããšã®ããããã®ã¡ãªããã䜵ããŠäº«åããŠããŸãã åœç€Ÿã§ã¯ 2021 幎 4 æåŸåããã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããã2021 幎 6 ææç¹ã§ã¯ãã§ã« æéã§ç· çµããå¥çŽæžã®ã3 å²ä»¥äžããé»åå¥çŽã掻çšããŠãã ãæŒå°æ
åœã®å±æãšããŠä»åŸãå©çšãæ¡å€§ããŠããäºå®ã§ãã ã³ãŒãã¬ãŒããšã³ãžãã¢åéäž ã¡ãã¬ãŒã®ã³ãŒãã¬ãŒãéšéã§ã¯ãæ¬çš¿ã®ããã«ãSaaS ã®å°å
¥ã²ãšã€ãšã£ãŠãæ€èšãå°œãããæ¢åã®ã·ã¹ãã ãšææ©çã«çµåãããããšã§ã培åºçã«åçæ§ã远æ±ããçµç¹åºç€ãã仿ãã¥ããããè¡ã£ãŠããŸãã é¢çœããïŒèå³ãããïŒãšæããæ¹ã¯ããã²åœç€Ÿæ¡çšããŒãžãããå¿åãé¡ãããŸãïŒ æåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã¯ããã« ã¯ãããŸããŠãã³ãŒãã¬ãŒããšã³ãžãã¢ã®å±±äžã§ãã 2020 幎㫠Slack ãæŽ»çšãã ChatOps çšè°ã¯ãŒã¯ãããŒãå
補ã§éçºããã®ã§ãããããã«ã2021 幎 4 æã«ãã® Slack çšè°ãšé»åå¥çŽã·ã¹ãã ã§ãã ã¯ã©ãŠããµã€ã³ ã飿ºãããŠãé»åå¥çŽããã£ãšäŸ¿å©ã«äœ¿ããçç£æ§ã®åäžãå®çŸããŸããã®ã§ã話ãããããŸãã ãŸããåœç€Ÿã®çšè°ã·ã¹ãã 㯠2020 幎 12 æã®åœç€Ÿã®èšäº ã®ããããã«ãªããŸãããçšè°ã®äœæ¥ã Slack äžã§å®çµããã ChatOps ã«ããçšè°ã¯ãŒã¯ãã㌠ãšãªã£ãŠãããŸããæ¬çš¿ã«ã€ããŠã¯ 2021 幎 7 æã«å·çããŠãããŸãã®ã§äžåºŠå°å
¥ãã 1 幎çšçµéãããã®é倧ããªãã©ãã«ãç¡ããä»ãåœç€Ÿã®æ¥µããŠè¿
éãªæææ±ºå®ã®äžå©ã«ãªã£ãŠããŸããChatOps ã«ããçšè°ã¯ãŒã¯ãããŒã«ã€ããŠã¯ãçŽè¿ã2021 幎 6 æã« LayerX 瀟ã LayerX ã¯ãŒã¯ãããŒã®æ°æ©èœãšããŠçºè¡š ãããµãŒãã¹ãšããŠãæäŸããã æ¥çµæ°è ã§ãåãäžããããŠããããšãããä»çŸåšã®ãã©ãã€ã ãšããŠãå
é²çã§æå¹ãªäžææ³ã§ãã£ããšåèªèããŠãããŸãã ä»åãæ°åã³ãããŠã€ã«ã¹æææ¡å€§é²æ¢ã«äŒŽããªã¢ãŒãã¯ãŒã¯ã®å éãšããç¶æ³ããããåœç€Ÿã§ 2021 幎 4 æã«é»åå¥çŽã·ã¹ãã ãšããŠã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããé»åå¥çŽã«éãããå¥çŽæŒå°äœæ¥ã¯çšè°ã®åŸç¶äœæ¥ã«åœããããããã å°å
¥ããŠäœ¿çšããã®ã¿ãªãããã¯ã©ãŠããµã€ã³ã® API ãå©çšããŠçšè°äžã«ããããŒã¿ãé»åå¥çŽã«éä¿¡ãããããšã§ã·ãŒã ã¬ã¹ãªé£æºãå®çŸããŠããŸããæ¬çš¿ã§ã¯åœç€Ÿãè¡ã£ãã·ãŒã ã¬ã¹ãªé£æºææ³ã«ã€ããŠè©³çްãã説æããããŸãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ã® API 飿ºã«ã€ã㊠å®è£
æŠèŠ åŒç€Ÿã®çšè°ã·ã¹ãã ã§ãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ãšã®é£æºã«ã€ããŠã話ãããŸãããŸããæ¬çš¿ã®éçºéšåãšã·ã¹ãã æ§æã¯äžèšã«ãªã£ãŠãããŸãã åŠçå
容ã®è©³çްã¯åŸã»ã©è¿°ã¹ãŸãããæŠèŠãšããŠã¯ TeamSprit(Apex)ããã¯ã©ãŠããµã€ã³ã® API ãã³ãŒã«ããã¯ã©ãŠããµã€ã³äžã§äœæããå¥çŽææžãžçšè°ã«èšèŒãããŠããå¥çŽæžãã¡ã€ã«ãå
æ¹æ
åœè
çã®æ
å ±ã飿ºããä»çµã¿ãšãªã£ãŠãããŸããããã«ããå¥çŽæ
åœè
ã¯ã¯ã©ãŠããµã€ã³ã«ãã°ã€ã³åŸãäžèšã® 3 ã¹ãããã§å
æ¹ã«éä¿¡ã§ããããã«ãªã£ãŠããŸãã èšèŒå
容ã®ç¢ºèª æŒå°ã»çœ²åç®æã®èšå® å
æ¹ãžã®éä¿¡ ã¯ã©ãŠããµã€ã³ã䜿çšããŠå¥çŽææžãäžããäœæããå Žåã®ãŠãŒã¶äœæ¥ãšãåœç€Ÿã§æ¡çšãã API 飿ºè¡ã£ãå Žåã®ãŠãŒã¶äœæ¥ãæ¯èŒãããã®ãäžèšã®è¡šã§ããäœæ¥ãååçšåºŠåæžãããããšãåãããŸãã äœæ¥é
çª äžããäœæããå Žå API 飿ºãå©çšããåœç€Ÿã®å Žå 1 ãã°ã€ã³ ãã°ã€ã³ 2 å¥çŽææžã®äœæ(ä»¶åãå¥çŽææžãšããŠã®å®åèšå®ç) ãªã 3 å¥çŽæžãã¡ã€ã«ã®ã¢ããããŒã ãªã 4 å
æ¹ã®éä¿¡å
èšå® ãªã 5 æŒå°æ¬ã®èšå® æŒå°æ¬ã®èšå® 6 å
æ¹ãžã®éä¿¡ å
æ¹ãžã®éä¿¡ å®è£
ä»åã®éçºã§äœ¿çšãã ã¯ã©ãŠããµã€ã³ API ã¯äžèšã® 5 ã€ã® API ã䜿çšããŸãã (â»ä»¥éãã¯ã©ãŠããµã€ã³ API ã«å£ãã倿°ã衚çŸããå Žå㯠{} ã§æ¬ããŸã)ã API çš®é¡ äœ¿çšçšé post /token ã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸ post /document å¥çŽææžã®äœæ put /documents/{documentID}/attribute å¥çŽææžã®äœæã§èšå®ã§ããªãã现ããé
ç®ã®èšå® post /documents/{documentID}/files ãã¡ã€ã«ã®ã¢ããããŒã post /documents/{documentID}/participants å
æ¹ã®éä¿¡å
èšå® å
šäœåã§èšèŒããã¯ã©ãŠããµã€ã³ã®é£æºéšã«ã€ããŠãäžèšã® API ãç¹ã亀ããŠè©³çްåãããšäžå³ã®ããã«ãªããŸãã å®è£
æ¹æ³ãšããŠã¯ã¯ã©ãŠããµã€ã³ API ã®ãªãã¡ã¬ã³ã¹ãåç
§ãããã¹ãå®è¡æã«åºåããã curl ã³ãã³ããåèã«åæ§ã®ã¬ã¹ãã³ã¹ãåŸãããã« Apex ã§ HTTP ãªã¯ãšã¹ããå®è£
ããŸãããã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸãäŸã«ãšããšäžèšã®ããã«ãªããŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/token' \ -H 'accept: application/json' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id=xxxxxxyyyyyyzzzzzz' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/token' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Content-Type' , 'application/x-www-form-urlencoded' ); req . setBody ( 'client_id=' + 'xxxxxxyyyyyyzzzzzz' ); ç§èªèº«ãApex ãã¯ã©ãŠããµã€ã³ API ããã®æ¡ä»¶ãæ
åœãããŸã§è§Šã£ãããšããããŸããã§ãããããªã¯ãšã¹ãã®è©Šè¡ããå®è£
ãŸã§ 2 é±éããããªãçšåºŠã§å®è£
ããããšãã§ããŸããã ãã ããå®è£
ãéçšã«ããã£ãŠã¯äžèš 2 ç¹ã«ã€ããŠæ³šæãå¿
èŠã«ãªããŸãã Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã 1. Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ãã¡ã€ã«ã®ã¢ããããŒãã«ã€ããŠã¯ä»å䜿çšãã API ã®äžã§ãå¯äžããã¹ãå®è¡ã® curl ãš Apex ã®ãªã¯ãšã¹ãå®è£
ã§å·®åãçãŸããŸãããŸãããã®å·®åã確èªããããã« curl ã³ãã³ãäŸãš Apex ã®ãªã¯ãšã¹ãå®è£
äŸã§ headerãbody ã«ã»ããããŠããå€ãæ¯èŒããŠã¿ãŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/documents/{document_id}/files' \ -H 'accept: application/json' \ -H 'Authorization: AAAAAABBBBBBCCCCCC' \ -H 'Content-Type: multipart/form-data' \ -F 'name=ãã¹ã' \ -F 'uploadfile=@ãã¹ã.pdf;type=application/pdf' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/documents/{document_id}/files' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Authorization' , âAAAAAABBBBBBCCCCCCâ); req . setHeader ( 'Content-Type' , 'multipart/form-data; boundary={boundary}' ); // â»1 req . setBodyAsBlob ({multipartBody}); // â»2 äž»ãªéã㯠â»1 , â»2 ãšã³ã¡ã³ãããéšåã«ãªããŸãã Apex ã§ã¯ HTTP ãªã¯ãšã¹ãã®å€ãæã§æžããŠããããšã«ãªãã®ã§ããã¹ãå®è¡äŸã®ããã« curl ããããªã«åŠçããŠããéšå(-F ãªãã·ã§ã³ã®éšåã Apex ã§èšèŒããŠãã boundary)ãå®è£
ããªããã°ãªããŸããããããåçŽã«å®è£
ã§ããªãçç±ã«ãªããŸãã boundary ã«ã€ããŠã¯ multipart/form-data ãéä¿¡ããéã«å¿
èŠãªå¢çã§ããããŒã§ã©ã®æååãå¢çã§ããããèšå®ããŸãã curl ã®-F ãªãã·ã§ã³ã§å®çŸ©ããŠããæååãšãã¡ã€ã«æå®éšåã¯ãApex ã§ãã¡ã€ã«(ãã€ããª)ãæ±ãããããã® body ã«å«ãŸããæååãå«ã㊠Blob åã§æ±ãå¿
èŠããããŸã( Content-Transfer-Encoding: base64 ã« API æäŸåŽã察å¿ããŠããå Žåã¯äŸå€ã«ãªããŸã)ããã®ãããæååãšãã€ããªããŒã¿ãçµåãäžã€ã® Blob ã«ããæ¹æ³ã¯äžèšã«ãªããŸãã ããã€ããªããŒã¿ãããbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã® 3 ã°ã«ãŒãã«åããã 3 ã°ã«ãŒãããããã Base64 ã§ç¬Šå·åããã 笊å·åããããã€ããªããŒã¿ããšãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååãã«ã€ããŠãBase64 ã®ããŒã¿ããã£ã³ã°ã瀺ãâ=âãå«ãŸããªãããã«æ¹è¡ã³ãŒãã§èª¿æŽããã ãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã®é ã§çµåããã çµåãã Base64 ã®ããŒã¿ã埩å·ããŠãäžã€ã® Blob ãšããã 2. ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã ã¢ã¯ã»ã¹ããŒã¯ã³ããã®æå¹æé㯠token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹ãšããŠã¯ã©ãŠããµã€ã³ããçºè¡ãããŸãã çºè¡ãããã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 3600 } ãã®ã¬ã¹ãã³ã¹ã®å
ãexpires_in ã®å€ãããŒã¯ã³ã®æå¹æéã«ãªããŸããæ²é¡ã®éããæå¹æéã®ç®¡çã¯ã¯ã©ãŠããµã€ã³åŽã§è¡ãããæå¹æéå
ã«å床ããŒã¯ã³ã®ãªã¯ãšã¹ããè¡ã£ãå Žåãçµéããæéã ã expires_in ã®å€ãå°ãããªã£ãçµæãè¿ã£ãŠããŠãaccess_token ãªã©ã¯åãå€ãååŸãããŸããæå¹æéå
ã« token API ãå床å®è¡ããçµæãäžèšã«ãªããŸãã æå¹æéåãåã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 762 } äžæ¹ãæå¹æéåŸã«ããŒã¯ã³ã®ãªã¯ãšã¹ããå®è¡ãããšããããŸã§ãšç°ãªãã¢ã¯ã»ã¹ããŒã¯ã³ãååŸããæ°ããæå¹æéãèšå®ãããŸãã æå¹æéåãåŸã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "XXXXXXYYYYYYZZZZZZ" , "token_type" : "xxxx" , "expires_in" : 3600 } ãã®ãããAPI 飿ºãäžåºŠåããåŸãæå¹æéããããã§ããäžåºŠ API 飿ºãåããŠããŸã£ãå Žåãã¿ã€ãã³ã°ãæªããšå¥çŽææžã®äœæããæçµåŠçã§ããå
æ¹ã®éä¿¡å
èšå®ãŸã§ã®ããã»ã¹å
ã®ã©ãããããããŒã¯ã³ã®æå¹æéåããçºçããå¯èœæ§ãæ³å®ãããŸããå®éã«æéåããçºçããå Žåãçºçæä»¥éã«çºè¡ãããã®åã® API 飿ºåŠçã倱æããŸãã ããŒã¯ã³ã®æå¹æéåããçºçããéãAPI ãªãã¡ã¬ã³ã¹ãã HTTP ã¹ããŒã¿ã¹ã³ãŒãã 401 ãã€ãšã©ãŒå
容ãâunauthorizedâã§å¿çãããããšãããåœç€Ÿã§ã¯ãã®ãšã©ãŒãåããå Žåã«ããŒã¯ã³ãåååŸããŠåŠçããªãã©ã€ããããã«å®è£
ããŸããã æŒå°ææžäœæãäŸã«ãšããšäžèšã®ãããªå®è£
ã€ã¡ãŒãžã«ãªããŸãã //ã¯ã©ãŠããµã€ã³äžã«æŒå°ææžãäœæããäœæããææž ID ãååŸãã public String getDocumentId ( String authToken, String title, String message){ ã»ã»ã»äžç¥ã»ã»ã» HTTPResponse res = http . send (req); if ( res . getStatusCode () == 200 ){ ã»ã»ã»æ£åžžã«çµäºããéã®åŠçã»ã»ã» } //ã¿ã€ãã³ã°ãæªã token ãã¿ã€ã ã¢ãŠãããå ŽåãããŒã¯ã³ãååŸãçŽããŠããªãã©ã€ãã else if ( res . getStatusCode () == 401 ){ //ã¬ã¹ãã³ã¹ã®å
容ã確èªããããããšã©ãŒã¬ã¹ãã³ã¹ã®äžèº«ãååŸãã Map < String , Object > responseBody = new Map < String , Object >(); responseBody = ( Map <String, Object>) JSON . deserializeUntyped ( res . getBody ()); String errorVal = (String) responseBody . get ( 'error' ); //ãªãã¡ã¬ã³ã¹äžãã¢ã¯ã»ã¹ããŒã¯ã³ãç¡å¹(æå¹æéåã)ã®å Žåã'unauthorizedâãšãªã if ( errorVal . equals ( 'unauthorized' )){ //ã¯ã©ãŠããµã€ã³ã®ã¢ã¯ã»ã¹ããŒã¯ã³ã®åååŸ authToken = getAuthToken (); //åçŽååž°ã§åå®è¡ããã documentId = getDocumentId (authToken, title, message); } ã»ã»ã»äžç¥ã»ã»ã» } ã»ã»ã»ä»¥äžçç¥ã»ã»ã» } å®è£
ãçµã㊠äžèšãå®è£
ããçµæãçšè°ãšå
¥åå
容ãåãããŸãã¯ãçšè°ããçæã§ããå
容ã¯å
šãŠã·ã¹ãã 飿ºã§èªåçæãããããæŒå°æ
åœã¯çšè°ãšã¯ã©ãŠããµã€ã³ã®ç»é¢ã䞊ã¹ãŠè»¢èšãããããªç
©éãªäœæ¥ãå¿
èŠãšããªãç°å¢ã«ãªããŸããããŸããå¥çŽæžã®è£œæ¬ãéµéçã®çŽåªäœã§ãããæ
ã®äºåã®åæžãã§ããããã«ãªãçã®ãé»åå¥çŽãå°å
¥ããããšã®ããããã®ã¡ãªããã䜵ããŠäº«åããŠããŸãã åœç€Ÿã§ã¯ 2021 幎 4 æåŸåããã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããã2021 幎 6 ææç¹ã§ã¯ãã§ã« æéã§ç· çµããå¥çŽæžã®ã3 å²ä»¥äžããé»åå¥çŽã掻çšããŠãã ãæŒå°æ
åœã®å±æãšããŠä»åŸãå©çšãæ¡å€§ããŠããäºå®ã§ãã ã³ãŒãã¬ãŒããšã³ãžãã¢åéäž ã¡ãã¬ãŒã®ã³ãŒãã¬ãŒãéšéã§ã¯ãæ¬çš¿ã®ããã«ãSaaS ã®å°å
¥ã²ãšã€ãšã£ãŠãæ€èšãå°œãããæ¢åã®ã·ã¹ãã ãšææ©çã«çµåãããããšã§ã培åºçã«åçæ§ã远æ±ããçµç¹åºç€ãã仿ãã¥ããããè¡ã£ãŠããŸãã é¢çœããïŒèå³ãããïŒãšæããæ¹ã¯ããã²åœç€Ÿæ¡çšããŒãžãããå¿åãé¡ãããŸãïŒ æåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã¯ããã« ã¯ãããŸããŠãã³ãŒãã¬ãŒããšã³ãžãã¢ã®å±±äžã§ãã 2020 幎㫠Slack ãæŽ»çšãã ChatOps çšè°ã¯ãŒã¯ãããŒãå
補ã§éçºããã®ã§ãããããã«ã2021 幎 4 æã«ãã® Slack çšè°ãšé»åå¥çŽã·ã¹ãã ã§ãã ã¯ã©ãŠããµã€ã³ ã飿ºãããŠãé»åå¥çŽããã£ãšäŸ¿å©ã«äœ¿ããçç£æ§ã®åäžãå®çŸããŸããã®ã§ã話ãããããŸãã ãŸããåœç€Ÿã®çšè°ã·ã¹ãã 㯠2020 幎 12 æã®åœç€Ÿã®èšäº ã®ããããã«ãªããŸãããçšè°ã®äœæ¥ã Slack äžã§å®çµããã ChatOps ã«ããçšè°ã¯ãŒã¯ãã㌠ãšãªã£ãŠãããŸããæ¬çš¿ã«ã€ããŠã¯ 2021 幎 7 æã«å·çããŠãããŸãã®ã§äžåºŠå°å
¥ãã 1 幎çšçµéãããã®é倧ããªãã©ãã«ãç¡ããä»ãåœç€Ÿã®æ¥µããŠè¿
éãªæææ±ºå®ã®äžå©ã«ãªã£ãŠããŸããChatOps ã«ããçšè°ã¯ãŒã¯ãããŒã«ã€ããŠã¯ãçŽè¿ã2021 幎 6 æã« LayerX 瀟ã LayerX ã¯ãŒã¯ãããŒã®æ°æ©èœãšããŠçºè¡š ãããµãŒãã¹ãšããŠãæäŸããã æ¥çµæ°è ã§ãåãäžããããŠããããšãããä»çŸåšã®ãã©ãã€ã ãšããŠãå
é²çã§æå¹ãªäžææ³ã§ãã£ããšåèªèããŠãããŸãã ä»åãæ°åã³ãããŠã€ã«ã¹æææ¡å€§é²æ¢ã«äŒŽããªã¢ãŒãã¯ãŒã¯ã®å éãšããç¶æ³ããããåœç€Ÿã§ 2021 幎 4 æã«é»åå¥çŽã·ã¹ãã ãšããŠã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããé»åå¥çŽã«éãããå¥çŽæŒå°äœæ¥ã¯çšè°ã®åŸç¶äœæ¥ã«åœããããããã å°å
¥ããŠäœ¿çšããã®ã¿ãªãããã¯ã©ãŠããµã€ã³ã® API ãå©çšããŠçšè°äžã«ããããŒã¿ãé»åå¥çŽã«éä¿¡ãããããšã§ã·ãŒã ã¬ã¹ãªé£æºãå®çŸããŠããŸããæ¬çš¿ã§ã¯åœç€Ÿãè¡ã£ãã·ãŒã ã¬ã¹ãªé£æºææ³ã«ã€ããŠè©³çްãã説æããããŸãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ã® API 飿ºã«ã€ã㊠å®è£
æŠèŠ åŒç€Ÿã®çšè°ã·ã¹ãã ã§ãã TeamSpirit ãšã¯ã©ãŠããµã€ã³ãšã®é£æºã«ã€ããŠã話ãããŸãããŸããæ¬çš¿ã®éçºéšåãšã·ã¹ãã æ§æã¯äžèšã«ãªã£ãŠãããŸãã åŠçå
容ã®è©³çްã¯åŸã»ã©è¿°ã¹ãŸãããæŠèŠãšããŠã¯ TeamSprit(Apex)ããã¯ã©ãŠããµã€ã³ã® API ãã³ãŒã«ããã¯ã©ãŠããµã€ã³äžã§äœæããå¥çŽææžãžçšè°ã«èšèŒãããŠããå¥çŽæžãã¡ã€ã«ãå
æ¹æ
åœè
çã®æ
å ±ã飿ºããä»çµã¿ãšãªã£ãŠãããŸããããã«ããå¥çŽæ
åœè
ã¯ã¯ã©ãŠããµã€ã³ã«ãã°ã€ã³åŸãäžèšã® 3 ã¹ãããã§å
æ¹ã«éä¿¡ã§ããããã«ãªã£ãŠããŸãã èšèŒå
容ã®ç¢ºèª æŒå°ã»çœ²åç®æã®èšå® å
æ¹ãžã®éä¿¡ ã¯ã©ãŠããµã€ã³ã䜿çšããŠå¥çŽææžãäžããäœæããå Žåã®ãŠãŒã¶äœæ¥ãšãåœç€Ÿã§æ¡çšãã API 飿ºè¡ã£ãå Žåã®ãŠãŒã¶äœæ¥ãæ¯èŒãããã®ãäžèšã®è¡šã§ããäœæ¥ãååçšåºŠåæžãããããšãåãããŸãã äœæ¥é
çª äžããäœæããå Žå API 飿ºãå©çšããåœç€Ÿã®å Žå 1 ãã°ã€ã³ ãã°ã€ã³ 2 å¥çŽææžã®äœæ(ä»¶åãå¥çŽææžãšããŠã®å®åèšå®ç) ãªã 3 å¥çŽæžãã¡ã€ã«ã®ã¢ããããŒã ãªã 4 å
æ¹ã®éä¿¡å
èšå® ãªã 5 æŒå°æ¬ã®èšå® æŒå°æ¬ã®èšå® 6 å
æ¹ãžã®éä¿¡ å
æ¹ãžã®éä¿¡ å®è£
ä»åã®éçºã§äœ¿çšãã ã¯ã©ãŠããµã€ã³ API ã¯äžèšã® 5 ã€ã® API ã䜿çšããŸãã (â»ä»¥éãã¯ã©ãŠããµã€ã³ API ã«å£ãã倿°ã衚çŸããå Žå㯠{} ã§æ¬ããŸã)ã API çš®é¡ äœ¿çšçšé post /token ã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸ post /document å¥çŽææžã®äœæ put /documents/{documentID}/attribute å¥çŽææžã®äœæã§èšå®ã§ããªãã现ããé
ç®ã®èšå® post /documents/{documentID}/files ãã¡ã€ã«ã®ã¢ããããŒã post /documents/{documentID}/participants å
æ¹ã®éä¿¡å
èšå® å
šäœåã§èšèŒããã¯ã©ãŠããµã€ã³ã®é£æºéšã«ã€ããŠãäžèšã® API ãç¹ã亀ããŠè©³çްåãããšäžå³ã®ããã«ãªããŸãã å®è£
æ¹æ³ãšããŠã¯ã¯ã©ãŠããµã€ã³ API ã®ãªãã¡ã¬ã³ã¹ãåç
§ãããã¹ãå®è¡æã«åºåããã curl ã³ãã³ããåèã«åæ§ã®ã¬ã¹ãã³ã¹ãåŸãããã« Apex ã§ HTTP ãªã¯ãšã¹ããå®è£
ããŸãããã¢ã¯ã»ã¹ããŒã¯ã³ã®ååŸãäŸã«ãšããšäžèšã®ããã«ãªããŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/token' \ -H 'accept: application/json' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id=xxxxxxyyyyyyzzzzzz' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/token' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Content-Type' , 'application/x-www-form-urlencoded' ); req . setBody ( 'client_id=' + 'xxxxxxyyyyyyzzzzzz' ); ç§èªèº«ãApex ãã¯ã©ãŠããµã€ã³ API ããã®æ¡ä»¶ãæ
åœãããŸã§è§Šã£ãããšããããŸããã§ãããããªã¯ãšã¹ãã®è©Šè¡ããå®è£
ãŸã§ 2 é±éããããªãçšåºŠã§å®è£
ããããšãã§ããŸããã ãã ããå®è£
ãéçšã«ããã£ãŠã¯äžèš 2 ç¹ã«ã€ããŠæ³šæãå¿
èŠã«ãªããŸãã Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã 1. Apex ããã¯ã©ãŠããµã€ã³ãžã®ãã¡ã€ã«ã®ã¢ããããŒãã¯åçŽã§ã¯ãªã ãã¡ã€ã«ã®ã¢ããããŒãã«ã€ããŠã¯ä»å䜿çšãã API ã®äžã§ãå¯äžããã¹ãå®è¡ã® curl ãš Apex ã®ãªã¯ãšã¹ãå®è£
ã§å·®åãçãŸããŸãããŸãããã®å·®åã確èªããããã« curl ã³ãã³ãäŸãš Apex ã®ãªã¯ãšã¹ãå®è£
äŸã§ headerãbody ã«ã»ããããŠããå€ãæ¯èŒããŠã¿ãŸãã API ãªãã¡ã¬ã³ã¹ã§ã® curl ã³ãã³ãäŸ curl -X 'POST' \ 'https://api.cloudsign.jp/documents/{document_id}/files' \ -H 'accept: application/json' \ -H 'Authorization: AAAAAABBBBBBCCCCCC' \ -H 'Content-Type: multipart/form-data' \ -F 'name=ãã¹ã' \ -F 'uploadfile=@ãã¹ã.pdf;type=application/pdf' Apex ã§ã®ãªã¯ãšã¹ãå®è£
äŸ HttpRequest req = new HttpRequest (); req . setMethod ( 'POST' ); req . setEndpoint ( 'https://api.cloudsign.jp/documents/{document_id}/files' ); req . setHeader ( 'accept' , 'application/json' ); req . setHeader ( 'Authorization' , âAAAAAABBBBBBCCCCCCâ); req . setHeader ( 'Content-Type' , 'multipart/form-data; boundary={boundary}' ); // â»1 req . setBodyAsBlob ({multipartBody}); // â»2 äž»ãªéã㯠â»1 , â»2 ãšã³ã¡ã³ãããéšåã«ãªããŸãã Apex ã§ã¯ HTTP ãªã¯ãšã¹ãã®å€ãæã§æžããŠããããšã«ãªãã®ã§ããã¹ãå®è¡äŸã®ããã« curl ããããªã«åŠçããŠããéšå(-F ãªãã·ã§ã³ã®éšåã Apex ã§èšèŒããŠãã boundary)ãå®è£
ããªããã°ãªããŸããããããåçŽã«å®è£
ã§ããªãçç±ã«ãªããŸãã boundary ã«ã€ããŠã¯ multipart/form-data ãéä¿¡ããéã«å¿
èŠãªå¢çã§ããããŒã§ã©ã®æååãå¢çã§ããããèšå®ããŸãã curl ã®-F ãªãã·ã§ã³ã§å®çŸ©ããŠããæååãšãã¡ã€ã«æå®éšåã¯ãApex ã§ãã¡ã€ã«(ãã€ããª)ãæ±ãããããã® body ã«å«ãŸããæååãå«ã㊠Blob åã§æ±ãå¿
èŠããããŸã( Content-Transfer-Encoding: base64 ã« API æäŸåŽã察å¿ããŠããå Žåã¯äŸå€ã«ãªããŸã)ããã®ãããæååãšãã€ããªããŒã¿ãçµåãäžã€ã® Blob ã«ããæ¹æ³ã¯äžèšã«ãªããŸãã ããã€ããªããŒã¿ãããbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã® 3 ã°ã«ãŒãã«åããã 3 ã°ã«ãŒãããããã Base64 ã§ç¬Šå·åããã 笊å·åããããã€ããªããŒã¿ããšãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååãã«ã€ããŠãBase64 ã®ããŒã¿ããã£ã³ã°ã瀺ãâ=âãå«ãŸããªãããã«æ¹è¡ã³ãŒãã§èª¿æŽããã ãbody ã®éå§ãããã€ããªããŒã¿ãŸã§ã®æååããããã€ããªããŒã¿ããããã€ããªããŒã¿ä»¥éããçµç«¯ãŸã§ã®æååãã®é ã§çµåããã çµåãã Base64 ã®ããŒã¿ã埩å·ããŠãäžã€ã® Blob ãšããã 2. ã¢ã¯ã»ã¹ããŒã¯ã³ã®æå¹æéã¯ã¯ã©ãŠããµã€ã³ã§ã³ã³ãããŒã«ããã ã¢ã¯ã»ã¹ããŒã¯ã³ããã®æå¹æé㯠token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹ãšããŠã¯ã©ãŠããµã€ã³ããçºè¡ãããŸãã çºè¡ãããã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 3600 } ãã®ã¬ã¹ãã³ã¹ã®å
ãexpires_in ã®å€ãããŒã¯ã³ã®æå¹æéã«ãªããŸããæ²é¡ã®éããæå¹æéã®ç®¡çã¯ã¯ã©ãŠããµã€ã³åŽã§è¡ãããæå¹æéå
ã«å床ããŒã¯ã³ã®ãªã¯ãšã¹ããè¡ã£ãå Žåãçµéããæéã ã expires_in ã®å€ãå°ãããªã£ãçµæãè¿ã£ãŠããŠãaccess_token ãªã©ã¯åãå€ãååŸãããŸããæå¹æéå
ã« token API ãå床å®è¡ããçµæãäžèšã«ãªããŸãã æå¹æéåãåã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "AAAAAABBBBBBCCCCCC" , "token_type" : âxxxxâ , "expires_in" : 762 } äžæ¹ãæå¹æéåŸã«ããŒã¯ã³ã®ãªã¯ãšã¹ããå®è¡ãããšããããŸã§ãšç°ãªãã¢ã¯ã»ã¹ããŒã¯ã³ãååŸããæ°ããæå¹æéãèšå®ãããŸãã æå¹æéåãåŸã« token API ãçºè¡ããéã®ã¬ã¹ãã³ã¹äŸ { "access_token" : "XXXXXXYYYYYYZZZZZZ" , "token_type" : "xxxx" , "expires_in" : 3600 } ãã®ãããAPI 飿ºãäžåºŠåããåŸãæå¹æéããããã§ããäžåºŠ API 飿ºãåããŠããŸã£ãå Žåãã¿ã€ãã³ã°ãæªããšå¥çŽææžã®äœæããæçµåŠçã§ããå
æ¹ã®éä¿¡å
èšå®ãŸã§ã®ããã»ã¹å
ã®ã©ãããããããŒã¯ã³ã®æå¹æéåããçºçããå¯èœæ§ãæ³å®ãããŸããå®éã«æéåããçºçããå Žåãçºçæä»¥éã«çºè¡ãããã®åã® API 飿ºåŠçã倱æããŸãã ããŒã¯ã³ã®æå¹æéåããçºçããéãAPI ãªãã¡ã¬ã³ã¹ãã HTTP ã¹ããŒã¿ã¹ã³ãŒãã 401 ãã€ãšã©ãŒå
容ãâunauthorizedâã§å¿çãããããšãããåœç€Ÿã§ã¯ãã®ãšã©ãŒãåããå Žåã«ããŒã¯ã³ãåååŸããŠåŠçããªãã©ã€ããããã«å®è£
ããŸããã æŒå°ææžäœæãäŸã«ãšããšäžèšã®ãããªå®è£
ã€ã¡ãŒãžã«ãªããŸãã //ã¯ã©ãŠããµã€ã³äžã«æŒå°ææžãäœæããäœæããææž ID ãååŸãã public String getDocumentId ( String authToken, String title, String message){ ã»ã»ã»äžç¥ã»ã»ã» HTTPResponse res = http . send (req); if ( res . getStatusCode () == 200 ){ ã»ã»ã»æ£åžžã«çµäºããéã®åŠçã»ã»ã» } //ã¿ã€ãã³ã°ãæªã token ãã¿ã€ã ã¢ãŠãããå ŽåãããŒã¯ã³ãååŸãçŽããŠããªãã©ã€ãã else if ( res . getStatusCode () == 401 ){ //ã¬ã¹ãã³ã¹ã®å
容ã確èªããããããšã©ãŒã¬ã¹ãã³ã¹ã®äžèº«ãååŸãã Map < String , Object > responseBody = new Map < String , Object >(); responseBody = ( Map <String, Object>) JSON . deserializeUntyped ( res . getBody ()); String errorVal = (String) responseBody . get ( 'error' ); //ãªãã¡ã¬ã³ã¹äžãã¢ã¯ã»ã¹ããŒã¯ã³ãç¡å¹(æå¹æéåã)ã®å Žåã'unauthorizedâãšãªã if ( errorVal . equals ( 'unauthorized' )){ //ã¯ã©ãŠããµã€ã³ã®ã¢ã¯ã»ã¹ããŒã¯ã³ã®åååŸ authToken = getAuthToken (); //åçŽååž°ã§åå®è¡ããã documentId = getDocumentId (authToken, title, message); } ã»ã»ã»äžç¥ã»ã»ã» } ã»ã»ã»ä»¥äžçç¥ã»ã»ã» } å®è£
ãçµã㊠äžèšãå®è£
ããçµæãçšè°ãšå
¥åå
容ãåãããŸãã¯ãçšè°ããçæã§ããå
容ã¯å
šãŠã·ã¹ãã 飿ºã§èªåçæãããããæŒå°æ
åœã¯çšè°ãšã¯ã©ãŠããµã€ã³ã®ç»é¢ã䞊ã¹ãŠè»¢èšãããããªç
©éãªäœæ¥ãå¿
èŠãšããªãç°å¢ã«ãªããŸããããŸããå¥çŽæžã®è£œæ¬ãéµéçã®çŽåªäœã§ãããæ
ã®äºåã®åæžãã§ããããã«ãªãçã®ãé»åå¥çŽãå°å
¥ããããšã®ããããã®ã¡ãªããã䜵ããŠäº«åããŠããŸãã åœç€Ÿã§ã¯ 2021 幎 4 æåŸåããã¯ã©ãŠããµã€ã³ãå°å
¥ããŸãããã2021 幎 6 ææç¹ã§ã¯ãã§ã« æéã§ç· çµããå¥çŽæžã®ã3 å²ä»¥äžããé»åå¥çŽã掻çšããŠãã ãæŒå°æ
åœã®å±æãšããŠä»åŸãå©çšãæ¡å€§ããŠããäºå®ã§ãã ã³ãŒãã¬ãŒããšã³ãžãã¢åéäž ã¡ãã¬ãŒã®ã³ãŒãã¬ãŒãéšéã§ã¯ãæ¬çš¿ã®ããã«ãSaaS ã®å°å
¥ã²ãšã€ãšã£ãŠãæ€èšãå°œãããæ¢åã®ã·ã¹ãã ãšææ©çã«çµåãããããšã§ã培åºçã«åçæ§ã远æ±ããçµç¹åºç€ãã仿ãã¥ããããè¡ã£ãŠããŸãã é¢çœããïŒèå³ãããïŒãšæããæ¹ã¯ããã²åœç€Ÿæ¡çšããŒãžãããå¿åãé¡ãããŸãïŒ æåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã2020 幎 9 æã«èª¿å€è¬å±åãã®ãããã¯ãããªãªãŒã¹ããã ãã® ãã¬ã¹ãªãªãŒã¹ ãçºè¡šãããã®ã¯ãCOVID-19 ã®æææ¡å€§ã«ç«¯ãçºããç·æ¥äºæ
宣èšãçºä»€ãããŠãã 2020 幎 4 æåã°ããã® 1 ã¶æåŸãç§ã¯ãªã¢ãŒãã¯ãŒã¯äžã§ã®ãªã³ã©ã€ã³ MTG ã«ãªãããªãç¶æ
ã®ãŸãŸã調å€è¬å±åããããã¯ãã®ãã©ã³ãã£ã³ã°ã«ã€ããŠåœ¹å¡é£ãäž»èŠãããžã§ã¯ãã¡ã³ããŒã«ãã¬ãŒã³ãè¡ã£ãŠããã ä»åã¯åœæã®ãã¬ãŒã³è³æããã©ããªãã Pharms ã®ãã©ã³ãèšèšã«ã€ããŠèª¬æããŠããããšæãã å»è¬åæ¥ã®ã«ãŒããšã¯ ãã¶ã€ããŒãšããŠåç°ãã¡ãã¬ãŒã«å
¥ç€ŸããŠããããªã³ã©ã€ã³èšºçãé»åã«ã«ããªã©ãäž»ã«å»çæ©é¢åãã®ãããã¯ããã¶ã€ã³ãæ
åœããŠãããã®ã®ã調å€è¬å±ã®ãããã¯ããã¶ã€ã³ã¯æªç¥ã®é åããã©ã³ãã£ã³ã°ãæ€èšããäžã§ãè¬ã®åŠæ¹ãè¡ãå»åž«ãšèª¿å€ã宿œããè¬å€åž«ãåæ
ããŠè¡ãå»è¬åæ¥ã®ã«ãŒãã€ããŠèª¿ã¹ãããšããã¯ãããã å»è¬åæ¥ã¯ãæ¯æ®ºãæããããªãŒããªã 2 äžã䞻治å»ã®åŠæ¹ããè¬ããæ¯ãçãããŠãªããä»è
ã«ãã§ãã¯ãããã®ãå§ãŸããšãããŠããã ïŒåèïŒ å
¬çç€Ÿå£æ³äºº æ¥æ¬è¬å€åž«äŒ HP ïœå»è¬åæ¥ãšã¯ ïŒ å»çãã©ãããã©ãŒã ã®æªæ¥ãèŠæ®ãããã©ã³ãå®çŸ© 次ã«ã調å€ã«é¢ããæ³å¶åºŠãç«¶åãªã©ã®å€éšèŠå ãã¡ãã¬ãŒãšããŠã®ãã©ã³ãåãéçºåãªã©ã®å
éšèŠå ã«ã€ããŠç°¡æãª SWOT åæãè¡ãã調å€è¬å±ã®ãããžã§ã¯ãã®åŠ¥åœæ§ãæ€èšŒãã¡ãã¬ãŒãåãçµãå»çãã©ãããã©ãŒã äºæ¥(â»)ã«ããããã«èª¿å€è¬å±ãããžã§ã¯ããå ããããšã«ããä»ã®ãããã¯ããšã®ãã©ã³ã¹ãèæ
®ããªãããã©ã³ãããŒãã³ã°æ€èšãè¡ã£ãŠãã£ãã â») å»çãã©ãããã©ãŒã äºæ¥ã§ã¯ãæ£è
ãšå»çé åã®æ¥åã·ã¹ãã ã SaaS ãããã¯ãã§ã€ãªããæ£è
ãšå»çæ©é¢åæ¹ã«ãšã£ãŠããã¯ãããžãŒã®æ©æµãåããããšã®ã§ãããã©ãããã©ãŒã ã¥ãããè¡ã£ãŠãããäž»èŠãµãŒãã¹ã¯ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãCLINICSãããªã³ã©ã€ã³èšºçã»æè¬æå°ã¢ããªãCLINICSãã ã¡ãã¬ãŒã®ãããŸã§ã®æŽå²ãæ¯ãè¿ããšããããã¯ãå
容ãæç¢ºãã€ç«¯çã«è¡šããããŒãã³ã°ãå€ããã¡ãã¬ãŒããã = ãäžå€®çªç ŽãªããŒãã³ã°ããšããããšãå®çŸ©ããããŒãã³ã°ãæ€èšããŠãã£ãã æçµçã«èª¿å€è¬å±ã衚ããPharmaciesïŒãã¡ãŒãã·ãŒãºïŒããšãPharmsïŒãã¡ãŒã ã¹ïŒãã® 2 æ¡ã«çµèŸŒã¿ãããããã®ã¡ãªããã»ãã¡ãªãããæŽçããŠãã£ãã åœæã瀟å
ã§ã¯èª¿å€è¬å±ã·ã¹ãã = Pharmacies ãšåŒã°ããŠããããã®äžå€®çªç ŽãªããŒãã³ã°ãææååè£ã§ãã£ããäžæ¹ã§ããã©ã³ãã§äœçŸãã¹ãã¢ã€ãã³ãã£ãã£ã®æ¬ åŠããåŒã³ã¥ãããªã©ã課é¡ãšããŠæ£èŠããããããã«ã¯å»çãã©ãããã©ãŒã å
šäœãèŠæ®ãããã©ã³ãæ§ç¯ãšãã芳ç¹ããèæ
®ãããšããã©ã³ã¹é¢ã§ã®èª²é¡ãæµ®ã圫ãã«ãªããããã課é¡ãã¯ãªã¢ã«ããŠèªçããã®ã PharmsïŒãã¡ãŒã ã¹ïŒã§ããã ãŽã£ãžã¥ã¢ã«ã»ã¢ã€ãã³ãã£ãã£ã®èšèš ãã©ã³ãåãåºãŸãã°ãããšã¯ãŽã£ãžã¥ã¢ã«ã»ã¢ã€ãã³ãã£ãã£ãçªãè©°ããŠããã®ã¿ãèŠèªæ§ãå¯èªæ§ãèæ
®ãããã©ã³ããã§ã€ã¹ã®æ€èšŒã調å€è¬å±ãšæ³èµ·ããããã©ã³ãã«ã©ãŒã®éžå®ããŸãã·ã³ãã«ã®èšèšãªã©ã«åãæãã£ãŠããã ãã©ã³ãã«ã©ãŒã®éžå®ã«ãããŠã¯ããªããšãªããç·ããšããã€ã¡ãŒãžãããŒã å
ã§ããã£ããããã粟緻åãããããè¬ã®èµ·æºã調å€è¬å±æ¬æ¥ã®åœ¹å²ãèžãŸã詳现ã«èœãšã蟌ãã§ãã£ãã ããŽã«ã·ã³ãã«ãå«ããããå«ããªãããæ€èšã®ã²ãšã€ã§ãã£ãããå»çãã©ãããã©ãŒã äºæ¥ã«ãã CLINICS ã®ããŽãã·ã³ãã«ããŒã¯ä»ãã§ãããããå»çãã©ãããã©ãŒã ã«é¢é£ãããããã¯ã = ã·ã³ãã«ãå®çŸ©ãããšããã«ãŒã«ãçå®ãã·ã³ãã«ãèšèšãã·ã³ãã«ã¯è¬ã®æ§é åŒã«å©çšããããããã«ã æ§é ããã¢ããŒããšãããã©ã³ãã«ã©ãŒãšåãããŠè©³çްã«äœã蟌ãã§ãã£ãã ãŸããPharms ã®è£œå玹ä»çšã©ã³ãã£ã³ã°ããŒãžããããã¯ããã¶ã€ã³ã®ã¢ãã¯ã¢ãããäœæããããŽãšã®ãã©ã³ã¹ãªã©ãèæ
®ããªãã調æŽãè¡ã£ãŠãã£ãã æçµçã«ãæ£è
ã»èª¿å€è¬å±ã»å»çæ©é¢ã® 3 è
ã®ã€ãªãããäžè§åœ¢ã§è¡šçŸãã€ã€ãäžå¿ãå
è¿°ãããããã«ã æ§é ããã¢ããŒããšãã圢ç¶ãšãPharms ã®é æåãPããã«ãã»ã«ãšé å€ã§è¡šçŸããŠã調å€è¬å±ã·ã¹ãã ãšããŠã·ã³ãã«ããŒã¯ã«åœãå¹ã蟌ãã ã ãŸãšã ãã®ãããªéçšãçµãŠãPharms ã®ãã©ã³ãã宿ããã®ã ãããããã¯èª¿å€è¬å±ã·ã¹ãã ã®éçºãšããŠã¯æ°·å±±ã®äžè§ã§ãããªããæ¬äžžã¯ãããã¯ããã¶ã€ã³ãäžè¬çã«ã¯ããŽãšãããã¯ããã¶ã€ã³ã¯å¥ãããžã§ã¯ãã§é²è¡ããããæ
åœãããã¶ã€ããŒãå¥ã ã£ããããããšãå€ãã®ã§ã¯ãªãã ãããã Pharms ã¯ãã©ã³ãèšèšããããã¯ããã¶ã€ã³ãããŒã±ãã£ã³ã°è³æãšãã£ããã¶ã€ã³é åããã¹ãŠç§ãæ
åœããŠããããšã«ãªãã®ã ããããæ
ã«äºæ¥å
šäœã俯ç°ãçè§£ããªãããã¶ã€ã³ã UI ãã¶ã€ã³ã«éã蟌ããŠæºããããšãã§ããããã¶ã€ããŒãã£ãªã¢ãšããŠããããŸã§å¹
åºãæºãããããšã¯éåžžã«è²ŽéãªçµéšãåŸãããšãã§ãããšèªè² ããŠããã ç¶ããŠãããã¯ããã¶ã€ã³éçºã®ç§è©±ã«ã€ããŠèªããããšããã ããçŸåš Pharms 以å€ã®å»çãã©ãããã©ãŒã äºæ¥ã«é¢é£ããæ°ããªãããã¯ãéçºã«æ³šåããŠããããããã®è©±ã¯ãŸãã®æ©äŒã«ã å»çãã©ãããã©ãŒã äºæ¥ã«é¢é£ãããããã¯ãããããããåµåºãæé·ãããŠããé¢çœãææã«ãããçŸåšãã¶ã€ããŒãç©æ¥µæ¡çšäžã§ããã«ãžã¥ã¢ã«ã«è©±ãèããããå»çé åã®ãã¶ã€ã³ã«èå³ããããšãã£ããã¶ã€ããŒã®æ¹ã¯ããã² ãã¡ã ãŸã§ãé£çµ¡ããã ãããšå¹žãã§ãã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã2020 幎 9 æã«èª¿å€è¬å±åãã®ãããã¯ãããªãªãŒã¹ããã ãã® ãã¬ã¹ãªãªãŒã¹ ãçºè¡šãããã®ã¯ãCOVID-19 ã®æææ¡å€§ã«ç«¯ãçºããç·æ¥äºæ
宣èšãçºä»€ãããŠãã 2020 幎 4 æåã°ããã® 1 ã¶æåŸãç§ã¯ãªã¢ãŒãã¯ãŒã¯äžã§ã®ãªã³ã©ã€ã³ MTG ã«ãªãããªãç¶æ
ã®ãŸãŸã調å€è¬å±åããããã¯ãã®ãã©ã³ãã£ã³ã°ã«ã€ããŠåœ¹å¡é£ãäž»èŠãããžã§ã¯ãã¡ã³ããŒã«ãã¬ãŒã³ãè¡ã£ãŠããã ä»åã¯åœæã®ãã¬ãŒã³è³æããã©ããªãã Pharms ã®ãã©ã³ãèšèšã«ã€ããŠèª¬æããŠããããšæãã å»è¬åæ¥ã®ã«ãŒããšã¯ ãã¶ã€ããŒãšããŠåç°ãã¡ãã¬ãŒã«å
¥ç€ŸããŠããããªã³ã©ã€ã³èšºçãé»åã«ã«ããªã©ãäž»ã«å»çæ©é¢åãã®ãããã¯ããã¶ã€ã³ãæ
åœããŠãããã®ã®ã調å€è¬å±ã®ãããã¯ããã¶ã€ã³ã¯æªç¥ã®é åããã©ã³ãã£ã³ã°ãæ€èšããäžã§ãè¬ã®åŠæ¹ãè¡ãå»åž«ãšèª¿å€ã宿œããè¬å€åž«ãåæ
ããŠè¡ãå»è¬åæ¥ã®ã«ãŒãã€ããŠèª¿ã¹ãããšããã¯ãããã å»è¬åæ¥ã¯ãæ¯æ®ºãæããããªãŒããªã 2 äžã䞻治å»ã®åŠæ¹ããè¬ããæ¯ãçãããŠãªããä»è
ã«ãã§ãã¯ãããã®ãå§ãŸããšãããŠããã ïŒåèïŒ å
¬çç€Ÿå£æ³äºº æ¥æ¬è¬å€åž«äŒ HP ïœå»è¬åæ¥ãšã¯ ïŒ å»çãã©ãããã©ãŒã ã®æªæ¥ãèŠæ®ãããã©ã³ãå®çŸ© 次ã«ã調å€ã«é¢ããæ³å¶åºŠãç«¶åãªã©ã®å€éšèŠå ãã¡ãã¬ãŒãšããŠã®ãã©ã³ãåãéçºåãªã©ã®å
éšèŠå ã«ã€ããŠç°¡æãª SWOT åæãè¡ãã調å€è¬å±ã®ãããžã§ã¯ãã®åŠ¥åœæ§ãæ€èšŒãã¡ãã¬ãŒãåãçµãå»çãã©ãããã©ãŒã äºæ¥(â»)ã«ããããã«èª¿å€è¬å±ãããžã§ã¯ããå ããããšã«ããä»ã®ãããã¯ããšã®ãã©ã³ã¹ãèæ
®ããªãããã©ã³ãããŒãã³ã°æ€èšãè¡ã£ãŠãã£ãã â») å»çãã©ãããã©ãŒã äºæ¥ã§ã¯ãæ£è
ãšå»çé åã®æ¥åã·ã¹ãã ã SaaS ãããã¯ãã§ã€ãªããæ£è
ãšå»çæ©é¢åæ¹ã«ãšã£ãŠããã¯ãããžãŒã®æ©æµãåããããšã®ã§ãããã©ãããã©ãŒã ã¥ãããè¡ã£ãŠãããäž»èŠãµãŒãã¹ã¯ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãCLINICSãããªã³ã©ã€ã³èšºçã»æè¬æå°ã¢ããªãCLINICSãã ã¡ãã¬ãŒã®ãããŸã§ã®æŽå²ãæ¯ãè¿ããšããããã¯ãå
容ãæç¢ºãã€ç«¯çã«è¡šããããŒãã³ã°ãå€ããã¡ãã¬ãŒããã = ãäžå€®çªç ŽãªããŒãã³ã°ããšããããšãå®çŸ©ããããŒãã³ã°ãæ€èšããŠãã£ãã æçµçã«èª¿å€è¬å±ã衚ããPharmaciesïŒãã¡ãŒãã·ãŒãºïŒããšãPharmsïŒãã¡ãŒã ã¹ïŒãã® 2 æ¡ã«çµèŸŒã¿ãããããã®ã¡ãªããã»ãã¡ãªãããæŽçããŠãã£ãã åœæã瀟å
ã§ã¯èª¿å€è¬å±ã·ã¹ãã = Pharmacies ãšåŒã°ããŠããããã®äžå€®çªç ŽãªããŒãã³ã°ãææååè£ã§ãã£ããäžæ¹ã§ããã©ã³ãã§äœçŸãã¹ãã¢ã€ãã³ãã£ãã£ã®æ¬ åŠããåŒã³ã¥ãããªã©ã課é¡ãšããŠæ£èŠããããããã«ã¯å»çãã©ãããã©ãŒã å
šäœãèŠæ®ãããã©ã³ãæ§ç¯ãšãã芳ç¹ããèæ
®ãããšããã©ã³ã¹é¢ã§ã®èª²é¡ãæµ®ã圫ãã«ãªããããã課é¡ãã¯ãªã¢ã«ããŠèªçããã®ã PharmsïŒãã¡ãŒã ã¹ïŒã§ããã ãŽã£ãžã¥ã¢ã«ã»ã¢ã€ãã³ãã£ãã£ã®èšèš ãã©ã³ãåãåºãŸãã°ãããšã¯ãŽã£ãžã¥ã¢ã«ã»ã¢ã€ãã³ãã£ãã£ãçªãè©°ããŠããã®ã¿ãèŠèªæ§ãå¯èªæ§ãèæ
®ãããã©ã³ããã§ã€ã¹ã®æ€èšŒã調å€è¬å±ãšæ³èµ·ããããã©ã³ãã«ã©ãŒã®éžå®ããŸãã·ã³ãã«ã®èšèšãªã©ã«åãæãã£ãŠããã ãã©ã³ãã«ã©ãŒã®éžå®ã«ãããŠã¯ããªããšãªããç·ããšããã€ã¡ãŒãžãããŒã å
ã§ããã£ããããã粟緻åãããããè¬ã®èµ·æºã調å€è¬å±æ¬æ¥ã®åœ¹å²ãèžãŸã詳现ã«èœãšã蟌ãã§ãã£ãã ããŽã«ã·ã³ãã«ãå«ããããå«ããªãããæ€èšã®ã²ãšã€ã§ãã£ãããå»çãã©ãããã©ãŒã äºæ¥ã«ãã CLINICS ã®ããŽãã·ã³ãã«ããŒã¯ä»ãã§ãããããå»çãã©ãããã©ãŒã ã«é¢é£ãããããã¯ã = ã·ã³ãã«ãå®çŸ©ãããšããã«ãŒã«ãçå®ãã·ã³ãã«ãèšèšãã·ã³ãã«ã¯è¬ã®æ§é åŒã«å©çšããããããã«ã æ§é ããã¢ããŒããšãããã©ã³ãã«ã©ãŒãšåãããŠè©³çްã«äœã蟌ãã§ãã£ãã ãŸããPharms ã®è£œå玹ä»çšã©ã³ãã£ã³ã°ããŒãžããããã¯ããã¶ã€ã³ã®ã¢ãã¯ã¢ãããäœæããããŽãšã®ãã©ã³ã¹ãªã©ãèæ
®ããªãã調æŽãè¡ã£ãŠãã£ãã æçµçã«ãæ£è
ã»èª¿å€è¬å±ã»å»çæ©é¢ã® 3 è
ã®ã€ãªãããäžè§åœ¢ã§è¡šçŸãã€ã€ãäžå¿ãå
è¿°ãããããã«ã æ§é ããã¢ããŒããšãã圢ç¶ãšãPharms ã®é æåãPããã«ãã»ã«ãšé å€ã§è¡šçŸããŠã調å€è¬å±ã·ã¹ãã ãšããŠã·ã³ãã«ããŒã¯ã«åœãå¹ã蟌ãã ã ãŸãšã ãã®ãããªéçšãçµãŠãPharms ã®ãã©ã³ãã宿ããã®ã ãããããã¯èª¿å€è¬å±ã·ã¹ãã ã®éçºãšããŠã¯æ°·å±±ã®äžè§ã§ãããªããæ¬äžžã¯ãããã¯ããã¶ã€ã³ãäžè¬çã«ã¯ããŽãšãããã¯ããã¶ã€ã³ã¯å¥ãããžã§ã¯ãã§é²è¡ããããæ
åœãããã¶ã€ããŒãå¥ã ã£ããããããšãå€ãã®ã§ã¯ãªãã ãããã Pharms ã¯ãã©ã³ãèšèšããããã¯ããã¶ã€ã³ãããŒã±ãã£ã³ã°è³æãšãã£ããã¶ã€ã³é åããã¹ãŠç§ãæ
åœããŠããããšã«ãªãã®ã ããããæ
ã«äºæ¥å
šäœã俯ç°ãçè§£ããªãããã¶ã€ã³ã UI ãã¶ã€ã³ã«éã蟌ããŠæºããããšãã§ããããã¶ã€ããŒãã£ãªã¢ãšããŠããããŸã§å¹
åºãæºãããããšã¯éåžžã«è²ŽéãªçµéšãåŸãããšãã§ãããšèªè² ããŠããã ç¶ããŠãããã¯ããã¶ã€ã³éçºã®ç§è©±ã«ã€ããŠèªããããšããã ããçŸåš Pharms 以å€ã®å»çãã©ãããã©ãŒã äºæ¥ã«é¢é£ããæ°ããªãããã¯ãéçºã«æ³šåããŠããããããã®è©±ã¯ãŸãã®æ©äŒã«ã å»çãã©ãããã©ãŒã äºæ¥ã«é¢é£ãããããã¯ãããããããåµåºãæé·ãããŠããé¢çœãææã«ãããçŸåšãã¶ã€ããŒãç©æ¥µæ¡çšäžã§ããã«ãžã¥ã¢ã«ã«è©±ãèããããå»çé åã®ãã¶ã€ã³ã«èå³ããããšãã£ããã¶ã€ããŒã®æ¹ã¯ããã² ãã¡ã ãŸã§ãé£çµ¡ããã ãããšå¹žãã§ãã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã2020 幎 9 æã«èª¿å€è¬å±åãã®ãããã¯ãããªãªãŒã¹ããã ãã® ãã¬ã¹ãªãªãŒã¹ ãçºè¡šãããã®ã¯ãCOVID-19 ã®æææ¡å€§ã«ç«¯ãçºããç·æ¥äºæ
宣èšãçºä»€ãããŠãã 2020 幎 4 æåã°ããã® 1 ã¶æåŸãç§ã¯ãªã¢ãŒãã¯ãŒã¯äžã§ã®ãªã³ã©ã€ã³ MTG ã«ãªãããªãç¶æ
ã®ãŸãŸã調å€è¬å±åããããã¯ãã®ãã©ã³ãã£ã³ã°ã«ã€ããŠåœ¹å¡é£ãäž»èŠãããžã§ã¯ãã¡ã³ããŒã«ãã¬ãŒã³ãè¡ã£ãŠããã ä»åã¯åœæã®ãã¬ãŒã³è³æããã©ããªãã Pharms ã®ãã©ã³ãèšèšã«ã€ããŠèª¬æããŠããããšæãã å»è¬åæ¥ã®ã«ãŒããšã¯ ãã¶ã€ããŒãšããŠåç°ãã¡ãã¬ãŒã«å
¥ç€ŸããŠããããªã³ã©ã€ã³èšºçãé»åã«ã«ããªã©ãäž»ã«å»çæ©é¢åãã®ãããã¯ããã¶ã€ã³ãæ
åœããŠãããã®ã®ã調å€è¬å±ã®ãããã¯ããã¶ã€ã³ã¯æªç¥ã®é åããã©ã³ãã£ã³ã°ãæ€èšããäžã§ãè¬ã®åŠæ¹ãè¡ãå»åž«ãšèª¿å€ã宿œããè¬å€åž«ãåæ
ããŠè¡ãå»è¬åæ¥ã®ã«ãŒãã€ããŠèª¿ã¹ãããšããã¯ãããã å»è¬åæ¥ã¯ãæ¯æ®ºãæããããªãŒããªã 2 äžã䞻治å»ã®åŠæ¹ããè¬ããæ¯ãçãããŠãªããä»è
ã«ãã§ãã¯ãããã®ãå§ãŸããšãããŠããã ïŒåèïŒ å
¬çç€Ÿå£æ³äºº æ¥æ¬è¬å€åž«äŒ HP ïœå»è¬åæ¥ãšã¯ ïŒ å»çãã©ãããã©ãŒã ã®æªæ¥ãèŠæ®ãããã©ã³ãå®çŸ© 次ã«ã調å€ã«é¢ããæ³å¶åºŠãç«¶åãªã©ã®å€éšèŠå ãã¡ãã¬ãŒãšããŠã®ãã©ã³ãåãéçºåãªã©ã®å
éšèŠå ã«ã€ããŠç°¡æãª SWOT åæãè¡ãã調å€è¬å±ã®ãããžã§ã¯ãã®åŠ¥åœæ§ãæ€èšŒãã¡ãã¬ãŒãåãçµãå»çãã©ãããã©ãŒã äºæ¥(â»)ã«ããããã«èª¿å€è¬å±ãããžã§ã¯ããå ããããšã«ããä»ã®ãããã¯ããšã®ãã©ã³ã¹ãèæ
®ããªãããã©ã³ãããŒãã³ã°æ€èšãè¡ã£ãŠãã£ãã â») å»çãã©ãããã©ãŒã äºæ¥ã§ã¯ãæ£è
ãšå»çé åã®æ¥åã·ã¹ãã ã SaaS ãããã¯ãã§ã€ãªããæ£è
ãšå»çæ©é¢åæ¹ã«ãšã£ãŠããã¯ãããžãŒã®æ©æµãåããããšã®ã§ãããã©ãããã©ãŒã ã¥ãããè¡ã£ãŠãããäž»èŠãµãŒãã¹ã¯ã¯ã©ãŠãèšºçæ¯æŽã·ã¹ãã ãCLINICSãããªã³ã©ã€ã³èšºçã»æè¬æå°ã¢ããªãCLINICSãã ã¡ãã¬ãŒã®ãããŸã§ã®æŽå²ãæ¯ãè¿ããšããããã¯ãå
容ãæç¢ºãã€ç«¯çã«è¡šããããŒãã³ã°ãå€ããã¡ãã¬ãŒããã = ãäžå€®çªç ŽãªããŒãã³ã°ããšããããšãå®çŸ©ããããŒãã³ã°ãæ€èšããŠãã£ãã æçµçã«èª¿å€è¬å±ã衚ããPharmaciesïŒãã¡ãŒãã·ãŒãºïŒããšãPharmsïŒãã¡ãŒã ã¹ïŒãã® 2 æ¡ã«çµèŸŒã¿ãããããã®ã¡ãªããã»ãã¡ãªãããæŽçããŠãã£ãã åœæã瀟å
ã§ã¯èª¿å€è¬å±ã·ã¹ãã = Pharmacies ãšåŒã°ããŠããããã®äžå€®çªç ŽãªããŒãã³ã°ãææååè£ã§ãã£ããäžæ¹ã§ããã©ã³ãã§äœçŸãã¹ãã¢ã€ãã³ãã£ãã£ã®æ¬ åŠããåŒã³ã¥ãããªã©ã課é¡ãšããŠæ£èŠããããããã«ã¯å»çãã©ãããã©ãŒã å
šäœãèŠæ®ãããã©ã³ãæ§ç¯ãšãã芳ç¹ããèæ
®ãããšããã©ã³ã¹é¢ã§ã®èª²é¡ãæµ®ã圫ãã«ãªããããã課é¡ãã¯ãªã¢ã«ããŠèªçããã®ã PharmsïŒãã¡ãŒã ã¹ïŒã§ããã ãŽã£ãžã¥ã¢ã«ã»ã¢ã€ãã³ãã£ãã£ã®èšèš ãã©ã³ãåãåºãŸãã°ãããšã¯ãŽã£ãžã¥ã¢ã«ã»ã¢ã€ãã³ãã£ãã£ãçªãè©°ããŠããã®ã¿ãèŠèªæ§ãå¯èªæ§ãèæ
®ãããã©ã³ããã§ã€ã¹ã®æ€èšŒã調å€è¬å±ãšæ³èµ·ããããã©ã³ãã«ã©ãŒã®éžå®ããŸãã·ã³ãã«ã®èšèšãªã©ã«åãæãã£ãŠããã ãã©ã³ãã«ã©ãŒã®éžå®ã«ãããŠã¯ããªããšãªããç·ããšããã€ã¡ãŒãžãããŒã å
ã§ããã£ããããã粟緻åãããããè¬ã®èµ·æºã調å€è¬å±æ¬æ¥ã®åœ¹å²ãèžãŸã詳现ã«èœãšã蟌ãã§ãã£ãã ããŽã«ã·ã³ãã«ãå«ããããå«ããªãããæ€èšã®ã²ãšã€ã§ãã£ãããå»çãã©ãããã©ãŒã äºæ¥ã«ãã CLINICS ã®ããŽãã·ã³ãã«ããŒã¯ä»ãã§ãããããå»çãã©ãããã©ãŒã ã«é¢é£ãããããã¯ã = ã·ã³ãã«ãå®çŸ©ãããšããã«ãŒã«ãçå®ãã·ã³ãã«ãèšèšãã·ã³ãã«ã¯è¬ã®æ§é åŒã«å©çšããããããã«ã æ§é ããã¢ããŒããšãããã©ã³ãã«ã©ãŒãšåãããŠè©³çްã«äœã蟌ãã§ãã£ãã ãŸããPharms ã®è£œå玹ä»çšã©ã³ãã£ã³ã°ããŒãžããããã¯ããã¶ã€ã³ã®ã¢ãã¯ã¢ãããäœæããããŽãšã®ãã©ã³ã¹ãªã©ãèæ
®ããªãã調æŽãè¡ã£ãŠãã£ãã æçµçã«ãæ£è
ã»èª¿å€è¬å±ã»å»çæ©é¢ã® 3 è
ã®ã€ãªãããäžè§åœ¢ã§è¡šçŸãã€ã€ãäžå¿ãå
è¿°ãããããã«ã æ§é ããã¢ããŒããšãã圢ç¶ãšãPharms ã®é æåãPããã«ãã»ã«ãšé å€ã§è¡šçŸããŠã調å€è¬å±ã·ã¹ãã ãšããŠã·ã³ãã«ããŒã¯ã«åœãå¹ã蟌ãã ã ãŸãšã ãã®ãããªéçšãçµãŠãPharms ã®ãã©ã³ãã宿ããã®ã ãããããã¯èª¿å€è¬å±ã·ã¹ãã ã®éçºãšããŠã¯æ°·å±±ã®äžè§ã§ãããªããæ¬äžžã¯ãããã¯ããã¶ã€ã³ãäžè¬çã«ã¯ããŽãšãããã¯ããã¶ã€ã³ã¯å¥ãããžã§ã¯ãã§é²è¡ããããæ
åœãããã¶ã€ããŒãå¥ã ã£ããããããšãå€ãã®ã§ã¯ãªãã ãããã Pharms ã¯ãã©ã³ãèšèšããããã¯ããã¶ã€ã³ãããŒã±ãã£ã³ã°è³æãšãã£ããã¶ã€ã³é åããã¹ãŠç§ãæ
åœããŠããããšã«ãªãã®ã ããããæ
ã«äºæ¥å
šäœã俯ç°ãçè§£ããªãããã¶ã€ã³ã UI ãã¶ã€ã³ã«éã蟌ããŠæºããããšãã§ããããã¶ã€ããŒãã£ãªã¢ãšããŠããããŸã§å¹
åºãæºãããããšã¯éåžžã«è²ŽéãªçµéšãåŸãããšãã§ãããšèªè² ããŠããã ç¶ããŠãããã¯ããã¶ã€ã³éçºã®ç§è©±ã«ã€ããŠèªããããšããã ããçŸåš Pharms 以å€ã®å»çãã©ãããã©ãŒã äºæ¥ã«é¢é£ããæ°ããªãããã¯ãéçºã«æ³šåããŠããããããã®è©±ã¯ãŸãã®æ©äŒã«ã å»çãã©ãããã©ãŒã äºæ¥ã«é¢é£ãããããã¯ãããããããåµåºãæé·ãããŠããé¢çœãææã«ãããçŸåšãã¶ã€ããŒãç©æ¥µæ¡çšäžã§ããã«ãžã¥ã¢ã«ã«è©±ãèããããå»çé åã®ãã¶ã€ã³ã«èå³ããããšãã£ããã¶ã€ããŒã®æ¹ã¯ããã² ãã¡ã ãŸã§ãé£çµ¡ããã ãããšå¹žãã§ãã https://www.medley.jp/jobs/designer-new.html