Перейти до вмісту

APK sources

Slack

Copy APKs posted in Slack channels, threads and forwards into a source with holtdroid-slack-sync.

Цей контент ще не доступний вашою мовою.

Holtdroid doesn’t talk to Slack itself. holtdroid-slack-sync is a separate, stateless job that polls channels and writes every .apk it finds, with a .meta.json sidecar, into a folder or S3 prefix that the api lists as a read-only source.

It picks up APKs:

  • attached to channel messages;
  • in thread replies;
  • inside forwarded messages.

Optionally it announces new builds the same way as the other sync jobs: one message per pass through shoutrrr (Slack, Telegram, Discord, Matrix, ntfy, email, webhooks, …). The message lists each build’s name, version, package and size, a link to the Slack message, and two launch links:

  • Quick launch starts a device right away with the user’s last provider and location;
  • Launch opens the launch dialog.

The quickest way is to create it from the manifest:

  1. Open https://api.slack.com/apps → Create New App → From a manifest, and pick the workspace.
  2. Paste the manifest below, then click Create → Install to Workspace.
  3. Copy the Bot User OAuth Token (xoxb-…) from OAuth & Permissions.
slack-app-manifest.yaml
display_information:
name: Holtdroid
description: Copies APKs posted here into Holtdroid and announces them with launch links.
background_color: "#8a5a3c"
features:
bot_user:
display_name: Holtdroid
always_online: false
oauth_config:
scopes:
bot:
- channels:history
- groups:history
- files:read
- users:read
- chat:write
settings:
org_deploy_enabled: false
socket_mode_enabled: false
token_rotation_enabled: false
Scope Needed for
channels:history, groups:history reading public / private channels
files:read downloading the APKs
users:read uploader names (optional; without it you see user IDs)
chat:write announcements into Slack (optional)

Manifests can’t set the app icon, so upload it under Basic Information if you want one, e.g. assets/holtdroid-icon.png.

Then invite the bot to every channel: /invite @Holtdroid. Channels are configured by ID, e.g. C0123ABCD: open the channel details and find the ID at the bottom of About.

The chart is in the sync repository (deploy/helm/holtdroid-sync, and oci://ghcr.io/holtdroid/charts/holtdroid-sync for tagged releases); job picks the Slack sync:

job: slack
existingSecret: holtdroid-slack-sync # SLACK_BOT_TOKEN, S3_ACCESS_KEY, S3_SECRET_KEY, NOTIFY_URL
config:
slack:
token: env:SLACK_BOT_TOKEN
channels: [C0123ABCD]
target:
type: s3
s3:
endpoint: https://s3.example.com
region: us-east-1
bucket: holtdroid
prefix: slack
accessKey: env:S3_ACCESS_KEY
secretKey: env:S3_SECRET_KEY
notify: # optional: announce new builds
urls: [env:NOTIFY_URL] # e.g. slack://xoxb:<bot token without xoxb->@C0123ABCD
portalURL: https://holtdroid.example.com
source: slack

To announce into the channel itself, reuse the bot token in the shoutrrr URL. Builds whose message is older than notify.maxAge (24 hours by default) aren’t announced, so the first pass over lookback stays quiet.

Every key can also come from HOLTDROID_SLACK_SYNC_* environment variables, e.g. HOLTDROID_SLACK_SYNC_SLACK__CHANNELS=C1,C2. The full reference is in the job’s docs.

Point a read-only source at the same place. Its name has to match notify.source, or the launch links open the wrong source:

sources:
- name: slack
type: s3
readOnly: true
s3:
endpoint: https://s3.example.com
region: us-east-1
bucket: holtdroid
prefix: slack
accessKey: env:S3_ACCESS_KEY
secretKey: env:S3_SECRET_KEY
{channel ID}/{file ID}/{file name}.apk
{channel ID}/{file ID}/{file name}.apk.meta.json
Sidecar field Value
changelog the message text; for a forward, the forwarder’s comment and then the original message
note, link permalink of the message in the channel
uploadedBy display name of whoever posted it (bots: the bot’s name; forwards: the original author)
uploadedAt message time (forwards: the original message’s time)
title the Slack file title, if it differs from the file name
origin slack

It also writes {file name}.apk.icon.png, the launcher icon re-rendered at 256 px, when one can be extracted.

Each pass reads the history of the last lookback (7 days by default) and lists the source. Only files the source doesn’t have yet get downloaded, so a restart loses nothing and does no extra work. A thread is fetched again only when it has a new reply. Edits to a top-level message rewrite its sidecar; the APK isn’t downloaded again.

Polling has these limits:

  • replies to threads whose parent is older than lookback are missed;
  • edits to thread replies that are already synced show up only after the thread gets another reply.