LoginSignup
19

More than 5 years have passed since last update.

iOSアプリの新規レビューを通知してくれるSlack Button Appを作った~手順と申請手続き

Last updated at Posted at 2016-01-29

2015年12月にSlackがApp Directoryを公開しました。今までもコミュニティによるIntegrationの一覧などのページがありましたが、より本格的にサードパーティーの開発を促すためなのか、Slack対応アプリを作って公開するまでの手順が整備されています。

以前に、GAE/GoでAppStoreのレビューをSlackに通知してくれるやつというのを作ってましたが、これを作りなおして、slack button app 対応してみましたので、その手順を紹介します。

ちなみにアプリそのものはこちらです。

Bell Apps AppStore Review Notification for Slack
https://bell-apps.appspot.com/

Bell_Apps 2.png

iOSアプリ開発者でSlackをチームで使っている人は、ぜひご利用ください。無料です。

アプリの登録

まずはアプリの登録が必要です。

https://slack.com/apps にアクセスして、「build your own」のところをクリックします。

App_Directory___Slack.png

その後のページで、Get Started with Slack Appsのほうを選択します。

Build_Your_Own___Slack.png

その後のページの中ごろにあるCreate your Slack appをクリックします。
Getting_started_with_Slack_apps___Slack.png

自分のアプリに関する情報を埋めたら、完了です。

Slack_API__New_Application___Slack.png

完了するとClientIDとSecretがもらえますので、それをアプリケーションで使います。

Slack_API__Edit_Application___Slack.png

アプリを作る

Slack Button のコードを取得

Slack Button Appの説明ページに行きます。
https://api.slack.com/docs/slack-button

するとページ中ごろに、コピペ用のコードが用意されています。なので、このコードをコピーして、自分の紹介サイトの中に貼るだけです。

Slack_Button___Slack.png

OAuth認証

このボタンをクリックすると、OAuth認証が始まります。Slack側での処理がほとんどです。

終わると、登録しておいたリダイレクトページもしくは、redirect_uriのパラメータで指定しておいたページに戻ってきます。

この時に、code というGETパラメータが付いてきますので、それとClientID,Secretを使って最終的に、imcoming webhook のURLやアクセストークンなどを取得します。

今回はGoogleAppEngine/Go(GAE/Go)で作りましたので、処理は以下のようになっています。


const clientId = "xxx"
const clientSecret = "xxxx"

func basicAuth() string {
    // 文字列をbyte配列にしてbase64にする
    data := clientId +":"+clientSecret
    sEnc := base64.StdEncoding.EncodeToString([]byte(data))
    return sEnc
}

client := urlfetch.Client(ctx)
code := r.URL.Query().Get("code")
req, err := http.NewRequest("GET", "https://slack.com/api/oauth.access?code="+code, nil)
if err != nil {
    ren.JSON(w, http.StatusBadRequest, map[string]interface{}{"message": "cannnot make http request"})
    return
}
req.Header.Add("Authorization", "Basic "+basicAuth())
resp, err := client.Do(req)
if err != nil {
    ren.JSON(w, http.StatusInternalServerError, map[string]interface{}{"message": "failed to get response from Oauth2 request"})
    return
}

エラーでも200のステータスコード

ここでプチはまりしたのが、Slackでアクセストークンを要求するAPIがエラーでも400系のエラーを返さず、200を返すようになっていたことです。

間違ったcodeパラメータの値を送ると例えば以下のように返ってきます。


http -f GET https://slack.com/api/oauth.access?code=aaa.bbb Authorization:"Basic xxxxxxxx"

return:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 35
Content-Security-Policy: referrer no-referrer;
Content-Type: application/json; charset=utf-8
Date: Tue, 29 Dec 2015 13:52:18 GMT
Server: Apache
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-XSS-Protection: 0

{
"error": "invalid_code",
"ok": false
}

Slackに問い合わせると、サポートの人も400系であるべきと認めてましたが、すぐには変えられないとの返事。仕方ないので、errorというプロパティの中身が何らかあれば、エラーとすることにしました。


// IncomingWebhook is a child element of oauth2 response
type IncomingWebhook struct {
    URL              string `json:"url"`
    Channel          string `json:"channel"`
    ConfigurationURL string `json:"configuration_url"`
}

