Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Go + Google Cloud Functions を使ったSlackのThreadにも対応したbotを簡単に作る方法
Search
ktykogm
July 25, 2019
Programming
0
380
Go + Google Cloud Functions を使ったSlackのThreadにも対応したbotを簡単に作る方法
Slack Dev Meetup Tokyo #1 LT 資料です。
ktykogm
July 25, 2019
Tweet
Share
More Decks by ktykogm
See All by ktykogm
街じゅうを"駅前化"する電動マイクロモビリティのシェアサービス「LUUP」のIoTとSRE
0gm
2
9.8k
サービスと組織の拡大を支えるEmbedded SREs
0gm
7
3.2k
SRE的team開発Tipsとベストプラクティスっぽい何か
0gm
9
5k
Other Decks in Programming
See All in Programming
GitHub Copilotのススメ
marcy731
1
190
R言語の環境構築と基礎 Tokyo.R 112
bob3bob3
0
260
Code Reviews
bkuhlmann
4
890
Changed Rules: Architectures with Lightweight Stores
manfredsteyer
PRO
0
240
try! Swift Tokyo 初参加報告LT
hinakko2
0
220
Folding Cheat Sheet #3
philipschwarz
PRO
0
120
PHPの次期バージョンはこの時期どうなっているのか - Internalsの開発体制について - PHPカンファレンス小田原
youkidearitai
PRO
1
190
Netty Chicago Java User Group 2024-04-17
sullis
0
170
Komplexe Oberflächen mit SVG und der Web Animation API
joergneumann
0
670
二郎系ラーメンのコールで学ぶ AST 解析
memory1994
PRO
7
1.7k
ScalarDBを用いたマイクロサービスにおけるデータ管理 (Database Engineering Meetup #2)
scalar
0
110
Ruby Function Composition
bkuhlmann
1
330
Featured
See All Featured
Agile that works and the tools we love
rasmusluckow
325
20k
A Modern Web Designer's Workflow
chriscoyier
689
190k
The Cult of Friendly URLs
andyhume
74
5.7k
Documentation Writing (for coders)
carmenintech
60
3.9k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
322
20k
Fontdeck: Realign not Redesign
paulrobertlloyd
76
4.9k
How GitHub Uses GitHub to Build GitHub
holman
468
290k
Docker and Python
trallard
34
2.7k
VelocityConf: Rendering Performance Case Studies
addyosmani
320
23k
Fireside Chat
paigeccino
21
2.6k
The Power of CSS Pseudo Elements
geoffreycrofte
60
5k
Design by the Numbers
sachag
274
18k
Transcript
(P (PPHMF$MPVE'VODUJPOTΛͬ ͨ4MBDLͷUISFBEʹରԠͨ͠CPUΛ؆ ୯ʹ࡞Δํ๏ λΠτϧ͕͗ͨ͢LUZLPHN 4MBDL%FW.FFUVQ5PLZP-5ࢿྉ
XIPBNJ w !LUZLPHN LPHVNB w ϝϧΧϦ43& w ࠷ۙ(PΛۀͰͨ·ʹॻ͍͍ͯΔϨϕϧ w
ʮ4MBDL (PͳΒͦͷ͘Β͍؆୯ʹԼ४උͰ͖ΔΑʯͱ͍͏͜ͱΛ ͑ʹདྷ·ͨ͠ w 43&-PVOHFͱ͍͏ίϛϡχςΟͷӡӦ׆ಈΛ͍ͯ͠·͢ɻ
ຊ͍͑ͨ͜ͱ w 4MBDL (P $MPVE'VODUJPOTͷ૬ੑ w (PΛͬͨ4MBDLͷ5ISFBEରԠํ๏ w (Pք۾ͰΑ͘ΒΕͨOMPQFTTMBDL͕DPPPPPPPPM w
ͦΕΒ#PU ͦΕҎ֎ ࡞ɺαʔόͱӡ༻අΛ༻ҙͤͣʹؾָʹ࢝Ί ΒΕΔ
$MPVE'VODUJPOTͱ w ΠϕϯτυϦϒϯͳαʔόϨείϯϐϡʔτϓϥοτ ϑΥʔϜ w (BUFXBZແͯ͘ಈ͘ w &YUFOTJCMF4FSWJDF1SPYZ &41 Λͬͯ(BUFXBZ
FOEQPJOUߏͪΖΜͰ͖·͢ɻ w ͦͷ··ؔΛઃஔͰ͖Δ HPCVJMEෆཁ w ࣗಈతʹεέʔϧͭɺ)" w ଞͷ($1αʔϏεʹଓ֦ͯ͠ு͕Մೳ w ແྉ͕ଘࡏ͢Δ w ݄ؒͰɺສݺͼग़͠ ສඵ (#ԼΓτϥ ϑΟοΫ ݄ʹ(PSVUJNF͕CFUBSFMFBTF IUUQTDMPVEHPPHMFDPNGVODUJPOT
$MPVE'VODUJPOT ଞͷ($1αʔϏεʹଓ֦ͯ͠ு͕Մೳ w $MPVE1VC4VC w $MPVE4UPSBHF w )551 w 4UBDLESJWFS-PHHJOH
w 'JSFCBTF w $MPVE42- $POOFDU71$ FUD
ࣄલ४උ w 4MBDLͷ༻ҙ w (PPHMF$MPVE1MBUGPSN ($1 ͷΞΧϯτΛ࡞ w HDMPVEίϚϯυ͕͑ΔΑ͏ʹ(PPHMF$MPVE4%,Λ*OTUBMM w
IUUQTDMPVEHPPHMFDPNTELJOTUBMM w HDMPVEݱࡏ1ZUIPO͕ඞཁͳͷͰɺQZFOWͰXPSLJOH EJSFDUPSZʹQZFOWMPDBMYͰཧ͢Δͱྑ͍Ͱ͢
ࠓճͷߏͱڥʹ͍ͭͯ w ࠓճ-5ͳͷͰλΠτϧʹ͋Δ4MBDL5ISFBEʹରԠͨ͠#PUΛ࡞͢Δ ํ๏ͱͦͷઆ໌͚ͩʹ༰Λ΄΅ߜΓ·͢ w 4MBDLࣗମ4MBTI$PNNBOE#PUͷNFOUJPOʹΑΔԠͳͲ༷ʑ ͳํͰରԠͰ͖·͢ w 4MBDLͷ35."1*Λ༻ w
(PͷOMPQFTTMBDLNPEVMFΛ༻
࠷খ$PEF package gcf_slack_sample import ( "net/http" "os" "strings" "github.com/nlopes/slack" )
var ( threadTs slack.RTMsgOption ) type SlackParams struct { accessToken string botUserID string rtm *slack.RTM } func PostMessage(w http.ResponseWriter, r *http.Request) { // Ҿ০ΓɻCloud Functionͷhttp trigger Ͱඞཁ params := SlackParams{ accessToken: os.Getenv("ACCESS_TOKEN"), botUserID: "", } api := slack.New(params.accessToken) params.rtm = api.NewRTM() go params.rtm.ManageConnection() go func() { for msg := range params.rtm.IncomingEvents { switch ev := msg.Data.(type) { case *slack.ConnectedEvent: params.botUserID = ev.Info.User.ID case *slack.MessageEvent: if !strings.Contains(ev.Msg.Text, params.botUserID) { continue } threadTs = slack.RTMsgOptionTS(ev.ThreadTimestamp) params.rtm.SendMessage(params.rtm.NewOutgoingMessage("Sample TEST", ev.Channel, threadTs)) } } }() ࣮͜Ε͚ͩͰɺຊ ͷʮ4MBDLͷ5ISFBEʹ ରԠͨ͠#PUPO $MPVE'VODUJPOTΛ(P Ͱ࡞Δʯ͜ͱՄೳ WBSTZBNMߦ͚ͩ$SFEFOUJBMཧ Ͱผ్͋Γ·͢ɻޙ΄Ͳઆ໌ HPNPEVMFTͷTFUVQͷઆ໌ল͖ ·͢
தͷઆ໌
FOEQPJOUؔ w (PPHMF$MPVE'VODUJPOTͷ༷ ͰɺNBJOؔҎ֎͕ඞཁʹͳΓ· ͢ɻ w ྫͰɺ1PTU.FTTBHF w Ͳ͔͜Β։࢝͞ΕΔ͔Θ͔Γ͍͢Α
͏ʹNBJOHPGVODUJPOHPͱ͍͏ pMF໊ʹͯ͠ҎԼͷΑ͏ʹ։࢝͢Δؔ Λ࡞Γ·͢ package gcf_slack_sample // <= ࣮ԿͰok // ..<snip> func PostMessage(w http.ResponseWriter, r *http.Request) { // Ҿ০ΓɻCloud Functionͷhttp trigger Ͱඞཁ params := SlackParams{ accessToken: os.Getenv("ACCESS_TOKEN"), botUserID: "", }
4MBDLͷ5ISFBEରԠ w TMBDL35.TH0QUJPO w ͜Εޙʹઆ໌͢Δ35.TH0QUJPO54 FW5ISFBE5JNFTUBNQ ʹؔ͠ ·͢ɻ var (
threadTs slack.RTMsgOption )
4MBDLͷ5ISFBEରԠ ҎԼ͕4MBDLͷ5ISFBEͰͦͷ࣌ʹऔಘ͞ΕΔ5ISFBE5JNF4UBNQΛ࣋ͪ· ͢ ͜ͷ5ISFBE5JNF4UBNQΛར༻͢Δ͜ͱͰ#PU͕4MBDLͷ5ISFBEʹରԠ͢ ΔΑ͏ʹͳΓ·͢ threadTs = slack.RTMsgOptionTS(ev.ThreadTimestamp)
4MBDLͷ5ISFBEରԠ 35.TH0QUJPO54 FW5ISFBE5JNFTUBNQ ͱԿͳͷ͔ go func() { for msg :=
range s.rtm.IncomingEvents { switch ev := msg.Data.(type) { ͜ͷFWɺͦͷલͷ35.ͷ*ODPNJOH&WFOUT͔Β&WFOUUZQF͝ͱʹTXJUDI͠ɺͦͷ&WFOUEBUBΛFWʹೖΕ͍ͯ·͢ case *slack.MessageEvent: // .. <snip> threadTs = slack.RTMsgOptionTS(ev.ThreadTimestamp) .FTTBHF&WFOUΛड͚औͬͨλΠϛϯάͰɺͦͷૹ৴ݩͷTMBDLͷUISFBEʹରԠ͢ΔͨΊʹ ͦͷ࣌ͷ5ISFBE5JNF4UBNQΛ༻͠·͢ ͢ͳΘͪɺ͜ͷ.FTTBHF&WFOU͕࢝·ͬͨ࣌ͷ5ISFBE5JNFTUBNQ͕ೖΓ·͢ɻ
OMPQFTTMBDLଆͷྲྀΕ ϖʔδͷ্ؔɺOMPQFTTMBDLଆͷઆ໌ׂѪ͠·͕͢ྲྀΕ͚ͩॻ͘ͱҎԼͰ͢ɻ 35.TH0QUJPO54 Ͱɺ.FTTBHF&WFOUΛड͚औͬͨͱ͖ͷ5ISFBE5NFTUBNQΛૹΔ 0VUHPJOH.FTTBBHF\5ISFBE5JNFTUBNQUISFBE5JNFTUBNQ^ʹઃఆ͞ΕΔ 35.TH0QUJPOܕͰฦ͢ 1BDLBHFWBSJBCMFͰࢦఆͨ͠มUISFBE5Tɺͦͷ35.TH0QUJPOܕͱͳΔ IUUQTHJUIVCDPNOMPQFTTMBDLCMPCFBFDEFFCDEEGD
NFTTBHFTHP--
ड͚औͬͨ5ISFBE5JNF4UBNQΛ͏ s.rtm.NewOutgoingMessage() ͜ͷؔɺTMBDL35.ͰҎԼͷΑ͏ʹఆٛ͞Ε͍ͯ·͢ɻ func (rtm *RTM) NewOutgoingMessage(text string, channelID string,
options ...RTMsgOption) *OutgoingMessage { // ..<snip> return &msg 4MBDLͰ#PU͕͢.FTTBHFΛೖΕΔؔ
ड͚औͬͨ5ISFBE5JNF4UBNQΛ͏ ҎԼͰUISFBE5JNF4UBNQΛ0QUJPOͰࢦఆ͢Εྑ͍Θ͚Ͱ͢ɻ s.rtm.NewOutgoingMessage(message, ev.Channel, threadTs)
ड͚औͬͨ5ISFBE5JNF4UBNQΛ͏ s.rtm.SendMessage(s.rtm.NewOutgoingMessage(message, ev.Channel, threadTs)) ࣮ࡍʹ.FTTBHFΛૹΔͨΊʹҎԼͷΑ͏ʹ͠·͢ɻ
͜ΕΛ$MPVE'VODUJPOTʹͤ ͯ4MBDLCPUͱͯ͠ొ͢Δ
4MBDLͰઃఆ 4MBDL"QQͷ࡞ɺొ͔Βɻ wิ w֤छͷઆ໌ʹ͍ͭͯҎԼ͕Θ͔Γ͍͢Ͱ͢ wIUUQTRJJUBDPNOBNVUBLBJUFNT BDBG IUUQTBQJTMBDLDPNBQQTɹΛ։͖·͢
4MBDLͰઃఆ $SFBUF/FX"QQTΛ։ ͍ͯ࡞Λ։࢝͠·͢ ͜͜ͰUFTUCPUͱ͍͏໊ લͰొ͠·͢ %FWFMPQNFOU4MBDL 8PSLTQBDFΛબ͠·͢
4MBDLͰઃఆ #PU6TFSTΛΫϦοΫ͠ ͯɺ"EEB#PUVTFSΛΫ ϦοΫ %JTQMBZOBNFͱ%FGBVMU VTFSOBNFͰɺͲͷΑ͏ ͳจࣈͰϋΠϑϯແ͠ ʹม͞ΕΔ
ϋΠϑϯ͕ඞཁͩͬͨΒՃ͍ͯͩ͘͠͞ VTFSOBNFจࣈ·Ͱͷ੍ݶ͕͋Γ· ͢ɻ
4MBDLͰઃఆ 4DPQFTʹ DIBUXSJUFCPUΛՃ͢Δ 4BWF$IBOHFTͰอଘ ಉ͡ϖʔδͷҰ൪্ʹ͋Δ
A*OTUBMMBQQUPXPSLTQBDFAΛ ΫϦοΫͯ͠"VUIPSJ[FE͢Δɻ 0BVUI1FSNJTTJPOTઃఆ
4MBDLͰઃఆ #PU6TFS0"VUI"DDFTT5PLFOΛऔ ಘͯ͠ɺWBSTZBNMʹॻ͘ 0BVUI1FSNJTTJPOTઃఆ ACCESS_TOKEN: xoxb-XXXXXXXXXXXXXXXXXXXX WBSTZBNM HJUJHOPSFʹೖΕ͓͖ͯ·͢
(PPHMF$MPVE'VODUJPOTʹEFQMPZ HDMPVEGVODUJPOTEFQMPZUFTUCPUa FOUSZQPJOU1PTU.FTTBHFa SVOUJNFHPa FOWWBSTpMFWBSTZBNMa USJHHFSIUUQ
(PPHMF$MPVE'VODUJPOTʹEFQMPZ ͠Βͭ͘ͱEFQMPZ͕ྃ͠·͢ɻ IUUQT5SJHHFS VSMIUUQTSFHJPOQSPKFDUDMPVEGVODUJPOTOFUUFTUCPU TUBUVT"$5*7& ͷΑ͏ͳIUUQT5SJHHFS͕ൃߦ͞Ε·͢ͷͰɺ͜ΕΛΫϦοΫ͠·͢ɻ
͜Ε͚ͩͰྃͰ͢ TMBDLͷDIBOOFMʹ#PUΛ*OWJUF͠·͢ɻ
#PUΛݺͼग़͢
#PUΛݺͼग़͢ 5ISFBEʹ#PUͷ .FOUJPOΛඈ͢ͱͦͷ 5ISFBEʹରԠ͍ͯ͠· ͢ɻ ·ͨɺ5ISFBEҎ֎ʹ ͦͷDIBOOFMʹਖ਼֬ʹ #PU͕ԠΛฦ͍ͤͯ· ͢ɻ
ิ w ͪΖΜࠓճ-5Ͱઆ໌༻Ͱۃʹͨ͘͠$PEFͰ͢ w ࣮ࡍʹ͏ͱ͖ظӡ༻Λߟ͑ͯॺ໊ͳΜ͔͚ͭΔͱྑ͍ͱࢥ͍·͢ w 4JHOJOHTFDSFU
·ͱΊ w 4MBDLCPUͷԼ४උΛ(PͰ؆୯ʹग़དྷΔ w 5ISFBEରԠɺ TMBDL35.TH0QUJPO54 FW5ISFBE5JNFTUBNQ Λऔಘͯ͠͏ ͚ͩ w
4MBDLCPU (P $MPVE'VODUJPOTͷ૬ੑѱ͘ͳ͍ w ࡞Γ͍͢ ֦ுੑ͕͋Δ The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/)
࠷ޙʹ IUUQTHJUIVCDPNLPHVNBHDGMFBTUTMBDLTBNQMFGPS-5
͝੩ௌ͋Γ͕ͱ͏͍͟͝·͠ ͨɻ