"devDependencies": {
"@google-cloud/functions-emulator": "^1.0.0-beta.6",
"@types/follow-redirects": "^1.8.0",
"@types/node": "^13.7.1",
"ts-node-dev": "^1.0.0-pre.44",
"typescript": "^3.7.5"
},
"dependencies": {
"follow-redirects": "^1.10.0"
}
export async function post(req: any, res: any) {
const body = req.body;
const payload = JSON.parse(body.payload || "{}");
// Home タブの構築
if (
body.type === "event_callback" &&
body.event.type === "app_home_opened" &&
body.event.tab === "home"
) {
const {
body: { playlists, userIds }
} = JSON.parse(await getMetadata());
await buildHome(body.event.user, playlists, userIds);
res.status(200).send(body.challenge);
}
}
export async function post(req: any, res: any) {
const body = req.body;
const payload = JSON.parse(body.payload || "{}");
// チャンネル登録・登録解除
else if (
payload.type === "block_actions" &&
(payload.actions?.[0]?.text?.text === "チャンネル登録" ||
payload.actions?.[0]?.text?.text === "登録済み")
) {
await toggleChannelSubscription(payload.user.id);
res.status(200).send("");
const {
body: { playlists, userIds }
} = JSON.parse(await getMetadata());
await buildHome(payload.user.id, playlists, userIds);
console.log("built.");
}
}
async function buildHome(userId: string, playlists: any[], userIds: string[]) {
const host = "slack.com";
const path = "/api/views.publish";
const headers = {
"Content-type": "application/json",
Authorization:
"Bearer xoxb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
};
const playlistsBlock = playlists.map((e: any) => {/* GAS のデータを加工 */});
const json = {/* block を構築 */};
const options = { host, path, method: "POST", headers };
return new Promise((resolve, reject) => {
const req = request(options, (res) => resolve(res.statusCode));
req.on("error", (e) => reject(e.message));
req.end(JSON.stringify(json));
});
}
export async function post(req: any, res: any) {
const body = req.body;
const payload = JSON.parse(body.payload || "{}");
// プッシュ通知の送信
else if (body.liveUrl) {
const {
body: { userIds }
} = JSON.parse(await getMetadata());
await pushNotification(body.liveUrl, userIds);
res.status(200).send("");
}
}
async function pushNotification(liveUrl: string, userIds: string[]) {
const host = "slack.com";
const path = "/api/chat.postMessage";
const headers = {
"Content-type": "application/json",
Authorization:
"Bearer xoxb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
};
const options = { host, path, method: "POST", headers };
const promises = userIds.map((u) => { /* GAS のデータを加工 */ };
return new Promise((resolve, reject) => {
const req = request(options, (res) => resolve(res.statusCode));
req.on("error", (e) => reject(e.message));
req.end(JSON.stringify(json));
});
});
return Promise.all(promises);
}
export async function post(req: any, res: any) {
const body = req.body;
const payload = JSON.parse(body.payload || "{}");
// それ以外の場合は適当にレスポンスを返す
else {
res.status(200).send(body.challenge);
}
}
Block Kit Builder の App Home Preview のテンプレートで
要素同士の隙間を開けるために画像を使ってるらしい
{
"type": "context",
"elements": [
{
"type": "image",
"image_url": "https://api.slack.com/img/blocks/bkb_template_images/placeholder.png",
"alt_text": "placeholder"
}
]
}