// AccessToken is a struct for oauth2 response
type AccessToken struct {
    AccessToken     string          `json:"access_token"`
    Scope           string          `json:"scope"`
    TeamName        string          `json:"team_name"`
    TeamID          string          `json:"team_id"`
    IncomingWebhook IncomingWebhook `json:"incoming_webhook"`
    OK              bool            `json:"ok"`
    Error           string          `json:"error"`
}


dec := json.NewDecoder(resp.Body)
var jsonData AccessToken
dec.Decode(&jsonData)
if len(jsonData.Error) > 0 {
    ren.JSON(w, http.StatusBadRequest, map[string]interface{}{"message": "Slack API does return error:" + jsonData.Error})
    return
}

アプリ独自の設定の登録

今回のアプリは、特定のiOSアプリの特定の地域のストアのレビューを通知するものです。なので、アクセストークンやWebhookのアドレスを取得後に、該当するストアのURLを入力してもらうような仕様にしています。ここはもう、Slackというよりはアプリ側で実装を入れる話です。

Bell_Apps.png

ユーザーにこの辺の設定を完了してもらったら、SlackButtonAppのプロセスはおしまいです。

通知内容のカスタマイズ

https://api.slack.com/docs/attachments こちらのattachmentsのページがわかりやすいですが、左側に指定の色で線を付けたり、付随の情報を付けたりできます。

Slack.png

下がGoでの実装です。ドキュメントの通りの構成のJSONを作って、incoming webhookにPOSTするだけです。


var fields []map[string]interface{}
starEmoji := ""
for i := 0; i < ar.Star; i++ {
    starEmoji = starEmoji + ":star:"
}
fields = append(fields, map[string]interface{}{
    "title": "Star:",
    "value": starEmoji,
    "short": false,
})
fields = append(fields, map[string]interface{}{
    "title": "Meta:",
    "value": ar.Version,
    "short": false,
})
var attachments []map[string]interface{}
attachments = append(attachments, map[string]interface{}{
    "fallback": text,
    "pretext":  rn.Title,
    "color":    "#8EFCD3",
    "title":    ar.Title,
    "text":     ar.Content + "\n",
    "fields":   fields,
})
payload := map[string]interface{}{"attachments": attachments, "username": "Bell Apps App Review Notification", "icon_url": iconURL, "mrkdwn": false}
payloadJSON, err := json.Marshal(payload)
if err != nil {
    log.Infof(ctx, "%v", err)
    return
}
b := bytes.NewBuffer(payloadJSON)
req, _ := http.NewRequest("POST", rn.WebhookURL, b)
req.Header.Set("Content-Type", "application/json")
resp, _ := client.Do(req)
defer resp.Body.Close()
if resp.StatusCode == http.StatusNotFound {
    rn.SetUpCompleted = false
    _, err = rn.Update(ctx)
}

ユーザーが連携を無効にしたら

上のコードの最後の部分ですが、ユーザーがincoming webhookの設定を無効にした場合、404が返ってくることになっています。

404が返ってきたら通知ができないので、次から通知しようとしないようにフラグを立てて置きます。

App Directoryへ申請する

https://api.slack.com/slack-apps#directory こちらのページから申請が可能です。

Banners_and_Alerts_and_Getting_started_with_Slack_apps___Slack.png

けっこう入力項目がありますが、中でもハードル高いなと思ったのは、privacy policyへのリンクが必要なことです。

今回は以前にたまたま英文で書いていたやつがあったので、多少修正して、使いました。

一通り入力し終わって、submitしてあとは審査を待つという状態ですが、2週間経っても公開にはいたってません。サポートの人とは色々やり取りしてるんですが、個人が作ったようなのは審査厳しめなのかなあ。

2016/03/04追記

サポートの人といろいろやり取りして、ちょいちょい修正を加えた結果、審査通りました。

課題

下のキャプチャの通りなのですが、1つのchannelに対して複数のアプリのレビュー通知を有効にすると、いったいどのアプリの通知の設定なのかまったくわかりません。これも何らかタイトル付けられないか、サポートに問い合わせたんですが、無理そうでした。

Configure_Bell_Apps_App_Review_Notification___SlackTools_Slack.png

Slackのサポートの反応が早い

審査はずっと待たされているので、残念なのですが、Slackのサポートはすごいレスポンスがいいのは助かります。技術的な質問すると土日でも、メールが返ってくるので、けっこうコストかけて体制作ってるんだなと思いました。ただし、すべて英文でやり取りする必要はありますが。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19