Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Go + Google Cloud Functions を使ったSlackのThreadにも対...
Search
ktykogm
July 25, 2019
Programming
550
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Go + Google Cloud Functions を使ったSlackのThreadにも対応したbotを簡単に作る方法
Slack Dev Meetup Tokyo #1 LT 資料です。
ktykogm
July 25, 2019
More Decks by ktykogm
See All by ktykogm
AIと新時代を切り拓く。これからのSREとメルカリIBISの挑戦
0gm
3
6.9k
ハイブリッドAIOps・AI Agent戦略:SaaS AI時代のプラットフォームエンジニアリング生存戦略
0gm
1
1.9k
メルカリIBISの紹介
0gm
2
3k
メルカリIBIS:AIが拓く次世代インシデント対応
0gm
2
1.9k
街じゅうを"駅前化"する電動マイクロモビリティのシェアサービス「LUUP」のIoTとSRE
0gm
1
11k
サービスと組織の拡大を支えるEmbedded SREs
0gm
7
3.8k
SRE的team開発Tipsとベストプラクティスっぽい何か
0gm
9
5.9k
Other Decks in Programming
See All in Programming
オーケストレーション記述言語 Katari
yukikurage
0
220
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Kaigi on Rails 2026, Tokyo, Japan
marcoroth
2
410
Modernizing iOS Apps
seyfoyun
0
150
PyConTW 2026 - AI Coding 不只是工具升級, 區域醫院醫療資訊系統協作開發與資訊團隊轉型實踐
cclai999
0
230
Zero-Tap Sign-In対応、結局何をすればいいの?
mitohato14
0
1.5k
Apple Intelligenceとオンデバイス時代の到来
yahir0
0
200
baseline으로 마이그레이션, 리팩토링 안전하게 맡기기
fornewid
1
880
自作Discord音声botをLambda MicroVMsに移行した話 / Migrating My Discord Voice Bot to Lambda MicroVMs
akihisaikeda
1
290
あなたの await、OS まで届いてる? strace で覗く JavaScript の非同期
hasutosasaki
1
2.1k
Python Lambdaにおけるテストしやすい設計とAI支援の活用 / Designing Testable Python Lambda Functions with AI
kitano_yuichi
1
290
Groovy as a human and AI friendly programming language
paulk
0
180
Performance Optimization With LLMs
xleitix
0
240
Featured
See All Featured
The untapped power of vector embeddings
frankvandijk
2
2k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
30 Presentation Tips
portentint
PRO
1
460
Raft: Consensus for Rubyists
vanstee
143
7.8k
Rails Girls Zürich Keynote
gr2m
96
14k
Thoughts on Productivity
jonyablonski
76
5.4k
BBQ
matthewcrist
90
10k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
2
2.1k
Large-scale JavaScript Application Architecture
addyosmani
516
110k
Speed Design
sergeychernyshev
33
2.2k
Mobile First: as difficult as doing things right
swwweet
225
10k
Design in an AI World
tapps
1
380
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
͝੩ௌ͋Γ͕ͱ͏͍͟͝·͠ ͨɻ