こんにちは、Udesk WebIMウェブプラグインへのご利用を歓迎します。以下に基本的な使用方法、注意事項、パラメータ説明、メソッド説明、イベント説明、関連するサンプルなどを提供します。
基本的な使用方法
Udeskサポートシステムの管理者アカウントでログインし、管理センター -> チャネル管理 -> インスタントメッセージング -> ウェブプラグイン -> (特定のプラグイン)管理で基本属性を設定した後、コードをウェブページにコピーすると、Udesk IMが有効になります。
注意事項
デバイスサポート
WebIMは現在、PC/Android(タブレット含む)/iOS(タブレット含む)などのデバイスをサポートしています。
ブラウザ互換性
WebIMは現在、IE8+(以上)のIEブラウザとそのカーネルに基づくブラウザ(360/qq/...)、その他の主要ブラウザ(chrome/firefox/...)をサポートしています。
基本的なサンプル
埋め込みコードサンプル
<body>
<!-- ウェブページの内容 具体的なコードは管理者のインスタントメッセージングウェブプラグインでコピーしてください -->
<script>
(function(a,h,c,b,f,g){a["UdeskApiObject"]=f;a[f]=a[f]||function(){(a[f].d=a[f].d||[]).push(arguments)};g=h.createElement(c);g.async=1;g.src=b;c=h.getElementsByTagName(c)[0];c.parentNode.insertBefore(g,c)})(window,document,"script","https://xxx.xxxx.cn/im_client/js/udeskApi.js?1487931175918","ud");
ud({
"code": "xxxx",
"link": "https://xxx.xxxx.cn/im_client/?web_plugin_id=1",
"isInvite": true,
"mode": "inner",
"color": "#307AE8",
"pos_flag": "srb",
"language": "en-us", //言語-英語
"onlineText": "カスタマーサポートに連絡し、オンラインで相談する",
"offlineText": "サポートは退勤しました。メッセージを残してください",
"mobile": { //レスポンシブレイアウトのため、pc、mobileのカスタマイズを提供
"mode": "blank",
"color": "#307AE8",
"pos_flag": "crb",
"onlineText": "カスタマーサポートに連絡し、オンラインで相談する",
"offlineText": "サポートは退勤しました。メッセージを残してください"
}
});
</script>
</body>
リンクサンプル
https://xxx.xxxx.cn/im_client/?web_plugin_id=xx&language=zh-cn&agent_id=xxx&group_id=xxx
カスタム設定
開発者は自身のニーズに応じて関連設定をカスタマイズできます。すべての属性、イベントは
ud({...})内で設定され、すべてのメソッドはud(methodName, ...arguments)の方法で呼び出されます。
設定方法
1. ud({key: val, key2: val2, ...});
2. ud(key, val);
パラメータ説明
グローバルパラメータ
| パラメータ名 | 型 | 値 | 必須 | 説明 |
|---|---|---|---|---|
| code | String | 系统生成 |
はい | 企業の一意識別子 |
| link | String | 系统生成 |
はい | 企業IMクライアントリンクアドレス |
| isInvite | Boolean | trueまたはfalse(デフォルト) | いいえ | ビジター招待機能を有効にするか管理台可配 |
| agent_id | String | 指定されたカスタマーサポートID、デフォルトでは指定なし | いいえ | セッションの担当カスタマーサポートを指定 |
| group_id | String | 指定されたカスタマーサポートグループID、デフォルトでは指定なし | いいえ | セッションのカスタマーサポートグループを指定 |
| session_key | String | 6桁のランダム文字列 | いいえ | 同じ顧客でも、異なるsesstion_keyは新しいセッションをトリガーします。 英字、数字、アンダースコアのみサポート、特殊文字は禁止 |
| merchant_id | String | 加盟店ID | いいえ | merchant_idを渡した場合、session_key、merchant_idの両方に同じ加盟店IDを渡す必要があります。 セッションロジック:関連する加盟店パラメータを渡すと保存され、既存のセッション順序を乱さず、ロボット、事前問い合わせフォーム、メッセージなどは、人工セッション時にのみパラメータを保存して表示置換を行います |
| merchant_name | String | 加盟店名 | いいえ | このカスタマーサポートとのセッションで【カスタマーサポート紹介】が【加盟店名】に置き換えて表示されます |
| merchant_avatar | String | 加盟店アイコン | いいえ | このカスタマーサポートとのセッションで【カスタマーサポートアイコン】が【加盟店アイコン】に置き換えて表示されます |
| merchant_list | Boolean | trueまたはfalse(デフォルト) | いいえ | ウェブプラグインリンクにmerchant_list=trueがある場合、ウェブプラグインは現在の顧客の過去のセッションにおけるすべての加盟店を読み込み、各加盟店の最新のセッション時間でソートして表示します |
| mode | String | inner:ウェブページ埋め込みモード(デフォルト) blank:独立ウィンドウモード |
いいえ | ボタンでウィンドウを開く際の表示モード管理台可配 |
| color | String | ボタンカラーコード、デフォルト:#307AE8 | いいえ | IMボタンの色を設定管理台可配 |
| pos_flag | String | ボタン形状+位置 1)形状: h(横) v(縦) c(円形) i(画像); 2)位置: lt(左上) mt(中上) rt(右上) lm(左中) mm(中央) rm(右中) lb(左下) mb(中下) rb(右下) デフォルト値:crb(pc)、hrb(mobile) |
いいえ | ボタン形状+位置 例:vrb(縦右下) 画像設定パス:管理センター-チャネル管理-インスタントメッセージ-ウェブプラグイン-管理-ボタン設定 |
| onlineText | String | カスタマーサポートオンライン表示テキスト、デフォルトは「カスタマーサポートに連絡、オンライン相談」 | はい | 管理台可配 |
| offlineText | String | カスタマーサポートオフライン表示テキスト、デフォルトは「カスタマーサポートは退勤中、メッセージを残してください」 | はい | 管理台可配 |
| noBubble | Boolean | trueまたはfalse(デフォルト) | いいえ | メッセージポップアップバブル通知を表示しない |
| manualInit | Boolean | trueまたはfalse(デフォルト) | いいえ | 手動初期化、trueに設定すると、埋め込みコードは自動的に初期化されず、ud('init')メソッドを明示的に呼び出す必要があります |
| language | String | "zh-cn"(中国語)、"en-us"(英語)など | いいえ | クライアントの多言語設定[詳細] |
| channel | String | カスタムチャネル | いいえ | 管理台可配 |
| targetSelector | String | #id,.class,tagName,...をサポート默认系统生成 唯一 |
いいえ | メインターゲットボタンセレクター 1) チャットウィンドウをトリガーするため 2) 代替システムが提供するデフォルトボタンに使用、指定が有効になるとデフォルトボタンは表示されなくなります 3) 招待を受け取るため 4) 新着メッセージ通知を受け取るため 5) ... |
| selector | String | #id,.class,tagName,...をサポート デフォルトなし 可多个 |
いいえ | 補助ボタンセレクター 1) チャットウィンドウをトリガーするため |
| css | Object | ボタンカスタムスタイル、例:css:{top:10%}、デフォルトなし | いいえ | |
| window | Object | 仅独立窗口模式 独立ウィンドウのデフォルトサイズは幅780、高さ560 例 window: {"width": "780", "height": "560"} |
いいえ | 独立ウィンドウのサイズを設定 |
| panel | Object | 仅网页内嵌模式 |
いいえ | セッションパネル [詳細] |
| pop | Object | いいえ | メッセージ通知バブル [詳細] | |
| customer | Object | いいえ | 顧客情報 [詳細] | |
| im_client_valid | {v_nonce:string,v_timestamp:string,v_signature:string} | いいえ | リクエスト権限検証が有効な場合は必須 [詳細] | |
| product | Object | いいえ | 相談対象 [詳細] | |
| hide_product | Boolean | いいえ | パラメータがtrueの場合、クライアント側の相談対象の表示が非表示になりますが、カスタマーサポート側には表示されます | |
| mobile | Object | いいえ | モバイル端末関連設定 [詳細] ウェブサイトがレスポンシブレイアウトの場合、pc、mobileのカスタマイズを提供 |
|
| robot_modelKey | String | ロボットFAQテンプレートID | いいえ | ロボットFAQテンプレートIDに基づいてFAQテンプレートを呼び出し、「Km-ロボット-FAQ対話-ナレッジベース-よくある質問-ID」で確認できます |
| c_cf_dialogueDesc | String | カスタム値、カンマ区切りで複数値をサポート | いいえ | このフィールドは、顧客がロボットに任意のカスタム情報を渡すニーズを満たすためのものです。 使用方法:まず、カスタマーサポートシステムの顧客カスタムフィールド内に、c_cf_dialogueDescという名前のカスタムフィールドを設定します。顧客のこのフィールド値を設定した後、web IMウェブプラグインを開き、このフィールドをパスパラメータに追加します。形式は以下の通りです https://xxx.udesk.cn/im_client/?web_plugin_id=41597&c_cf_dialogueDesc=* これにより、システムは自動的にc_cf_dialogueDescのパラメータ値をロボットに渡し、ロボットの対話説明フィールドがこの値を受け取ります |
| uba | {app_key: string} | ユーザー行動分析設定 | いいえ | 例:ud({uba:{app_key: 'xxxxxxx'}}) |
| src_url | String | http URLアドレス | いいえ | 参照元URL |
| ### サンプル |
ud({
"code": "xxxx",
"link": "https://xxx.xxxx.cn/im_client/",
"mode": "inner",
"color": "#307AE8",
"pos_flag": "srb",
"onlineText": "カスタマーサポートに連絡、オンライン相談",
"offlineText": "サポートは終了しました、メッセージをお残しください",
"targetSelector": "#btn_udesk_im",
"selector": ".udesk_im",
"pop": {},
"panel": {},
"mobile": {},
"window": {}
});
> モバイル端末 - パラメータ説明
| パラメータ名 | タイプ | 値 | 必須かどうか | 説明 |
|---|---|---|---|---|
| mode | String | inner:ウェブページ埋め込みモード(デフォルト) blank:独立ウィンドウモード |
いいえ | ボタンで開くウィンドウの表示モード管理台可配 |
| color | String | ボタンの色コード、デフォルト:#307AE8 | いいえ | IMボタンの色を設定管理台可配 |
| pos_flag | String | ボタンの形状+位置 1)形状: h(横長) v(縦長) c(円形) i(画像); 2)位置: lt(左上) mt(中上) rt(右上) lm(左中) mm(中央) rm(右中) lb(左下) mb(中下) rb(右下) デフォルト値:crb(pc)、hrb(mobile) |
いいえ | ボタンの形状+位置 例:vrb(縦長右下角) 画像設定パス:管理センター-チャネル管理-インスタントメッセージ-ウェブプラグイン-管理-ボタン設定 |
| onlineText | String | サポートオンライン時表示テキスト、デフォルト「カスタマーサポートに連絡、オンライン相談」 | はい | 管理台可配 |
| offlineText | String | サポートオフライン時表示テキスト、デフォルト「サポートは終了しました、メッセージをお残しください」 | はい | 管理台可配 |
| noBubble | Boolean | trueまたはfalse(デフォルト) | いいえ | メッセージポップアップバブル通知を表示しない |
| language | String | "zh-cn"(中国語) または "en-us"(英語) | いいえ | クライアントの多言語設定 |
| targetSelector | String | #id,.class,tagName,...をサポート默认系统生成 唯一 |
いいえ | メインターゲットボタンセレクタ 1) チャットウィンドウをトリガーするため 2) 代替システムデフォルト提供ボタン、指定有効後デフォルトボタンは表示されない 3) 招待を受信するため 4) 新着メッセージ通知を受信するため 5) ... |
| selector | String | #id,.class,tagName,...をサポート デフォルト無し 可多个 |
いいえ | 補助ボタンセレクタ 1) チャットウィンドウをトリガーするため |
| css | Object | ボタンカスタムスタイル、例:css:{top:10%}、デフォルト無し | いいえ | |
| pop | Object | いいえ | メッセージ通知バブル [詳細] | |
| ### サンプル |
ud({
"mobile", {
"mode": "blank",
"color": "#307AE8",
"pos_flag": "crb",
"onlineText": "カスタマーサポートに連絡、オンライン相談",
"offlineText": "サポートは終了しました、メッセージを残してください",
"pop": {
"direction": "top",
"arrow": {
"top": 0,
"left": "70%"
}
}
}
});
> チャットパネル - パラメータ説明
| パラメータ名 | タイプ | 値 | 必須かどうか | 説明 |
|---|---|---|---|---|
| css | Object | カスタムスタイル、例:css:{top:10%}、デフォルトは無し | いいえ | パネルの位置は top、left、right のみサポート |
| onToggle | Function | カスタムメソッド パラメータ:data.visible(trueまたはfalse)}, |
いいえ | 現在のチャットパネルが開いているかどうかを検出、visibleがtrueの場合は開いている状態 |
サンプル
ud({
"panel": {
"css": {
"top": "0",
"left": "0"
},
"onToggle": function(data) { //パネルの開閉イベント
if (data.visible) {
//console.log('ウィンドウが開きました');
}
else{
//console.log('ウィンドウが閉じました');
}
}
}
});
> メッセージ通知バルーン - パラメータ説明
| パラメータ名 | タイプ | 値 | 必須かどうか | 説明 |
|---|---|---|---|---|
| css | Object | カスタムスタイル、例:css:{top:10%}、デフォルトは無し | いいえ | |
| direction | String | バルーンの表示方向、"top"(デフォルト);"right";"left";"bottom" | いいえ | |
| offset | Object | バルーンの位置オフセット、{top:0,left:0}、デフォルトは中央揃え | いいえ | |
| arrow | Object | バルーン矢印の設定、{top:0,left:0}、デフォルトは中央揃え | いいえ | |
| ### サンプル |
ud({
"pop": {
"direction": "top",
"arrow": {
"top": 0,
"left": "70%"
}
}
});
> 顧客情報 - パラメータ説明
概要
WebサイトにログインしているユーザーがWeb IMを通じてチャットを行う際に、顧客情報をリンク経由でUdeskに転送することができます。これにより、サポート担当者は顧客との対話中に直接顧客情報を確認できます。顧客情報補助コンポーネントを通じて、この顧客の注文情報などをさらに把握することも可能です。
使用方法
Web IM対話ウィンドウのリンク(https://xxxx.udesk.cn/im_client/)に、以下のルールに従ってパラメータと暗号化情報を追加することで、顧客情報を送信できます。
メールアドレスと電話番号は顧客識別に使用されます。つまり、Udeskシステム内のCRMの既存データと照合され、既存の顧客の場合は情報が更新され、一致しない場合は新しい顧客が作成されます。
> 顧客認証 - リクエストパラメータ
顧客情報や業務記録を渡すには、認証が必要です signature暗号化アルゴリズム。これらのデータを渡す必要がない場合は、認証は不要です。
顧客識別の有効期間: 4日間
顧客識別の優先順位: web_token > customer_token > c_email > c_phone
渡されたweb_tokenまたはcustomer_tokenがシステムに存在しない場合でも、渡されたc_emailまたはc_phoneが既に存在する場合、システムは元の顧客として識別します。 web_tokenのみを渡し、customer_token、c_email、c_phoneなどの識別データを渡さない場合、web_tokenは顧客のweb_tokenデータのみと照合され、一致しない場合は新しい顧客が作成されます。
| パラメータ名 | タイプ | 値 | 必須 | 説明 |
|---|---|---|---|---|
| nonce | String | ランダム値 | はい | ランダム値。動的なランダム値は静的なものよりもセキュリティが高くなります。 |
| timestamp | String | タイムスタンプ | はい | 現在のタイムスタンプ(13桁ミリ秒) |
| web_token | String | 顧客ID | はい | 顧客の一意の識別子。メールアドレス、電話番号などの使用を推奨します。 英数字とアンダースコアのみサポート。特殊文字は使用禁止 |
| customer_token | String | 顧客外部ID | いいえ | 顧客の外部一意識別子。open_api_tokenと同等です。 英数字とアンダースコアのみサポート。特殊文字は使用禁止 |
| signature | String | 暗号化署名 | はい | [signature暗号化アルゴリズム] |
| encryption_algorithm | String | SHA1またはSHA256 |
いいえ | 暗号化アルゴリズム。未指定の場合はデフォルトでSHA1。SHA256の使用を推奨します。 |
| ### signature暗号化アルゴリズム(3ステップ) |
1、以下のパラメータと順序で文字列を連結し、key=value&の形式にします: nonce、timestamp、web_token、im_user_key
im_user_keyの取得場所【管理センター-インスタントメッセージング-ウェブプラグイン-管理/顧客情報追加内のKEY】
sign_str = nonce=value×tamp=value&web_token=value&im_user_key
2、 暗号化アルゴリズムを使用して署名文字列を計算します
sign_str = sha1(sign_str) または sign_str = sha256(sign_str)
3、 文字列を大文字に変換します
sign_str = sign_str.toUpperCase()
4、よくある間違い
1、 im_user_keyはパラメータ名が不要で、値のみ必要です 2、 signature文字列は大文字に変換する必要があります
SHA1の例:
sign_str = "nonce=9ca6fff5a509fb887ac72cf5c92010e7×tamp=1455675719000&web_token=test@udesk.cn&b476f9f8-5309-4d0a-a2d4-af08c4507a15";
sign_str = sha1(sign_str);
sign_str = sign_str.toUpperCase();
例
// SHA1の例
ud({
"customer": {
"nonce": "9ca6fff5a509fb887ac72cf5c92010e7",
"signature": "9B2619225AA6476DC1EB80DBB8801E1575EBE39C",
"timestamp": "1455675719000",
"web_token": "test@udesk.cn"
}
});
// SHA256の例
ud({
"customer": {
"nonce": "9ca6fff5a509fb887ac72cf5c92010e7",
"signature": "4CC40FA2D762DAB1D4509750A7135123743D26F2552B7E23611AB8CB5D35825B",
"timestamp": "1455675719000",
"web_token": "test@udesk.cn",
"encryption_algorithm": "SHA256"
}
});
顧客パラメータ
| パラメータ名 | タイプ | 値 | 必須かどうか | 説明 |
|---|---|---|---|---|
| c_name | String | 顧客名 | いいえ | |
| c_email | String | 顧客メールアドレス唯一 |
いいえ | |
| c_phone | String | 顧客電話番号唯一 |
いいえ | |
| customer_token | String | 顧客外部識別子唯一 |
いいえ | open_api_tokenと同じフィールド |
| c_desc | String | 顧客説明 | いいえ | |
| c_org | String | 会社名 | いいえ | 複数会社を有効にしている場合は、複数渡すことができ、英語のカンマで区切ります 例:"かっこいい,きれい";有効にしていない場合は最初のもののみ取得 |
| c_tags | String | 顧客タグ | いいえ | 顧客タグを渡し、カンマで区切ります 例:"かっこいい,きれい" |
| c_owner | String | 顧客担当者ID | いいえ | |
| c_vip | String | 'vip'(VIP顧客) または 'normal'(一般顧客) | いいえ | 顧客VIP識別 |
| c_owner_group | String | 顧客担当グループID | いいえ | |
| c_other_emails | String | 顧客のその他のメールアドレスリスト | いいえ | カンマ区切り 例:"a@xxx.cn,b@xxx.cn" |
| c_cf_<カスタムフィールド名> | String | 顧客カスタムフィールド | いいえ | 顧客カスタムフィールド 例: c_cf_名前、c_cf_age、... |
| ## > 業務記録 - リクエストパラメータ |
| パラメータ名 | タイプ | 値 | 必須 | 説明 |
|---|---|---|---|---|
| c_cn_title | String | 業務記録主題 | いいえ | 業務記録の主題を入力します |
| c_cn_<カスタムフィールド名> | String | 業務記録カスタムフィールド | いいえ | 業務記録のカスタムフィールド 例: c_cn_名前、c_cn_age、... |
例
ud({
"customer": {
"c_name": "顧客名kimi",
"c_email": "newest3@udesk.cn",
"c_other_emails": '11@udesk.cn,22@udesk.cn',
"c_desc": "見込み顧客、潜在力が大きい",
"c_org": "desc",
"c_phone": "1100110012",
"c_tags": "ハンサム,新規追加",
"c_owner_group": "62",
"c_owner": "3",
"c_vip": "vip",
"c_qq": "123123",
"c_cf_年齢": 10,
"c_cf_趣味": "エクストリームチャレンジ",
"c_cn_title":"業務記録主題",
"c_cn_名前":"業務記録の名前",
"nonce": "694db2645b3f69a8",
"signature": "315345C77C73A128CF9850EAD777F7A71D423A36",
"timestamp": "1465878579000",
"web_token": "newest3@udesk.cn"
}
});
リンク例
渡すパラメータはエンコード処理してください。そうしないと文字化けが発生します!
https://xxx.udesk.cn/im_client/?c_desc=test123456789&c_email=jiangst%40udesio.com&c_phone=15888888888&echostr=hello&nonce=cdebd5d13f4d331e&signature=693140534BDDDAF002A46F0027E06244DF0B21AB×tamp=1457696747000&web_token=42f6607e-8892-4fcf-889b-f9babf627060
> チケット情報 - リクエストパラメータ
| パラメータ名 | タイプ | 値 | 必須 | 説明 |
|---|---|---|---|---|
| t_subject | String | チケット主題 | いいえ | チケットの主題 |
| t_content | String | チケット説明 | いいえ | 値を渡すとページに反映され、メッセージ内容テンプレートを上書きします |
| t_priority_id | String | チケット優先度 | いいえ | t_priority_idの取り得る値 1(緊急)、2(高)、3(標準)、4(低) 詳細 |
| t_status_id | String | チケット状態 | いいえ | t_status_idの取り得る値 1(オープン)、2(解決済み)、3(クローズ済み)、4(解決中) 詳細 |
| t_tags | String | チケットタグ | いいえ | チケットタグを入力します。カンマで区切ります 例:"tag1,tag2,tag3" |
| t_cf_<カスタムフィールド名> | String | チケットカスタムフィールド | いいえ | チケットのカスタムフィールド。APIでフィールド詳細リストを取得します 例: t_cf_TextField_213、t_cf_SelectField_225 詳細 |
| ### サンプル |
ud({
"ticket": {
"t_subject": "チケット件名",
"t_content": "チケット説明",
"t_priority_id": '3',//標準
"t_status_id": "1",//オープン
"t_tags": "遠雷、雨待ち、ここに留まれ",
"t_cf_TextField_213": "テキスト",
"t_cf_TextField_214": "12:00:00",//時間
"t_cf_TextField_215": "2018-10-26",//日付
"t_cf_TextField_215": "2018-10-20 12:00",//日時
"t_cf_SelectField_225": "3",//単一選択またはドロップダウン
"t_cf_SelectField_226": "1,2",//複数選択
"t_cf_SelectField_227": "0,0",//カスケード
}
});
リンクサンプル
渡すパラメータはエンコード処理してください。そうしないと文字化けが発生する可能性があります!
https://xxx.udesk.cn/im_client/?t_priority_id=3&t_status_id=1&t_cf_TextField_124=%E6%96%87%E6%9C%AC%E6%A1%86&t_cf_TextField_135=2018-10-20&t_cf_TextField_136=12:00:00&t_cf_TextField_137=2018-10-20%2012:00&t_cf_TextField_138=3.14&t_cf_TextField_139=250&t_cf_TextField_140=https://www.baidu.com&t_cf_TextField_141=abc&t_cf_TextField_142=%E9%80%9A%E5%8E%BF&t_cf_SelectField_134=1&t_cf_SelectField_135=0,0&t_cf_SelectField_136=0&t_cf_SelectField_137=1,2&t_tags=%E6%B5%8B%E8%AF%951,%E5%BC%A0%E4%B8%89,%E6%9D%8E%E5%9B%9B,%E7%8E%8B%E4%BA%94&c_name=im_client%E6%B5%8B%E8%AF%95%E5%AE%A2%E6%88%B7&c_email=t_im_client@163.com&c_phone=13520361010
> コンサルティングオブジェクト - パラメータ説明
2種類の導入方法を提供します:URLパラメータ方式、JavaScript導入方式
パラメータ説明
| 名前 | 値 | 説明 |
|---|---|---|
| title | String | タイトル |
| title_style | String | タイトルのスタイル、例:color:rgb(50,50,50);font-weight:bold |
| url | String | 遷移先ページのリンクアドレス |
| image | String | 表示画像アドレス |
| send | trueまたはfalse | trueの場合、コンサルティングオブジェクトの下に送信ボタンが表示され、クリックすると現在のコンサルティングオブジェクトが商品メッセージとしてカスタマーサポートに送信されます |
| <カスタムパラメータ> | 複数のカスタムパラメータを定義できます。日本語も可能です | |
| <カスタムパラメータ>_style | String | カスタムパラメータのスタイル |
| ### URLパラメータ渡し方式 |
すべてのパラメータの前にプレフィックス
product_を付け、渡すパラメータはエンコード処理を行ってください。そうしないと文字化けが発生する可能性があります!例:https://udeskdemo.udesk.cn/im_client/?product_send=true&product_title=Apple%20iPhone%207&product_url=http%3A%2F%2Fitem.jd.com%2F3133829.html%3Fcu%3Dtrue%26utm_source%E2%80%A6erm%3D9457752645_0_11333d2bdbd545f1839f020ae9b27f14&product_image=http%3A%2F%2Fimg14.360buyimg.com%2Fn1%2Fs450x450_jfs%2Ft3157%2F63%2F1645131029%2F112074%2Ff4f79169%2F57d0d44dN8cddf5c5.jpg%3Fv%3D1474635884816&product_%E4%BB%B7%E6%A0%BC=%EF%BF%A56189.00&product_%E4%BF%83%E9%94%80%E4%BF%A1%E6%81%AF=%E8%B4%AD%E4%B9%B0%E4%BA%AC%E4%B8%9C%E8%87%AA%E8%90%A5%E7%94%B5%E8%84%91%2C%E6%89%8B%E6%9C%BA%2C%E6%95%B0%E7%A0%81%E5%93%81%E7%B1%BB%E6%8C%87%E5%AE%9A%E4%BA%A7%E5%93%81%2C%E5%AE%9E%E9%99%85%E4%B8%8B%E5%8D%95%E7%BB%93%E7%AE%97%E9%87%91%E9%A2%9D%E6%BB%A1199%E5%85%83%2C%E8%BF%94%E4%BA%AC%E4%B8%9C%E8%87%AA%E8%90%A5%E5%A4%A7%E9%97%B8%E8%9F%B9%E4%B8%9C%E5%88%B8%E4%B8%80%E5%BC%A0.
JavaScript連携方式
ud({
product: {
title: "Apple iPhone 7",
url: "http://item.jd.com/3133829.html?cu=true&utm_source…erm=9457752645_0_11333d2bdbd545f1839f020ae9b27f14",
image: "http://img14.360buyimg.com/n1/s450x450_jfs/t3157/63/1645131029/112074/f4f79169/57d0d44dN8cddf5c5.jpg",
"価格": "¥6189.00",
"プロモーション価格": "¥6188.00"
}
});
> クライアントの多言語設定 - 詳細
多言語設定から既に設定されている多言語言語コードを探す
多言語機能はUdeskに個別にご連絡いただき、有効化してください
管理 -> アカウント設定 -> 多言語サポート
| 言語名 | ファイル名 | 言語コード | 更新日時 | 操作 |
|---|---|---|---|---|
| English | reocar_language_translation(en-us).xlsx | en-us | 2017/08/23 14:30 | ファイルダウンロード ファイルアップロード 更新 |
設定された言語コード en-us を language パラメータとして使用します。フランス語を使用する場合は、まずフランス語の多言語設定を行い、多言語サポートリストの 法语配置记录 の言語コードを使用してください。
zh-cn(簡体字中国語)はすでにシステムデフォルトとして設定されており、直接使用できます。多语言支持 で設定する必要はありません。
もし language に 多语言支持列表 で設定されていない言語コードパラメータが渡された場合、デフォルトの簡体字中国語が使用されます。
フロントエンドの静的リソース内の表示内容は現在、簡体字中国語とEnglishをサポートしています。カスタム言語翻訳はサポートしていません。より多くの言語をサポートする必要がある場合は、弊社までご連絡ください。
多言語言語コード設定規定
言語コードは以下のリストから選択する必要があります:
設定したい多言語言語コードが以下のリストにない場合は、Udeskにお問い合わせください。
| 言語名 | 言語コード |
|---|---|
| アラビア語 | ar |
| English | en-us |
| スペイン語 | es |
| フランス語 | fr |
| 日本語 | ja |
| 朝鮮語/韓国語 | ko |
| タイ語 | th |
| インドネシア語 | id |
| 繁体字中国語 | zh-TW |
| ポルトガル語 | pt |
| ロシア語 | ru |
メソッド説明
| メソッド名 | パラメータ | 説明 |
|---|---|---|
| init | なし | 手動初期化。ただし、manualInitがtrueに設定されている場合に有効です。例:ud("init") |
| hidePanel | なし | 手動でチャットパネルを非表示にします。例:ud("hidePanel") |
| showPanel | なし | 手動でチャットパネルを表示します。例:ud("showPanel") |
| dataTrace | type(データタイプ), data(データ) | データ追跡:閲覧履歴、イベントなどを含みます。 |
> 商品閲覧履歴アップロード
メソッド説明
ud("dataTrace", type, data);
パラメータ説明
| パラメータ名 | タイプ | 値 | 必須 | 説明 |
|---|---|---|---|---|
| type | String | product | はい | 追跡タイプ |
| data | Object | はい | 追跡データ | |
| data.name | String | はい | 商品名 | |
| data.url | String | いいえ | 商品へのリンク(新しいページで表示)。値が空の場合、クリックできません。 | |
| data.imgUrl | String | いいえ | 値が空の場合、表示されません。 | |
| data.params | Object | いいえ | パラメータリスト | |
| data.params.text | String | いいえ | パラメータテキスト | |
| data.params.color | String | いいえ | パラメータの色値。16進数の色を指定します(例:#ff0000)。 | |
| data.params.fold | Boolean | いいえ | 太字にするかどうか | |
| data.params.break | Boolean | いいえ | 改行するかどうか | |
| data.params.size | Number | デフォルト12 | いいえ | フォントサイズ |
| ### サンプル |
// 商品閲覧履歴
ud("dataTrace", "product", {
"name": " Apple iPhone X (A1903) 64GB 深空灰色 移动联通4G手机",
"url": "https://item.jd.com/6748052.html",
"imgUrl": "http://img12.360buyimg.com/n1/s450x450_jfs/t10675/253/1344769770/66891/92d54ca4/59df2e7fN86c99a27.jpg",
"params": [
{
"text": "¥6999.00",
"color": "#FF0000",
"fold": false,
"break": false, //breakはキーワードのため、IE8では引用符で囲む必要があります
"size": 12
}
]
});
> 注文イベントのアップロード
注文イベントをアップロードするには、まず顧客認証を行い、その後以下の方法で呼び出してください。
メソッド説明
ud("dataTrace", type, data);
パラメータ説明
| パラメータ名 | タイプ | 値 | 必須かどうか | 説明 |
|---|---|---|---|---|
| type | String | order | 必須 | トラッキングタイプ |
| data | Object | 必須 | トラッキングデータ | |
| data.order_no | String | 必須 | 注文番号 | |
| data.name | String | 必須 | 注文名 | |
| data.url | String | 任意 | 注文へのリンクURL | |
| data.price | Number | 必須 | 注文金額 | |
| data.order_at | Date | 必須 | 注文日時 | |
| data.pay_at | Date | 任意 | 支払い日時 | |
| data.status | String | 必須 | 注文ステータス: wait_pay(支払い待ち)、paid(支払い済み)、closed(キャンセル済み) | |
| data.remark | String | 任意 | 備考、最大長は1000バイト(日本語は2バイト) | |
| data.consignee_name | String | 任意 | 受取人氏名 | |
| data.consignee_phone | String | 任意 | 受取人電話番号 | |
| data.commodit_num | String | 任意 | 商品総数 | |
| commodities | Array | 任意 | 商品情報Array(Ojbect) | |
| ### commodities商品情報オブジェクト |
| パラメータ名 | タイプ | 必須 | 説明 |
|---|---|---|---|
| commodit_name | string | いいえ | 商品名 |
| commodit_no | string | いいえ | 商品番号 |
| commodit_count | numeric | いいえ | 商品数量 |
| commodit_fee | string | いいえ | 商品価格 |
サンプル
ud("dataTrace", "order", {
order_no: '1',
name: '最初の注文',
url: 'http://xxx.xxxx.com/注文リンク',
price: 16.8,
order_at: new Date(),
pay_at: new Date(),
status: 'wait_pay',
remark: '備考',
consignee_name: '張三',
consignee_phone: '01012345',
consignee_address: '北京市大興区',
commodit_num: 88,
commodities: [
{
commodit_name: '牛乳A',
commodit_no: 'NO123456',
commodit_count: 1,
commodit_fee: '46.5'
}
]
});
> マーケティングセッションイベントトラッキング
メソッド説明
ud("dataTrace", type, data);
パラメータ説明
| パラメータ名 | タイプ | 値 | 必須 | 説明 |
|---|---|---|---|---|
| type | String | marketing | はい | トラッキングタイプ |
| data | Object | はい | トラッキングデータ | |
| data.name | String | はい | イベント名 |
サンプル
// 商品閲覧履歴
ud("dataTrace", "marketing", {
"name": "注文キャンセル"
});
イベント説明
| パラメータ名 | タイプ | 値 | 必須 | 説明 |
|---|---|---|---|---|
| onReady | Function | リスナーイベント, パラメータなし | いいえ | Udesk IMプラグイン初期化完了イベントコールバック |
| onUnread | Function | リスナーイベント, パラメータ:data:{count:1 //未読メッセージ数} | いいえ | 未読メッセージイベントコールバック |
| ### サンプル |
ud({
"onReady": function() {
console.log('初期化完了');
},
"onUnread": function(data) {
console.log('未読メッセージ数'+data.count);
}
});
> ボタン位置の変更(ドラッグ)
概要
主にサードパーティがボタンの位置を変更し、カスタムドラッグイベントを実現するために使用します。 classが
udesk-client-btnのCSS(top, right, bottom, left)を変更します。
注意事項
ドラッグクリックによるチャットテンプレートの展開や招待の受け入れなどのイベントを防ぐためには、以下が必要です:
document.onmousedownイベント内でud('noDrag');を呼び出します。document.onmousemoveイベント内でud('isDrag')を呼び出します。
サンプル
- ボタン位置の変更: カスタマーサポートシステム管理画面 -> チャネル管理 -> インスタントメッセージング -> 特定のウェブプラグイン(管理をクリック)-> ボタン設定(右上)
- ドラッグによる変更方法: ユーザー自身が実装します。ネイティブの
mousemoveとmouseupメソッドを使用し、自身の実際のビジネスロジックに基づいて実装できます。
ウィンドウ設定 - 情報エリアのカスタムURL
Udeskウェブプラグインを使用し、かつウェブプラグインのウィンドウ設定でカスタムURLを構成した場合、構成されたページ内からUdeskカスタマーサポート/ボットにメッセージを送信できます。
基本的な使い方
カスタムURLページは、postMessageを使用して親ページと通信し、特定のメッセージ形式に従う必要があります。
カスタマーサポートチャット画面: テキストメッセージと商品メッセージを送信できます。
ボットチャット画面: テキストメッセージのみサポートしています。
現在のウィンドウのウェブリンクをカスタムiframeに渡す
ウィンドウは、現在のウェブページリンクのパラメータをカスタムURLのiframeに渡します。(ただし、
cur_url、cur_title、pre_url、src_urlの4つのパラメータは渡しません)。
パラメータ説明
| パラメータ名 | タイプ | 値 | 必須かどうか | 説明 |
|---|---|---|---|---|
| method | String | 'sendMsg' | はい | メソッド名、現在はsendMsgのみサポートしています |
| type | String | 'text' または 'product' | はい | メッセージタイプ: 文本消息 または 商品消息 |
| content | String | Object | はい | メッセージ内容 |
サンプル
1. テキストメッセージ
var data = JSON.stringify({
method: "sendMsg", // 固定method
type: "text", // 固定type
content: "xxx" // 送信するメッセージ
});
var origin = "*";
window.parent.postMessage(data, origin);
2. 商品メッセージ パラメータ詳細
var data = JSON.stringify({
method: "sendMsg", // 固定method
type: "product", // 固定type
content: { // 商品メッセージ形式
name: "Apple iPhone X (A1903) 64GB 深空灰色 移動通信4G携帯電話",
url: "https://item.jd.com/6748052.html",
imgUrl: "http://img12.360buyimg.com/n1/s450x450_jfs/t10675/253/1344769770/66891/92d54ca4/59df2e7fN86c99a27.jpg",
params: [{
text: "¥6999.00",
color: "#FF0000",
fold: false,
break: false,
size: 12
}, {
text: "1999元以上購入で30円追加"
}]
}
});
var origin = "*";
window.parent.postMessage(data, origin);
注意事項
- 送信頻度を制限してください
- メッセージ形式に注意してください
カスタム検索キーワード
| パラメータ名 | タイプ | 説明 |
|---|---|---|
| udesk_wd | String | 検索キーワード。サードパーティ(例:百度広告)からリダイレクトされた場合に使用 |
サードパーティウェブサイトリンク例(例:企業公式サイト)
https://www.企業ドメイン.com?udesk_wd=xxxx
ウェブプラグインリンク例
https://企業ドメイン.udesk.cn/im_client/?udesk_wd=xxxx
外部へのイベント通知
ウェブプラグインは window.postMessage を使用して外部にイベントを通知します。
サードパーティページは window.addEventListener('message',function (event) { //event }) で受信します。
例
window.addEventListener('message',function (event) {
/*
セッション終了イベントを例に挙げます
受信した `type` でイベントタイプを区別します。具体的なイベントタイプはパラメータ説明を参照してください
*/
let receiveEvent = JSON.parse(event.data)
if (receiveEvent.type === 'chatDone') {
//カスタムイベント処理
}
})
| 値 | 説明 |
|---|---|
| chatting | セッション開始イベント |
| chatDone | セッション終了イベント |
| queuing | 待機列入りイベント |
| hidePanel | ウィンドウ非表示イベント |
"web IMリクエスト権限検証" 有効化後の検証方法
ウェブプラグインリンクが検証後にのみアクセスを許可されるように強制したい場合は、
管理センター -> ウェブプラグイン -> その他設定 で "web IMリクエスト権限検証" を有効にしてください。
有効にした後、プラグインリンクには v_signature、v_timestamp、v_nonce を渡す必要があります。
v_signature 暗号化アルゴリズム(3ステップ)
-
以下のパラメータと順序で文字列を連結します(
key=value&形式):v_nonce、v_timestamp、im_user_keyim_user_key の取得場所:【管理センター - インスタントメッセージング - ウェブプラグイン - 管理/顧客情報追加 内の KEY】sign_str = v_nonce=value&v_timestamp=value&im_user_key
-
暗号化アルゴリズムを使用して署名文字列を計算します
sign_str = sha1(sign_str)
-
文字列を大文字に変換します
sign_str = sign_str.toUpperCase()
Javaコード例
1.依存関係のインストール
sha1 計算用の commons-codec
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.17.0</version>
</dependency>
2.コード実装
import org.apache.commons.codec.digest.DigestUtils;
public class App {
public static void main(String[] args) {
// プラグイン専用リンク
String baseURL = "[ここをプラグイン専用リンクに置き換えてください]";
// プラグインの認証キー
String im_user_key = "[ここをプラグインの im_user_key に置き換えてください]";
// タイムスタンプ(単位:ミリ秒)
long timestamp = System.currentTimeMillis();
// ランダム文字列
String nonce = Long.toString(Double.valueOf(Math.ceil(Math.random() * Long.MAX_VALUE)).longValue(), 36);
// 署名用の文字列に結合
String s = String.format("v_nonce=%s&v_timestamp=%s&%s", nonce, timestamp, im_user_key);
// sha1を計算し、結果を大文字に変換
String signature = DigestUtils.sha1Hex(s).toUpperCase();
// 最終的なウェブプラグインリンクを結合
String url = String.format(
"%s&v_nonce=%s&v_timestamp=%s&v_signature=%s",
baseURL,
nonce,
timestamp,
signature
);
System.out.println(url);
// コード連携方式を使用する場合
System.out.printf(
"ud({\n code: '%s',\n link: '%s',\n im_client_valid:{\n v_nonce:'%s',\n v_timestamp:'%s',\n v_signature:'%s'\n }\n})\n",
"[ここを code に置き換えてください]",
baseURL,
nonce,
timestamp,
signature
);
}
}
ウェブプラグインパラメータの暗号化方法
URL方式でウェブプラグインと連携する場合、顧客情報はすべてURLに結合され、さらに平文で送信されます。
この問題を解決するため、Udeskは、c_で始まるすべてのURLパラメータを公開鍵で暗号化し、
暗号化された暗号文をパラメータ customer_encrypt の値として設定する方法を提供しています。
以下は、この機能をJavaで実装した例です。
1.依存関係のインストール
commons-lang3 は Java でよく使用されるユーティリティクラスです。
commons-codec は署名計算に使用されます。
jackson-databind は object を JSON 文字列に変換するために使用されます。
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.14.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.16.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.2</version>
</dependency>
2.コード実装
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.RandomStringUtils;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Base64;
public class DemoUdeskImClientApplication {
// c_で始まるすべてのパラメータを暗号化するために使用
private static final String PUBLIC_KEY = "[ウェブプラグインの公開鍵に置き換えてください]";
// パラメータ署名に使用
private static final String IM_USER_KEY = "[ウェブプラグインの認証用キーに置き換えてください]";
private static final String URL_BASE = "https://[ここをカスタマーサポートシステムのドメインに置き換えてください]/im_client/?web_plugin_id=[ウェブプラグインIDに置き換えてください]";
public static void main(String[] args) throws Exception {
Customer customer = new Customer(
"李四",
"lisi@udesk.cn",
"18518518518",
"李四はテスト顧客です",
"顧客タグ,顧客タグ2",
"normal",
"AAJD1710397772205@udesktest.com"
);
String params = String.format(
"nonce=%s×tamp=%s&web_token=%s",
RandomStringUtils.random(5, true, true),
System.currentTimeMillis(),
customer.getWeb_token()
);
String url = URL_BASE
+ "&customer_encrypt=" + encode(customer)
+ "&" + params
+ "&encryption_algorithm=SHA256"
+ "&signature=" + getSignature(params);
System.out.println(url);
}
public static String encode(Customer customer) throws Exception {
// customer を JSON 文字列に変換
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
String message = objectMapper.writer().writeValueAsString(customer);
// RSAPublicKey オブジェクトを取得
byte[] encoded = Base64.getDecoder().decode(PUBLIC_KEY);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
// Cipher を初期化
Cipher encryptCipher = Cipher.getInstance("RSA");
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
// 平文をセグメント化
int dataCount = (int) Math.ceil((double) message.getBytes().length / 117);
byte[][] datas = new byte[dataCount][];
for (int i = 0; i < dataCount; i++) {
int length = (i == dataCount - 1) ? (message.getBytes().length % 117) : 117;
byte[] item = Arrays.copyOfRange(message.getBytes(), i * 117, i * 117 + length);
datas[i] = item;
}
// セグメント化された平文を暗号化し、1つの大きな byte 配列に合成してから、この大きな配列を base64 でエンコード
byte[] mi = new byte[]{};
for (byte[] s : datas) {
mi = ArrayUtils.addAll(mi, encryptCipher.doFinal(s));
}
return Base64.getEncoder().encodeToString(mi);
}
public static String getSignature(String paramString) {
return DigestUtils.sha256Hex(paramString + "&" + IM_USER_KEY).toUpperCase();
}
@JsonRootName("customer")
@JsonInclude(JsonInclude.Include.NON_NULL)
static class Customer {
String c_name;
String c_email;
String c_phone;
String c_desc;
String c_tags;
String c_vip;
String web_token;
public Customer(String c_name, String c_email, String c_phone, String c_desc, String c_tags, String c_vip, String web_token) {
this.c_name = c_name;
this.c_email = c_email;
this.c_phone = c_phone;
this.c_desc = c_desc;
this.c_tags = c_tags;
this.c_vip = c_vip;
this.web_token = web_token;
}
public Customer(String c_name) {
this.c_name = c_name;
}
public String getC_name() {
return c_name;
}
public void setC_name(String c_name) {
this.c_name = c_name;
}
public String getWeb_token() {
return web_token;
}
public void setWeb_token(String web_token) {
this.web_token = web_token;
}
public String getC_email() {
return c_email;
}
public void setC_email(String c_email) {
this.c_email = c_email;
}
public String getC_phone() {
return c_phone;
}
public void setC_phone(String c_phone) {
this.c_phone = c_phone;
}
public String getC_desc() {
return c_desc;
}
public void setC_desc(String c_desc) {
this.c_desc = c_desc;
}
public String getC_tags() {
return c_tags;
}
public void setC_tags(String c_tags) {
this.c_tags = c_tags;
}
public String getC_vip() {
return c_vip;
}
public void setC_vip(String c_vip) {
this.c_vip = c_vip;
}
}
}
よくある質問
企業WeChat H5で写真が撮れない?
Udeskカスタマーサポートに連絡し、企業WeChatの代行開発アプリケーションの信頼できるドメインを設定してもらってください。
Android WebViewで写真や動画が撮れない?
ウェブプラグインのファイル、写真、動画はすべて通常の<input type='file'>タグです。
Android WebViewでは、いくつかのコードを書いて適応させる必要があります。
以下のコードは以下の機能を実装しています。動画で効果を確認する
1. 写真撮影をクリックすると直接カメラが開き、動画撮影をクリックすると直接カメラで録画が始まり、ファイルをクリックするとすべての種類のファイルを選択できます。
2. 未承認のアプリが写真や画面録画を行う際に権限をリクエストします。
3. カメラ権限が拒否された場合、「設定へ」というメッセージボックスを表示します。
import android.Manifest;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.Settings;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
private static final int FILE_CHOOSER_REQUEST_CODE = 1;
private static final int CAMERA_PERMISSION_REQUEST_CODE = 2;
private static final int CAMERA_VIDEO_PERMISSION_REQUEST_CODE = 3;
private WebView webView;
private ValueCallback<Uri[]> filePathCallback;
private String cameraPhotoPath;
private String cameraVideoPath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webview);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient());
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
MainActivity.this.filePathCallback = filePathCallback;
String[] acceptTypes = fileChooserParams.getAcceptTypes();
if (acceptTypes.length > 0) {
String acceptType = acceptTypes[0];
if (acceptType.equals("video/*") || acceptType.equals("image/*")) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
MainActivity.this,
new String[]{Manifest.permission.CAMERA},
acceptType.equals("video/*") ? CAMERA_VIDEO_PERMISSION_REQUEST_CODE : CAMERA_PERMISSION_REQUEST_CODE
);
return true;
} else {
if (acceptType.equals("image/*")) {
openImageChooser();
return true;
} else if (acceptType.equals("video/*")) {
openVideoChooser();
return true;
}
}
}
}
openFileChooser();
return true;
}
});
webView.loadUrl("https://[あなたの専用ドメインに置き換えてください]/im_client/");
}
private void openImageChooser() {
// カメラを呼び出すためのIntentを作成
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// 撮影した画像を保存するためのファイルを作成
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", cameraPhotoPath);
} catch (IOException ex) {
// エラー処理
ex.printStackTrace();
}
if (photoFile != null) {
cameraPhotoPath = "file:" + photoFile.getAbsolutePath();
Uri photoURI = FileProvider.getUriForFile(this, "udesk.im.client.webview.demo.provider", photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
} else {
takePictureIntent = null;
}
}
startActivityForResult(takePictureIntent, FILE_CHOOSER_REQUEST_CODE);
}
private File createImageFile() throws IOException {
// 画像ファイル名を作成
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(null);
return File.createTempFile(imageFileName, ".jpg", storageDir);
}
private void openVideoChooser() {
// カメラ録画を呼び出すためのIntentを作成
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {
// 録画ファイルを保存するためのファイルを作成
File videoFile = null;
try {
videoFile = createVideoFile();
takeVideoIntent.putExtra("VideoPath", cameraVideoPath);
} catch (IOException ex) {
// エラー処理
ex.printStackTrace();
}
if (videoFile != null) {
cameraVideoPath = "file:" + videoFile.getAbsolutePath();
Uri videoURI = FileProvider.getUriForFile(this, "udesk.im.client.webview.demo.provider", videoFile);
takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, videoURI);
} else {
takeVideoIntent = null;
}
}
startActivityForResult(takeVideoIntent, FILE_CHOOSER_REQUEST_CODE);
}
private File createVideoFile() throws IOException {
// 動画ファイル名を作成
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String videoFileName = "MP4_" + timeStamp + "_";
File storageDir = getExternalFilesDir(null);
return File.createTempFile(videoFileName, ".mp4", storageDir);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILE_CHOOSER_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Uri[] results = null;
if (resultCode == Activity.RESULT_OK) {
if (data == null || data.getData() == null) {
if (cameraPhotoPath != null) {
results = new Uri[]{Uri.parse(cameraPhotoPath)};
}
} else {
String dataString = data.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
}
filePathCallback.onReceiveValue(results);
filePathCallback = null;
} else {
if (filePathCallback != null) {
filePathCallback.onReceiveValue(null);
filePathCallback = null;
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == CAMERA_PERMISSION_REQUEST_CODE || requestCode == CAMERA_VIDEO_PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (requestCode == CAMERA_VIDEO_PERMISSION_REQUEST_CODE) {
openVideoChooser(); // 録画をクリックして権限をリクエストした際に同意して権限を付与
} else if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
openImageChooser(); // 写真撮影をクリックして権限をリクエストした際に同意して権限を付与
}
} else {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
showPermissionDeniedDialog(); // 権限が拒否され、かつ「今後表示しない」がチェックされている場合。
} else {
Toast.makeText(this, "写真撮影と画面録画にはカメラ権限が必要です。", Toast.LENGTH_SHORT).show();
}
if (filePathCallback != null) {
filePathCallback.onReceiveValue(null);
filePathCallback = null;
}
}
}
}
private void openFileChooser() {
Intent takePictureIntent = new Intent(Intent.ACTION_GET_CONTENT);
takePictureIntent.setType("*/*");
startActivityForResult(takePictureIntent, FILE_CHOOSER_REQUEST_CODE);
}
private void showPermissionDeniedDialog() {
new AlertDialog.Builder(this)
.setTitle("権限が必要です")
.setMessage("写真撮影にはカメラ権限が必要です。設定でこの権限を有効にしてください。")
.setPositiveButton("設定へ", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
openAppSettings();
}
})
.setNegativeButton("キャンセル", null)
.show();
}
private void openAppSettings() {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
}
Android WebViewで画像をダウンロードする方法は?
ウェブプラグインで画像をクリックすると、専用の画像表示画面が表示され、画面の上部にダウンロードボタンがあります。
このボタンは通常のaタグであり、このaタグをクリックすると新しいページで画像が開きます。
したがって、Androidアプリ内でこの動作をインターセプトし、ダウンロードに変更する必要があります。
以下は具体的なコード実装です。
import android.app.DownloadManager;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private WebView myWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myWebView = findViewById(R.id.webview);
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.setWebViewClient(new MyWebViewClient());
myWebView.loadUrl("https://[あなたの専用ドメインに置き換えてください]/im_client/");
}
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (isImageUrl(url)) {
// 画像リンクの場合、ダウンロードメソッドを呼び出す
downloadImage(MainActivity.this, url);
return true;
} else {
// 画像リンクでない場合、URLの読み込みを続行する
return false;
}
}
private boolean isImageUrl(String url) {
// URLが画像形式かどうかをチェックする
return url.endsWith(".jpg")
|| url.endsWith(".jpeg")
|| url.endsWith(".png")
|| url.endsWith(".gif")
|| url.contains(".jpg?")
|| url.contains(".jpeg?")
|| url.contains(".png?")
|| url.contains(".gif?");
}
private void downloadImage(Context context, String url) {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, url.substring(url.lastIndexOf("/") + 1));
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
if (downloadManager != null) {
downloadManager.enqueue(request);
Toast.makeText(context, "ダウンロード中...", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "ダウンロードマネージャーが利用できません", Toast.LENGTH_SHORT).show();
}
}
}
}